Exemplo n.º 1
0
    def assign_elementary(self, lhs, rhs, evaluation, tags=None, upset=False):
        name = lhs.get_head_name()

        if name in system_symbols('OwnValues', 'DownValues', 'SubValues',
                                  'UpValues', 'NValues', 'Options',
                                  'DefaultValues', 'Attributes', 'Messages'):
            if len(lhs.leaves) != 1:
                evaluation.message_args(name, len(lhs.leaves), 1)
                return False
            tag = lhs.leaves[0].get_name()
            if not tag:
                evaluation.message(name, 'sym', lhs.leaves[0], 1)
                return False
            if tags is not None and tags != [tag]:
                evaluation.message(name, 'tag', Symbol(name), Symbol(tag))
                return False

            if (name != 'System`Attributes' and 'System`Protected'    # noqa
                in evaluation.definitions.get_attributes(tag)):
                evaluation.message(name, 'wrsym', Symbol(tag))
                return False
            if name == 'System`Options':
                option_values = rhs.get_option_values(evaluation)
                if option_values is None:
                    evaluation.message(name, 'options', rhs)
                    return False
                evaluation.definitions.set_options(tag, option_values)
            elif name == 'System`Attributes':
                attributes = get_symbol_list(
                    rhs, lambda item: evaluation.message(name, 'sym', item, 1))
                if attributes is None:
                    return False
                if 'System`Locked' in evaluation.definitions.get_attributes(tag):
                    evaluation.message(name, 'locked', Symbol(tag))
                    return False
                evaluation.definitions.set_attributes(tag, attributes)
            else:
                rules = rhs.get_rules_list()
                if rules is None:
                    evaluation.message(name, 'vrule', lhs, rhs)
                    return False
                evaluation.definitions.set_values(tag, name, rules)
            return True

        form = ''
        nprec = None
        default = False
        message = False

        allow_custom_tag = False

        focus = lhs

        if name == 'System`N':
            if len(lhs.leaves) not in (1, 2):
                evaluation.message_args('N', len(lhs.leaves), 1, 2)
                return False
            if len(lhs.leaves) == 1:
                nprec = Symbol('MachinePrecision')
            else:
                nprec = lhs.leaves[1]
            focus = lhs.leaves[0]
            lhs = Expression('N', focus, nprec)
        elif name == 'System`MessageName':
            if len(lhs.leaves) != 2:
                evaluation.message_args('MessageName', len(lhs.leaves), 2)
                return False
            focus = lhs.leaves[0]
            message = True
        elif name == 'System`Default':
            if len(lhs.leaves) not in (1, 2, 3):
                evaluation.message_args('Default', len(lhs.leaves), 1, 2, 3)
                return False
            focus = lhs.leaves[0]
            default = True
        elif name == 'System`Format':
            if len(lhs.leaves) not in (1, 2):
                evaluation.message_args('Format', len(lhs.leaves), 1, 2)
                return False
            if len(lhs.leaves) == 2:
                form = lhs.leaves[1].get_name()
                if not form:
                    evaluation.message('Format', 'fttp', lhs.leaves[1])
                    return False
            else:
                form = system_symbols(
                    'StandardForm', 'TraditionalForm', 'OutputForm',
                    'TeXForm', 'MathMLForm')
            lhs = focus = lhs.leaves[0]
        else:
            allow_custom_tag = True

        focus = focus.evaluate_leaves(evaluation)

        if tags is None and not upset:
            name = focus.get_lookup_name()
            if not name:
                evaluation.message(self.get_name(), 'setraw', focus)
                return False
            tags = [name]
        elif upset:
            if allow_custom_tag:
                tags = []
                if focus.is_atom():
                    evaluation.message(self.get_name(), 'normal')
                    return False
                for leaf in focus.leaves:
                    name = leaf.get_lookup_name()
                    tags.append(name)
            else:
                tags = [focus.get_lookup_name()]
        else:
            allowed_names = [focus.get_lookup_name()]
            if allow_custom_tag:
                for leaf in focus.get_leaves():
                    allowed_names.append(leaf.get_lookup_name())
            for name in tags:
                if name not in allowed_names:
                    evaluation.message(self.get_name(), 'tagnfd', Symbol(name))
                    return False

        ignore_protection = False
        rhs_int_value = rhs.get_int_value()
        lhs_name = lhs.get_name()
        if lhs_name == 'System`$RecursionLimit':
            # if (not rhs_int_value or rhs_int_value < 20) and not
            # rhs.get_name() == 'System`Infinity':
            if (not rhs_int_value or rhs_int_value < 20 or
                rhs_int_value > settings.MAX_RECURSION_DEPTH):  # nopep8

                evaluation.message('$RecursionLimit', 'limset', rhs)
                return False
            try:
                set_recursionlimit(rhs_int_value)
            except OverflowError:
                # TODO: Message
                return False
            ignore_protection = True
        elif lhs_name == 'System`$ModuleNumber':
            if not rhs_int_value or rhs_int_value <= 0:
                evaluation.message('$ModuleNumber', 'set', rhs)
                return False
            ignore_protection = True
        elif lhs_name in ('System`$Line', 'System`$HistoryLength'):
            if rhs_int_value is None or rhs_int_value < 0:
                evaluation.message(lhs_name, 'intnn', rhs)
                return False
            ignore_protection = True
        elif lhs_name == 'System`$RandomState':
            # TODO: allow setting of legal random states!
            # (but consider pickle's insecurity!)
            evaluation.message('$RandomState', 'rndst', rhs)
            return False
        elif lhs_name == 'System`$Context':
            new_context = rhs.get_string_value()
            if new_context is None or not valid_context_name(
                    new_context, allow_initial_backquote=True):
                evaluation.message(lhs_name, 'cxset', rhs)
                return False

            # With $Context in Mathematica you can do some strange
            # things: e.g. with $Context set to Global`, something
            # like:
            #    $Context = "`test`"; newsym
            # is accepted and creates Global`test`newsym.
            # Implement this behaviour by interpreting
            #    $Context = "`test`"
            # as
            #    $Context = $Context <> "test`"
            #
            if new_context.startswith('`'):
                new_context = (evaluation.definitions.get_current_context() +
                               new_context.lstrip('`'))

            evaluation.definitions.set_current_context(new_context)
            ignore_protection = True
            return True
        elif lhs_name == 'System`$ContextPath':
            context_path = [s.get_string_value() for s in rhs.get_leaves()]
            if rhs.has_form('List', None) and all(valid_context_name(s) for s in context_path):
                evaluation.definitions.set_context_path(context_path)
                ignore_protection = True
                return True
            else:
                evaluation.message(lhs_name, 'cxlist', rhs)
                return False
        elif lhs_name == 'System`$MinPrecision':
            # $MinPrecision = Infinity is not allowed
            if rhs_int_value is not None and rhs_int_value >= 0:
                ignore_protection = True
                max_prec = evaluation.definitions.get_config_value('$MaxPrecision')
                if max_prec is not None and max_prec < rhs_int_value:
                    evaluation.message('$MinPrecision', 'preccon', Symbol('$MinPrecision'))
                    return True
            else:
                evaluation.message(lhs_name, 'precset', lhs, rhs)
                return False
        elif lhs_name == 'System`$MaxPrecision':
            if rhs.has_form('DirectedInfinity', 1) and rhs.leaves[0].get_int_value() == 1:
                ignore_protection = True
            elif rhs_int_value is not None and rhs_int_value > 0:
                ignore_protection = True
                min_prec = evaluation.definitions.get_config_value('$MinPrecision')
                if min_prec is not None and rhs_int_value < min_prec:
                    evaluation.message('$MaxPrecision', 'preccon', Symbol('$MaxPrecision'))
                    ignore_protection = True
                    return True
            else:
                evaluation.message(lhs_name, 'precset', lhs, rhs)
                return False

        rhs_name = rhs.get_head_name()
        if rhs_name == 'System`Condition':
            if len(rhs.leaves) != 2:
                evaluation.message_args('Condition', len(rhs.leaves), 2)
                return False
            else:
                lhs = Expression('Condition', lhs, rhs.leaves[1])
                rhs = rhs.leaves[0]

        rule = Rule(lhs, rhs)
        count = 0
        defs = evaluation.definitions
        for tag in tags:
            if (not ignore_protection and 'System`Protected'   # noqa
                in evaluation.definitions.get_attributes(tag)):
                if lhs.get_name() == tag:
                    evaluation.message(self.get_name(), 'wrsym', Symbol(tag))
                else:
                    evaluation.message(self.get_name(), 'write', Symbol(tag), lhs)
                continue
            count += 1
            if form:
                defs.add_format(tag, rule, form)
            elif nprec:
                defs.add_nvalue(tag, rule)
            elif default:
                defs.add_default(tag, rule)
            elif message:
                defs.add_message(tag, rule)
            else:
                if upset:
                    defs.add_rule(tag, rule, position='up')
                else:
                    defs.add_rule(tag, rule)
        if count == 0:
            return False

        return True
Exemplo n.º 2
0
    def assign_elementary(self, lhs, rhs, evaluation, tags=None, upset=False):
        name = lhs.get_head_name()

        if name in system_symbols('OwnValues', 'DownValues', 'SubValues',
                                  'UpValues', 'NValues', 'Options',
                                  'DefaultValues', 'Attributes', 'Messages'):
            if len(lhs.leaves) != 1:
                evaluation.message_args(name, len(lhs.leaves), 1)
                return False
            tag = lhs.leaves[0].get_name()
            if not tag:
                evaluation.message(name, 'sym', lhs.leaves[0], 1)
                return False
            if tags is not None and tags != [tag]:
                evaluation.message(name, 'tag', Symbol(name), Symbol(tag))
                return False

            if (name != 'System`Attributes' and 'System`Protected'    # noqa
                in evaluation.definitions.get_attributes(tag)):
                evaluation.message(name, 'wrsym', Symbol(tag))
                return False
            if name == 'System`Options':
                option_values = rhs.get_option_values(evaluation)
                if option_values is None:
                    evaluation.message(name, 'options', rhs)
                    return False
                evaluation.definitions.set_options(tag, option_values)
            elif name == 'System`Attributes':
                attributes = get_symbol_list(
                    rhs, lambda item: evaluation.message(name, 'sym', item, 1))
                if attributes is None:
                    return False
                if 'System`Locked' in evaluation.definitions.get_attributes(tag):
                    evaluation.message(name, 'locked', Symbol(tag))
                    return False
                evaluation.definitions.set_attributes(tag, attributes)
            else:
                rules = rhs.get_rules_list()
                if rules is None:
                    evaluation.message(name, 'vrule', lhs, rhs)
                    return False
                evaluation.definitions.set_values(tag, name, rules)
            return True

        form = ''
        nprec = None
        default = False
        message = False

        allow_custom_tag = False

        focus = lhs

        if name == 'System`N':
            if len(lhs.leaves) not in (1, 2):
                evaluation.message_args('N', len(lhs.leaves), 1, 2)
                return False
            if len(lhs.leaves) == 1:
                nprec = Symbol('MachinePrecision')
            else:
                nprec = lhs.leaves[1]
            focus = lhs.leaves[0]
            lhs = Expression('N', focus, nprec)
        elif name == 'System`MessageName':
            if len(lhs.leaves) != 2:
                evaluation.message_args('MessageName', len(lhs.leaves), 2)
                return False
            focus = lhs.leaves[0]
            message = True
        elif name == 'System`Default':
            if len(lhs.leaves) not in (1, 2, 3):
                evaluation.message_args('Default', len(lhs.leaves), 1, 2, 3)
                return False
            focus = lhs.leaves[0]
            default = True
        elif name == 'System`Format':
            if len(lhs.leaves) not in (1, 2):
                evaluation.message_args('Format', len(lhs.leaves), 1, 2)
                return False
            if len(lhs.leaves) == 2:
                form = lhs.leaves[1].get_name()
                if not form:
                    evaluation.message('Format', 'fttp', lhs.leaves[1])
                    return False
            else:
                form = system_symbols(
                    'StandardForm', 'TraditionalForm', 'OutputForm',
                    'TeXForm', 'MathMLForm')
            lhs = focus = lhs.leaves[0]
        else:
            allow_custom_tag = True

        focus = focus.evaluate_leaves(evaluation)

        if tags is None and not upset:
            name = focus.get_lookup_name()
            if not name:
                evaluation.message(self.get_name(), 'setraw', focus)
                return False
            tags = [name]
        elif upset:
            if allow_custom_tag:
                tags = []
                if focus.is_atom():
                    evaluation.message(self.get_name(), 'normal')
                    return False
                for leaf in focus.leaves:
                    name = leaf.get_lookup_name()
                    tags.append(name)
            else:
                tags = [focus.get_lookup_name()]
        else:
            allowed_names = [focus.get_lookup_name()]
            if allow_custom_tag:
                for leaf in focus.get_leaves():
                    allowed_names.append(leaf.get_lookup_name())
            for name in tags:
                if name not in allowed_names:
                    evaluation.message(self.get_name(), 'tagnfd', Symbol(name))
                    return False

        ignore_protection = False
        rhs_int_value = rhs.get_int_value()
        lhs_name = lhs.get_name()
        if lhs_name == 'System`$RecursionLimit':
            # if (not rhs_int_value or rhs_int_value < 20) and not
            # rhs.get_name() == 'System`Infinity':
            if (not rhs_int_value or rhs_int_value < 20 or
                rhs_int_value > settings.MAX_RECURSION_DEPTH):  # nopep8

                evaluation.message('$RecursionLimit', 'limset', rhs)
                return False
            try:
                set_recursionlimit(rhs_int_value)
            except OverflowError:
                # TODO: Message
                return False
            ignore_protection = True
        elif lhs_name == 'System`$ModuleNumber':
            if not rhs_int_value or rhs_int_value <= 0:
                evaluation.message('$ModuleNumber', 'set', rhs)
                return False
            ignore_protection = True
        elif lhs_name in ('System`$Line', 'System`$HistoryLength'):
            if rhs_int_value is None or rhs_int_value < 0:
                evaluation.message(lhs_name, 'intnn', rhs)
                return False
            ignore_protection = True
        elif lhs_name == 'System`$RandomState':
            # TODO: allow setting of legal random states!
            # (but consider pickle's insecurity!)
            evaluation.message('$RandomState', 'rndst', rhs)
            return False
        elif lhs_name == 'System`$Context':
            new_context = rhs.get_string_value()
            if new_context is None or not valid_context_name(
                    new_context, allow_initial_backquote=True):
                evaluation.message(lhs_name, 'cxset', rhs)
                return False

            # With $Context in Mathematica you can do some strange
            # things: e.g. with $Context set to Global`, something
            # like:
            #    $Context = "`test`"; newsym
            # is accepted and creates Global`test`newsym.
            # Implement this behaviour by interpreting
            #    $Context = "`test`"
            # as
            #    $Context = $Context <> "test`"
            #
            if new_context.startswith('`'):
                new_context = (evaluation.definitions.get_current_context() +
                               new_context.lstrip('`'))

            evaluation.definitions.set_current_context(new_context)
            ignore_protection = True
            return True
        elif lhs_name == 'System`$ContextPath':
            context_path = [s.get_string_value() for s in rhs.get_leaves()]
            if rhs.has_form('List', None) and all(valid_context_name(s) for s in context_path):
                evaluation.definitions.set_context_path(context_path)
                ignore_protection = True
                return True
            else:
                evaluation.message(lhs_name, 'cxlist', rhs)
                return False
        elif lhs_name == 'System`$MinPrecision':
            # $MinPrecision = Infinity is not allowed
            if rhs_int_value is not None and rhs_int_value >= 0:
                ignore_protection = True
                max_prec = evaluation.definitions.get_config_value('$MaxPrecision')
                if max_prec is not None and max_prec < rhs_int_value:
                    evaluation.message('$MinPrecision', 'preccon', Symbol('$MinPrecision'))
                    return True
            else:
                evaluation.message(lhs_name, 'precset', lhs, rhs)
                return False
        elif lhs_name == 'System`$MaxPrecision':
            if rhs.has_form('DirectedInfinity', 1) and rhs.leaves[0].get_int_value() == 1:
                ignore_protection = True
            elif rhs_int_value is not None and rhs_int_value > 0:
                ignore_protection = True
                min_prec = evaluation.definitions.get_config_value('$MinPrecision')
                if min_prec is not None and rhs_int_value < min_prec:
                    evaluation.message('$MaxPrecision', 'preccon', Symbol('$MaxPrecision'))
                    ignore_protection = True
                    return True
            else:
                evaluation.message(lhs_name, 'precset', lhs, rhs)
                return False

        rhs_name = rhs.get_head_name()
        if rhs_name == 'System`Condition':
            if len(rhs.leaves) != 2:
                evaluation.message_args('Condition', len(rhs.leaves), 2)
                return False
            else:
                lhs = Expression('Condition', lhs, rhs.leaves[1])
                rhs = rhs.leaves[0]

        rule = Rule(lhs, rhs)
        count = 0
        defs = evaluation.definitions
        for tag in tags:
            if (not ignore_protection and 'System`Protected'   # noqa
                in evaluation.definitions.get_attributes(tag)):
                if lhs.get_name() == tag:
                    evaluation.message(self.get_name(), 'wrsym', Symbol(tag))
                else:
                    evaluation.message(self.get_name(), 'write', Symbol(tag), lhs)
                continue
            count += 1
            if form:
                defs.add_format(tag, rule, form)
            elif nprec:
                defs.add_nvalue(tag, rule)
            elif default:
                defs.add_default(tag, rule)
            elif message:
                defs.add_message(tag, rule)
            else:
                if upset:
                    defs.add_rule(tag, rule, position='up')
                else:
                    defs.add_rule(tag, rule)
        if count == 0:
            return False

        return True
Exemplo n.º 3
0
    def assign_elementary(self, lhs, rhs, evaluation, tags=None, upset=False):
        name = lhs.get_head_name()

        if name in (
            "OwnValues",
            "DownValues",
            "SubValues",
            "UpValues",
            "NValues",
            "Options",
            "DefaultValues",
            "Attributes",
            "Messages",
        ):
            if len(lhs.leaves) != 1:
                evaluation.message_args(name, len(lhs.leaves), 1)
                return False
            tag = lhs.leaves[0].get_name()
            if not tag:
                evaluation.message(name, "sym", lhs.leaves[0], 1)
                return False
            if tags is not None and tags != [tag]:
                evaluation.message(name, "tag", name, tag)
                return False

            if name != "Attributes" and "Protected" in evaluation.definitions.get_attributes(tag):  # noqa
                evaluation.message(name, "wrsym", tag)
                return False
            if name == "Options":
                option_values = rhs.get_option_values(evaluation)
                if option_values is None:
                    evaluation.message(name, "options", rhs)
                    return False
                evaluation.definitions.set_options(tag, option_values)
            elif name == "Attributes":
                attributes = get_symbol_list(rhs, lambda item: evaluation.message(name, "sym", item, 1))
                if attributes is None:
                    return False
                if "Locked" in evaluation.definitions.get_attributes(tag):
                    evaluation.message(name, "locked", tag)
                    return False
                evaluation.definitions.set_attributes(tag, attributes)
            else:
                rules = rhs.get_rules_list()
                if rules is None:
                    evaluation.message(name, "vrule", lhs, rhs)
                    return False
                evaluation.definitions.set_values(tag, name, rules)
            return True

        form = ""
        nprec = None
        default = False
        message = False

        allow_custom_tag = False

        focus = lhs

        if name == "N":
            if len(lhs.leaves) not in (1, 2):
                evaluation.message_args("N", len(lhs.leaves), 1, 2)
                return False
            if len(lhs.leaves) == 1:
                nprec = Symbol("MachinePrecision")
            else:
                nprec = lhs.leaves[1]
            focus = lhs.leaves[0]
            lhs = Expression("N", focus, nprec)
        elif name == "MessageName":
            if len(lhs.leaves) != 2:
                evaluation.message_args("MessageName", len(lhs.leaves), 2)
                return False
            focus = lhs.leaves[0]
            message = True
        elif name == "Default":
            if len(lhs.leaves) not in (1, 2, 3):
                evaluation.message_args("Default", len(lhs.leaves), 1, 2, 3)
                return False
            focus = lhs.leaves[0]
            default = True
        elif name == "Format":
            if len(lhs.leaves) not in (1, 2):
                evaluation.message_args("Format", len(lhs.leaves), 1, 2)
                return False
            if len(lhs.leaves) == 2:
                form = lhs.leaves[1].get_name()
                if not form:
                    evaluation.message("Format", "fttp", lhs.leaves[1])
                    return False
            else:
                form = ("StandardForm", "TraditionalForm", "OutputForm", "TeXForm", "MathMLForm")
            lhs = focus = lhs.leaves[0]
        else:
            allow_custom_tag = True

        focus = focus.evaluate_leaves(evaluation)

        if tags is None and not upset:
            name = focus.get_lookup_name()
            if not name:
                evaluation.message(self.get_name(), "setraw", focus)
                return False
            tags = [name]
        elif upset:
            if allow_custom_tag:
                tags = []
                if focus.is_atom():
                    evaluation.message(self.get_name(), "normal")
                    return False
                for leaf in focus.leaves:
                    name = leaf.get_lookup_name()
                    tags.append(name)
            else:
                tags = [focus.get_lookup_name()]
        else:
            allowed_names = [focus.get_lookup_name()]
            if allow_custom_tag:
                for leaf in focus.get_leaves():
                    allowed_names.append(leaf.get_lookup_name())
            for name in tags:
                if name not in allowed_names:
                    evaluation.message(self.get_name(), "tagnfd", name)
                    return False

        ignore_protection = False
        rhs_int_value = rhs.get_int_value()
        lhs_name = lhs.get_name()
        if lhs_name == "$RecursionLimit":
            # if (not rhs_int_value or rhs_int_value < 20) and not
            # rhs.get_name() == 'Infinity':
            if not rhs_int_value or rhs_int_value < 20 or rhs_int_value > settings.MAX_RECURSION_DEPTH:  # noqa

                evaluation.message("$RecursionLimit", "limset", rhs)
                return False
            try:
                set_recursionlimit(rhs_int_value)
            except OverflowError:
                # TODO: Message
                return False
            ignore_protection = True
        elif lhs_name == "$ModuleNumber":
            if not rhs_int_value or rhs_int_value <= 0:
                evaluation.message("$ModuleNumber", "set", rhs)
                return False
            ignore_protection = True
        elif lhs_name in ("$Line", "$HistoryLength"):
            if rhs_int_value is None or rhs_int_value < 0:
                evaluation.message(lhs_name, "intnn", rhs)
                return False
            ignore_protection = True
        elif lhs_name == "$RandomState":
            # TODO: allow setting of legal random states!
            # (but consider pickle's insecurity!)
            evaluation.message("$RandomState", "rndst", rhs)
            return False

        rhs_name = rhs.get_head_name()
        if rhs_name == "Condition":
            if len(rhs.leaves) != 2:
                evaluation.message_args("Condition", len(rhs.leaves), 2)
                return False
            else:
                lhs = Expression("Condition", lhs, rhs.leaves[1])
                rhs = rhs.leaves[0]

        rule = Rule(lhs, rhs)
        count = 0
        defs = evaluation.definitions
        for tag in tags:
            if not ignore_protection and "Protected" in evaluation.definitions.get_attributes(tag):  # noqa
                if lhs.get_name() == tag:
                    evaluation.message(self.get_name(), "wrsym", tag)
                else:
                    evaluation.message(self.get_name(), "write", tag, lhs)
                continue
            count += 1
            if form:
                defs.add_format(tag, rule, form)
            elif nprec:
                defs.add_nvalue(tag, rule)
            elif default:
                defs.add_default(tag, rule)
            elif message:
                defs.add_message(tag, rule)
            else:
                if upset:
                    defs.add_rule(tag, rule, position="up")
                else:
                    defs.add_rule(tag, rule)
        if count == 0:
            return False

        return True
Exemplo n.º 4
0
    def assign_elementary(self, lhs, rhs, evaluation, tags=None, upset=False):
        name = lhs.get_head_name()

        if name in ('OwnValues', 'DownValues', 'SubValues', 'UpValues',
                    'NValues', 'Options', 'DefaultValues', 'Attributes',
                    'Messages'):
            if len(lhs.leaves) != 1:
                evaluation.message_args(name, len(lhs.leaves), 1)
                return False
            tag = lhs.leaves[0].get_name()
            if not tag:
                evaluation.message(name, 'sym', lhs.leaves[0], 1)
                return False
            if tags is not None and tags != [tag]:
                evaluation.message(name, 'tag', name, tag)
                return False

            if (name != 'Attributes' and 'Protected'    # noqa
                in evaluation.definitions.get_attributes(tag)):
                evaluation.message(name, 'wrsym', tag)
                return False
            if name == 'Options':
                option_values = rhs.get_option_values(evaluation)
                if option_values is None:
                    evaluation.message(name, 'options', rhs)
                    return False
                evaluation.definitions.set_options(tag, option_values)
            elif name == 'Attributes':
                attributes = get_symbol_list(
                    rhs, lambda item: evaluation.message(name, 'sym', item, 1))
                if attributes is None:
                    return False
                if 'Locked' in evaluation.definitions.get_attributes(tag):
                    evaluation.message(name, 'locked', tag)
                    return False
                evaluation.definitions.set_attributes(tag, attributes)
            else:
                rules = rhs.get_rules_list()
                if rules is None:
                    evaluation.message(name, 'vrule', lhs, rhs)
                    return False
                evaluation.definitions.set_values(tag, name, rules)
            return True

        form = ''
        nprec = None
        default = False
        message = False

        allow_custom_tag = False

        focus = lhs

        if name == 'N':
            if len(lhs.leaves) not in (1, 2):
                evaluation.message_args('N', len(lhs.leaves), 1, 2)
                return False
            if len(lhs.leaves) == 1:
                nprec = Symbol('MachinePrecision')
            else:
                nprec = lhs.leaves[1]
            focus = lhs.leaves[0]
            lhs = Expression('N', focus, nprec)
        elif name == 'MessageName':
            if len(lhs.leaves) != 2:
                evaluation.message_args('MessageName', len(lhs.leaves), 2)
                return False
            focus = lhs.leaves[0]
            message = True
        elif name == 'Default':
            if len(lhs.leaves) not in (1, 2, 3):
                evaluation.message_args('Default', len(lhs.leaves), 1, 2, 3)
                return False
            focus = lhs.leaves[0]
            default = True
        elif name == 'Format':
            if len(lhs.leaves) not in (1, 2):
                evaluation.message_args('Format', len(lhs.leaves), 1, 2)
                return False
            if len(lhs.leaves) == 2:
                form = lhs.leaves[1].get_name()
                if not form:
                    evaluation.message('Format', 'fttp', lhs.leaves[1])
                    return False
            else:
                form = ('StandardForm', 'TraditionalForm', 'OutputForm',
                        'TeXForm', 'MathMLForm',
                        )
            lhs = focus = lhs.leaves[0]
        else:
            allow_custom_tag = True

        focus = focus.evaluate_leaves(evaluation)

        if tags is None and not upset:
            name = focus.get_lookup_name()
            if not name:
                evaluation.message(self.get_name(), 'setraw', focus)
                return False
            tags = [name]
        elif upset:
            if allow_custom_tag:
                tags = []
                if focus.is_atom():
                    evaluation.message(self.get_name(), 'normal')
                    return False
                for leaf in focus.leaves:
                    name = leaf.get_lookup_name()
                    tags.append(name)
            else:
                tags = [focus.get_lookup_name()]
        else:
            allowed_names = [focus.get_lookup_name()]
            if allow_custom_tag:
                for leaf in focus.get_leaves():
                    allowed_names.append(leaf.get_lookup_name())
            for name in tags:
                if name not in allowed_names:
                    evaluation.message(self.get_name(), 'tagnfd', name)
                    return False

        ignore_protection = False
        rhs_int_value = rhs.get_int_value()
        lhs_name = lhs.get_name()
        if lhs_name == '$RecursionLimit':
            # if (not rhs_int_value or rhs_int_value < 20) and not
            # rhs.get_name() == 'Infinity':
            if (not rhs_int_value or rhs_int_value < 20  # noqa
                or rhs_int_value > settings.MAX_RECURSION_DEPTH):

                evaluation.message('$RecursionLimit', 'limset', rhs)
                return False
            try:
                set_recursionlimit(rhs_int_value)
            except OverflowError:
                # TODO: Message
                return False
            ignore_protection = True
        elif lhs_name == '$ModuleNumber':
            if not rhs_int_value or rhs_int_value <= 0:
                evaluation.message('$ModuleNumber', 'set', rhs)
                return False
            ignore_protection = True
        elif lhs_name in ('$Line', '$HistoryLength'):
            if rhs_int_value is None or rhs_int_value < 0:
                evaluation.message(lhs_name, 'intnn', rhs)
                return False
            ignore_protection = True
        elif lhs_name == '$RandomState':
            # TODO: allow setting of legal random states!
            # (but consider pickle's insecurity!)
            evaluation.message('$RandomState', 'rndst', rhs)
            return False

        rhs_name = rhs.get_head_name()
        if rhs_name == 'Condition':
            if len(rhs.leaves) != 2:
                evaluation.message_args('Condition', len(rhs.leaves), 2)
                return False
            else:
                lhs = Expression('Condition', lhs, rhs.leaves[1])
                rhs = rhs.leaves[0]

        rule = Rule(lhs, rhs)
        count = 0
        defs = evaluation.definitions
        for tag in tags:
            if (not ignore_protection and 'Protected'   # noqa
                in evaluation.definitions.get_attributes(tag)):
                if lhs.get_name() == tag:
                    evaluation.message(self.get_name(), 'wrsym', tag)
                else:
                    evaluation.message(self.get_name(), 'write', tag, lhs)
                continue
            count += 1
            if form:
                defs.add_format(tag, rule, form)
            elif nprec:
                defs.add_nvalue(tag, rule)
            elif default:
                defs.add_default(tag, rule)
            elif message:
                defs.add_message(tag, rule)
            else:
                if upset:
                    defs.add_rule(tag, rule, position='up')
                else:
                    defs.add_rule(tag, rule)
        if count == 0:
            return False

        return True
Exemplo n.º 5
0
 def assign_elementary(self, lhs, rhs, evaluation, tags=None, upset=False):
     name = lhs.get_head_name()
     
     if name in ('OwnValues', 'DownValues', 'SubValues', 'UpValues', 'NValues', 'Options',
         'DefaultValues', 'Attributes', 'Messages'):
         if len(lhs.leaves) != 1:
             evaluation.message_args(name, len(lhs.leaves), 1)
             return False
         tag = lhs.leaves[0].get_name()
         if not tag:
             evaluation.message(name, 'sym', lhs.leaves[0], 1)
             return False
         if tags is not None and tags != [tag]:
             evaluation.message(name, 'tag', name, tag)
             return False
         
         if name != 'Attributes' and 'Protected' in evaluation.definitions.get_attributes(tag):
             evaluation.message(name, 'wrsym', tag)
             return False
         if name == 'Options':
             option_values = rhs.get_option_values(evaluation)
             if option_values is None:
                 evaluation.message(name, 'options', rhs)
                 return False
             evaluation.definitions.set_options(tag, option_values)
         elif name == 'Attributes':
             attributes = get_symbol_list(rhs, lambda item: evaluation.message(name, 'sym', item, 1))
             if attributes is None:
                 return False
             if 'Locked' in evaluation.definitions.get_attributes(tag):
                 evaluation.message(name, 'locked', tag)
                 return False
             evaluation.definitions.set_attributes(tag, attributes)
         else:
             rules = rhs.get_rules_list()
             if rules is None:
                 evaluation.message(name, 'vrule', lhs, rhs)
                 return False 
             evaluation.definitions.set_values(tag, name, rules)
         return True
     
     form = ''
     nprec = None
     default = False
     message = False
         
     allow_custom_tag = False
         
     focus = lhs
     
     if name == 'N':
         if len(lhs.leaves) not in (1, 2):
             evaluation.message_args('N', len(lhs.leaves), 1, 2)
             return False
         if len(lhs.leaves) == 1:
             nprec = Symbol('MachinePrecision')
         else:
             nprec = lhs.leaves[1]
         focus = lhs.leaves[0]
         lhs = Expression('N', focus, nprec)
     elif name == 'MessageName':
         if len(lhs.leaves) != 2:
             evaluation.message_args('MessageName', len(lhs.leaves), 2)
             return False
         focus = lhs.leaves[0]
         message = True
     elif name == 'Default':
         if len(lhs.leaves) not in (1, 2, 3):
             evaluation.message_args('Default', len(lhs.leaves), 1, 2, 3)
             return False
         focus = lhs.leaves[0]
         default = True  
     elif name == 'Format':
         if len(lhs.leaves) not in (1, 2):
             evaluation.message_args('Format', len(lhs.leaves), 1, 2)
             return False
         if len(lhs.leaves) == 2:
             form = lhs.leaves[1].get_name()
             if not form:
                 evaluation.message('Format', 'fttp', lhs.leaves[1])
                 return False
         else:
             form = ('StandardForm', 'TraditionalForm', 'OutputForm',
                 'TeXForm', 'MathMLForm',
             )
         lhs = focus = lhs.leaves[0]
     else:
         allow_custom_tag = True
                 
     focus = focus.evaluate_leaves(evaluation)
     
     if tags is None and not upset:
         name = focus.get_lookup_name()
         if not name:
             evaluation.message(self.get_name(), 'setraw', focus)
             return False
         tags = [name]
     elif upset:
         if allow_custom_tag:
             tags = []
             if focus.is_atom():
                 evaluation.message(self.get_name(), 'normal')
                 return False
             for leaf in focus.leaves:
                 name = leaf.get_lookup_name()
                 tags.append(name)
         else:
             tags = [focus.get_lookup_name()]
     else:
         allowed_names = [focus.get_lookup_name()]
         if allow_custom_tag:
             for leaf in focus.get_leaves():
                 allowed_names.append(leaf.get_lookup_name())
         for name in tags:
             if name not in allowed_names:
                 evaluation.message(self.get_name(), 'tagnfd', name)
                 return False
         
     ignore_protection = False
     rhs_int_value = rhs.get_int_value()
     lhs_name = lhs.get_name()
     if lhs_name == '$RecursionLimit':
         #if (not rhs_int_value or rhs_int_value < 20) and not rhs.get_name() == 'Infinity':
         if not rhs_int_value or rhs_int_value < 20 or rhs_int_value > settings.MAX_RECURSION_DEPTH:
             evaluation.message('$RecursionLimit', 'limset', rhs)
             return False
         try:
             set_recursionlimit(rhs_int_value)
         except OverflowError:
             #TODO: Message
             return False
         ignore_protection = True
     elif lhs_name == '$ModuleNumber':
         if not rhs_int_value or rhs_int_value <= 0:
             evaluation.message('$ModuleNumber', 'set', rhs)
             return False
         ignore_protection = True
     elif lhs_name in ('$Line', '$HistoryLength'):
         if rhs_int_value is None or rhs_int_value < 0:
             evaluation.message(lhs_name, 'intnn', rhs)
             return False
         ignore_protection = True
     elif lhs_name == '$RandomState':
         # TODO: allow setting of legal random states!
         # (but consider pickle's insecurity!)
         evaluation.message('$RandomState', 'rndst', rhs)
         return False
         
     rhs_name = rhs.get_head_name()
     if rhs_name == 'Condition':
         if len(rhs.leaves) != 2:
             evaluation.message_args('Condition', len(rhs.leaves), 2)
             return False
         else:
             lhs = Expression('Condition', lhs, rhs.leaves[1])
             rhs = rhs.leaves[0]
             
     rule = Rule(lhs, rhs)
     count = 0
     defs = evaluation.definitions
     for tag in tags:
         if not ignore_protection and 'Protected' in evaluation.definitions.get_attributes(tag):
             if lhs.get_name() == tag:
                 evaluation.message(self.get_name(), 'wrsym', tag)
             else:
                 evaluation.message(self.get_name(), 'write', tag, lhs)
             continue
         count += 1
         if form:
             defs.add_format(tag, rule, form)
         elif nprec:
             defs.add_nvalue(tag, rule)
         elif default:
             defs.add_default(tag, rule)
         elif message:
             defs.add_message(tag, rule)
         else:
             if upset:
                 defs.add_rule(tag, rule, position='up')
             else:
                 defs.add_rule(tag, rule)
     if count == 0:
         return False
             
     return True