Example #1
0
def contribute(definitions):
    # let MakeBoxes contribute first
    builtins['System`MakeBoxes'].contribute(definitions)
    for name, item in builtins.items():
        if name != 'System`MakeBoxes':
            item.contribute(definitions)

    # Is there another way to Unprotect these symbols at initialization?
    definitions.get_attributes('System`$PreRead').clear()
    definitions.get_attributes('System`$Pre').clear()
    definitions.get_attributes('System`$Post').clear()
    definitions.get_attributes('System`$PrePrint').clear()
    definitions.get_attributes('System`$SyntaxHandler').clear()

            
    from mathics.core.expression import ensure_context
    from mathics.core.parser import all_operator_names
    from mathics.core.definitions import Definition

    # All builtins are loaded. Create dummy builtin definitions for
    # any remaining operators that don't have them. This allows
    # operators like \[Cup] to behave correctly.
    for operator in all_operator_names:
        if not definitions.have_definition(ensure_context(operator)):
            op = ensure_context(operator)
            definitions.builtin[op] = Definition(name=op)
Example #2
0
def contribute(definitions):
    # let MakeBoxes contribute first
    builtins['System`MakeBoxes'].contribute(definitions)
    for name, item in builtins.items():
        if name != 'System`MakeBoxes':
            item.contribute(definitions)

    # Is there another way to Unprotect these symbols at initialization?
    definitions.get_attributes('System`$PreRead').clear()
    definitions.get_attributes('System`$Pre').clear()
    definitions.get_attributes('System`$Post').clear()
    definitions.get_attributes('System`$PrePrint').clear()
    definitions.get_attributes('System`$SyntaxHandler').clear()

    from mathics.core.expression import ensure_context
    from mathics.core.parser import all_operator_names
    from mathics.core.definitions import Definition

    # All builtins are loaded. Create dummy builtin definitions for
    # any remaining operators that don't have them. This allows
    # operators like \[Cup] to behave correctly.
    for operator in all_operator_names:
        if not definitions.have_definition(ensure_context(operator)):
            op = ensure_context(operator)
            definitions.builtin[op] = Definition(name=op)
Example #3
0
    def has_form(self, heads, *leaf_counts):
        """
        leaf_counts:
            (,):        no leaves allowed
            (None,):    no constraint on number of leaves
            (n, None):  leaf count >= n
            (n1, n2, ...):    leaf count in {n1, n2, ...}
        """

        head_name = self.get_name()
        if isinstance(heads, (tuple, list, set)):
            if head_name not in [ensure_context(h) for h in heads]:
                return False
        else:
            if head_name != ensure_context(heads):
                return False
        if not leaf_counts:
            return False
        if leaf_counts and leaf_counts[0] is not None:
            count = len(self._leaves)
            if count not in leaf_counts:
                if (
                    len(leaf_counts) == 2
                    and leaf_counts[1] is None  # noqa
                    and count >= leaf_counts[0]
                ):
                    return True
                else:
                    return False
        return True
Example #4
0
    def __init__(self, *args, **kwargs):
        super(BinaryOperator, self).__init__(*args, **kwargs)
        name = self.get_name()
        # Prevent pattern matching symbols from gaining meaning here using
        # Verbatim
        name = 'Verbatim[%s]' % name

        # For compatibility, allow grouping symbols in builtins to be
        # specified without System`.
        self.grouping = ensure_context(self.grouping)

        if self.grouping in ('System`None', 'System`NonAssociative'):
            op_pattern = '%s[items__]' % name
            replace_items = 'items'
        else:
            op_pattern = '%s[x_, y_]' % name
            replace_items = 'x, y'

        if self.default_formats:
            operator = self.get_operator_display()
            formatted = 'MakeBoxes[Infix[{%s},"%s",%d,%s], form]' % (
                replace_items, operator, self.precedence, self.grouping)
            formatted_output = 'MakeBoxes[Infix[{%s}," %s ",%d,%s], form]' % (
                replace_items, operator, self.precedence, self.grouping)
            default_rules = {
                'MakeBoxes[{0}, form:StandardForm|TraditionalForm]'.format(op_pattern):
                formatted,
                'MakeBoxes[{0}, form:InputForm|OutputForm]'.format(op_pattern):
                formatted_output,
            }
            default_rules.update(self.rules)
            self.rules = default_rules
Example #5
0
 def tmp(args, op=flat_infix_op):
     op = ensure_context(op)
     if args[1].get_head_name() == op:
         args[1].leaves.append(args[3])
         args[0] = args[1]
     else:
         args[0] = Expression(op, args[1], args[3])
Example #6
0
 def get_option(self, options, name, evaluation, pop=False):
     name = ensure_context(name)
     value = options.pop(name, None) if pop else options.get(name)
     if value is not None:
         return value.evaluate(evaluation)
     else:
         return None
Example #7
0
    def __init__(self, *args, **kwargs):
        super(BinaryOperator, self).__init__(*args, **kwargs)
        name = self.get_name()
        # Prevent pattern matching symbols from gaining meaning here using
        # Verbatim
        name = 'Verbatim[%s]' % name

        # For compatibility, allow grouping symbols in builtins to be
        # specified without System`.
        self.grouping = ensure_context(self.grouping)

        if self.grouping in ('System`None', 'System`NonAssociative'):
            op_pattern = '%s[items__]' % name
            replace_items = 'items'
        else:
            op_pattern = '%s[x_, y_]' % name
            replace_items = 'x, y'

        if self.default_formats:
            operator = self.get_operator_display()
            formatted = 'MakeBoxes[Infix[{%s},"%s",%d,%s], form]' % (
                replace_items, operator, self.precedence, self.grouping)
            formatted_output = 'MakeBoxes[Infix[{%s}," %s ",%d,%s], form]' % (
                replace_items, operator, self.precedence, self.grouping)
            default_rules = {
                'MakeBoxes[{0}, form:StandardForm|TraditionalForm]'.format(
                    op_pattern): formatted,
                'MakeBoxes[{0}, form:InputForm|OutputForm]'.format(
                    op_pattern): formatted_output,
            }
            default_rules.update(self.rules)
            self.rules = default_rules
Example #8
0
 def get_option(self, options, name, evaluation, pop=False):
     name = ensure_context(name)
     value = options.pop(name, None) if pop else options.get(name)
     if value is not None:
         return value.evaluate(evaluation)
     else:
         return None
Example #9
0
 def tmp(args, op=flat_infix_op):
     op = ensure_context(op)
     if args[1].get_head_name() == op:
         args[1].leaves.append(args[3])
         args[0] = args[1]
     else:
         args[0] = Expression(op, args[1], args[3])
Example #10
0
File: base.py Project: slel/Mathics
    def get_functions(self, prefix="apply", is_pymodule=False):
        from mathics.core.parser import parse_builtin_rule

        unavailable_function = self._get_unavailable_function()
        for name in dir(self):
            if name.startswith(prefix):

                function = getattr(self, name)
                pattern = function.__doc__
                if pattern is None:  # Fixes PyPy bug
                    continue
                else:
                    m = re.match(r"([\w,]+)\:\s*(.*)", pattern)
                if m is not None:
                    attrs = m.group(1).split(",")
                    pattern = m.group(2)
                else:
                    attrs = []
                if is_pymodule:
                    name = ensure_context(self.get_name(short=True), "Pymathics")
                else:
                    name = self.get_name()

                pattern = pattern % {"name": name}
                definition_class = (
                    PyMathicsDefinitions() if is_pymodule else SystemDefinitions()
                )
                pattern = parse_builtin_rule(pattern, definition_class)
                if unavailable_function:
                    function = unavailable_function
                if attrs:
                    yield (attrs, pattern), function
                else:
                    yield (pattern, function)
Example #11
0
    def message(self, symbol, tag, *args):
        from mathics.core.expression import String, Symbol, Expression, from_python

        # Allow evaluation.message('MyBuiltin', ...) (assume
        # System`MyBuiltin)
        symbol = ensure_context(symbol)
        quiet_messages = set(self.get_quiet_messages())

        pattern = Expression("MessageName", Symbol(symbol), String(tag))

        if pattern in quiet_messages or self.quiet_all:
            return

        # Shorten the symbol's name according to the current context
        # settings. This makes sure we print the context, if it would
        # be necessary to find the symbol that this message is
        # attached to.
        symbol_shortname = self.definitions.shorten_name(symbol)

        if settings.DEBUG_PRINT:
            print("MESSAGE: %s::%s (%s)" % (symbol_shortname, tag, args))

        text = self.definitions.get_value(symbol, "System`Messages", pattern, self)
        if text is None:
            pattern = Expression("MessageName", Symbol("General"), String(tag))
            text = self.definitions.get_value("System`General", "System`Messages", pattern, self)

        if text is None:
            text = String("Message %s::%s not found." % (symbol_shortname, tag))

        text = self.format_output(Expression("StringForm", text, *(from_python(arg) for arg in args)), "text")

        self.out.append(Message(symbol_shortname, tag, text))
        self.output.out(self.out[-1])
Example #12
0
def contribute(definitions):
    # let MakeBoxes contribute first
    builtins['System`MakeBoxes'].contribute(definitions)
    for name, item in builtins.items():
        if name != 'System`MakeBoxes':
            item.contribute(definitions)

    from mathics.core.expression import ensure_context
    from mathics.core.parser import all_operator_names
    from mathics.core.definitions import Definition

    # All builtins are loaded. Create dummy builtin definitions for
    # any remaining operators that don't have them. This allows
    # operators like \[Cup] to behave correctly.
    for operator in all_operator_names:
        if not definitions.have_definition(ensure_context(operator)):
            op = ensure_context(operator)
            definitions.builtin[op] = Definition(name=op)
Example #13
0
def contribute(definitions):
    # let MakeBoxes contribute first
    builtins['System`MakeBoxes'].contribute(definitions)
    for name, item in builtins.items():
        if name != 'System`MakeBoxes':
            item.contribute(definitions)

    from mathics.core.expression import ensure_context
    from mathics.core.parser import all_operator_names
    from mathics.core.definitions import Definition

    # All builtins are loaded. Create dummy builtin definitions for
    # any remaining operators that don't have them. This allows
    # operators like \[Cup] to behave correctly.
    for operator in all_operator_names:
        if not definitions.have_definition(ensure_context(operator)):
            op = ensure_context(operator)
            definitions.builtin[op] = Definition(name=op)
Example #14
0
 def tmp(args, op=innequality_op):
     head = args[1].get_head_name()
     if head == ensure_context(op):
         args[1].leaves.append(args[3])
         args[0] = args[1]
     elif head == 'System`Inequality':
         args[1].leaves.append(Symbol(op))
         args[1].leaves.append(args[3])
         args[0] = args[1]
     elif head in [ensure_context(k)
                   for k in innequality_operators.keys()]:
         leaves = []
         for i, leaf in enumerate(args[1].leaves):
             if i != 0:
                 leaves.append(Symbol(head))
             leaves.append(leaf)
         leaves.append(Symbol(op))
         leaves.append(args[3])
         args[0] = Expression('Inequality', *leaves)
     else:
         args[0] = Expression(op, args[1], args[3])
Example #15
0
 def tmp(args, op=innequality_op):
     head = args[1].get_head_name()
     if head == ensure_context(op):
         args[1].leaves.append(args[3])
         args[0] = args[1]
     elif head == 'System`Inequality':
         args[1].leaves.append(Symbol(op))
         args[1].leaves.append(args[3])
         args[0] = args[1]
     elif head in [ensure_context(k)
                   for k in innequality_operators.keys()]:
         leaves = []
         for i, leaf in enumerate(args[1].leaves):
             if i != 0:
                 leaves.append(Symbol(head))
             leaves.append(leaf)
         leaves.append(Symbol(op))
         leaves.append(args[3])
         args[0] = Expression('Inequality', *leaves)
     else:
         args[0] = Expression(op, args[1], args[3])
Example #16
0
    def apply_3(self, f, optvals, optname, evaluation):
        "OptionValue[f_, optvals_, optname_]"
        if type(optname) is String:
            name = optname.to_python()[1:-1]
        else:
            name = optname.get_name()

        if not name:
            name = optname.get_string_value()
            if name:
                name = ensure_context(name)
        if not name:
            evaluation.message("OptionValue", "sym", optname, 1)
            return
        # Look first in the explicit list
        if optvals:
            val = get_option(optvals.get_option_values(evaluation), name,
                             evaluation)
        else:
            val = None
        # then, if not found, look at $f$. It could be a symbol, or a list of symbols, rules, and list of rules...
        if val is None:
            if f.is_symbol():
                val = get_option(
                    evaluation.definitions.get_options(f.get_name()), name,
                    evaluation)
            else:
                if f.get_head_name() in ("System`Rule", "System`RuleDelayed"):
                    f = Expression("List", f)
                if f.get_head_name() == "System`List":
                    for leave in f.get_leaves():
                        if leave.is_symbol():
                            val = get_option(
                                evaluation.definitions.get_options(
                                    leave.get_name()),
                                name,
                                evaluation,
                            )
                            if val:
                                break
                        else:
                            values = leave.get_option_values(evaluation)
                            val = get_option(values, name, evaluation)
                            if val:
                                break

        if val is None and evaluation.options:
            val = get_option(evaluation.options, name, evaluation)
        if val is None:
            evaluation.message("OptionValue", "optnf", optname)
            return Symbol(name)
        return val
Example #17
0
    def get_option_values(self, leaves, **options):
        evaluation = options.get("evaluation", None)
        if evaluation:
            default = evaluation.definitions.get_options(self.get_name()).copy()
            options = Expression("List", *leaves).get_option_values(evaluation)
            default.update(options)
        else:
            from mathics.core.parser import parse_builtin_rule

            default = {}
            for option, value in self.options.items():
                option = ensure_context(option)
                default[option] = parse_builtin_rule(value)
        return default
Example #18
0
    def apply_2(self, f, optname, evaluation):
        'OptionValue[f_, optname_]'
        name = optname.get_name()
        if not name:
            name = optname.get_string_value()
            if name:
                name = ensure_context(name)
        if not name:
            evaluation.message('OptionValue', 'sym', optname, 1)
            return Expression('OptionValue', optname)

        val = evaluation.definitions.get_options(f.get_name()).get(name, None)
        if val is None:
            evaluation.message('OptionValue', 'optnf', optname)
            return Expression('OptionValue', optname)
        return val
Example #19
0
    def apply(self, symbol, evaluation):
        'OptionValue[symbol_]'

        if evaluation.options is None:
            return
        name = symbol.get_name()
        if not name:
            name = symbol.get_string_value()
            if name:
                name = ensure_context(name)
        if not name:
            evaluation.message('OptionValue', 'sym', symbol, 1)
            return
        value = evaluation.options.get(name)
        if value is None:
            evaluation.message('OptionValue', 'optnf', symbol)
            return
        return value
Example #20
0
    def apply_1(self, optname, evaluation):
        'OptionValue[optname_]'
        if evaluation.options is None:
            return
        name = optname.get_name()
        if not name:
            name = optname.get_string_value()
            if name:
                name = ensure_context(name)
        if not name:
            evaluation.message('OptionValue', 'sym', optname, 1)
            return Expression('OptionValue', optname)

        val = evaluation.options.get(name)
        if val is None:
            evaluation.message('OptionValue', 'optnf', optname)
            return Expression('OptionValue', optname)
        return val
Example #21
0
    def apply(self, symbol, evaluation):
        'OptionValue[symbol_]'

        if evaluation.options is None:
            return
        name = symbol.get_name()
        if not name:
            name = symbol.get_string_value()
            if name:
                name = ensure_context(name)
        if not name:
            evaluation.message('OptionValue', 'sym', symbol, 1)
            return
        value = evaluation.options.get(name)
        if value is None:
            evaluation.message('OptionValue', 'optnf', symbol)
            return
        return value
Example #22
0
    def message(self, symbol, tag, *args) -> None:
        from mathics.core.expression import (String, Symbol, Expression,
                                             from_python)

        # Allow evaluation.message('MyBuiltin', ...) (assume
        # System`MyBuiltin)
        symbol = ensure_context(symbol)
        quiet_messages = set(self.get_quiet_messages())

        pattern = Expression('MessageName', Symbol(symbol), String(tag))

        if pattern in quiet_messages or self.quiet_all:
            return

        # Shorten the symbol's name according to the current context
        # settings. This makes sure we print the context, if it would
        # be necessary to find the symbol that this message is
        # attached to.
        symbol_shortname = self.definitions.shorten_name(symbol)

        if settings.DEBUG_PRINT:
            print('MESSAGE: %s::%s (%s)' % (symbol_shortname, tag, args))

        text = self.definitions.get_value(symbol, 'System`Messages', pattern,
                                          self)
        if text is None:
            pattern = Expression('MessageName', Symbol('General'), String(tag))
            text = self.definitions.get_value('System`General',
                                              'System`Messages', pattern, self)

        if text is None:
            text = String("Message %s::%s not found." %
                          (symbol_shortname, tag))

        text = self.format_output(
            Expression('StringForm', text,
                       *(from_python(arg) for arg in args)), 'text')

        self.out.append(Message(symbol_shortname, tag, text))
        self.output.out(self.out[-1])
Example #23
0
    def apply_1(self, optname, evaluation):
        "OptionValue[optname_]"
        if evaluation.options is None:
            return

        if type(optname) is String:
            name = optname.to_python()[1:-1]
        else:
            name = optname.get_name()

        name = optname.get_name()
        if not name:
            name = optname.get_string_value()
            if name:
                name = ensure_context(name)
        if not name:
            evaluation.message("OptionValue", "sym", optname, 1)
            return

        val = get_option(evaluation.options, name, evaluation)
        if val is None:
            evaluation.message("OptionValue", "optnf", optname)
            return Symbol(name)
        return val
Example #24
0
 def lookup_name(self, name):
     assert isinstance(name, six.string_types)
     return ensure_context(name)
Example #25
0
 def lookup_name(self, name):
     assert isinstance(name, str)
     return ensure_context(name)
Example #26
0
 def lookup_name(self, name):
     assert isinstance(name, str)
     context = "System`" if name in SYSTEM_LIST else "Pymathics`"
     # print("XXX", name, context)
     return ensure_context(name, context)
Example #27
0
 def lookup_name(self, name):
     assert isinstance(name, basestring)
     return ensure_context(name)
Example #28
0
 def lookup_name(self, name):
     assert isinstance(name, six.string_types)
     return ensure_context(name)
Example #29
0
    def contribute(self, definitions):
        from mathics.core.parser import parse_builtin_rule

        name = self.get_name()
        rules = []
        for pattern, function in self.get_functions():
            rules.append(BuiltinRule(pattern, function, system=True))
        for pattern, replace in self.rules.items():
            if not isinstance(pattern, BaseExpression):
                pattern = pattern % {'name': name}
                pattern = parse_builtin_rule(pattern)
            replace = replace % {'name': name}
            rules.append(Rule(pattern, parse_builtin_rule(replace), system=True))

        box_rules = []
        if name != 'System`MakeBoxes':
            new_rules = []
            for rule in rules:
                if rule.pattern.get_head_name() == 'System`MakeBoxes':
                    box_rules.append(rule)
                else:
                    new_rules.append(rule)
            rules = new_rules

        def extract_forms(name, pattern):
            # Handle a tuple of (forms, pattern) as well as a pattern
            # on the left-hand side of a format rule. 'forms' can be
            # an empty string (=> the rule applies to all forms), or a
            # form name (like 'System`TraditionalForm'), or a sequence
            # of form names.
            def contextify_form_name(f):
                # Handle adding 'System`' to a form name, unless it's
                # '' (meaning the rule applies to all forms).
                return '' if f == '' else ensure_context(f)
            if isinstance(pattern, tuple):
                forms, pattern = pattern
                if isinstance(forms, str):
                    forms = [contextify_form_name(forms)]
                else:
                    forms = [contextify_form_name(f) for f in forms]
            else:
                forms = ['']
            return forms, pattern

        formatvalues = {'': []}
        for pattern, function in self.get_functions('format_'):
            forms, pattern = extract_forms(name, pattern)
            for form in forms:
                if form not in formatvalues:
                    formatvalues[form] = []
                formatvalues[form].append(BuiltinRule(
                    pattern, function, system=True))
        for pattern, replace in self.formats.items():
            forms, pattern = extract_forms(name, pattern)
            for form in forms:
                if not form in formatvalues:
                    formatvalues[form] = []
                if not isinstance(pattern, BaseExpression):
                    pattern = parse_builtin_rule(pattern)
                formatvalues[form].append(Rule(
                    pattern, parse_builtin_rule(replace), system=True))
        for form, formatrules in formatvalues.items():
            formatrules.sort()

        messages = [Rule(Expression('MessageName', Symbol(name), String(msg)),
                         String(value), system=True)
                    for msg, value in self.messages.items()]

        if name == 'System`MakeBoxes':
            attributes = []
        else:
            attributes = ['System`Protected']
        attributes += list(ensure_context(a) for a in self.attributes)
        options = {}
        for option, value in self.options.iteritems():
            option = ensure_context(option)
            options[option] = parse_builtin_rule(value)
            if option.startswith('System`'):
                # Create a definition for the option's symbol.
                # Otherwise it'll be created in Global` when it's
                # used, so it won't work.
                if option not in definitions.builtin:
                    definitions.builtin[option] = Definition(
                        name=name, attributes=set())
        defaults = []
        for spec, value in self.defaults.iteritems():
            value = parse_builtin_rule(value)
            pattern = None
            if spec is None:
                pattern = Expression('Default', Symbol(name))
            elif isinstance(spec, int):
                pattern = Expression('Default', Symbol(name), Integer(spec))
            if pattern is not None:
                defaults.append(Rule(pattern, value, system=True))
        definition = Definition(
            name=name, rules=rules, formatvalues=formatvalues,
            messages=messages, attributes=attributes, options=options,
            defaultvalues=defaults)
        definitions.builtin[name] = definition

        makeboxes_def = definitions.builtin['System`MakeBoxes']
        for rule in box_rules:
            makeboxes_def.add_rule(rule)
Example #30
0
 def contextify_form_name(f):
     # Handle adding 'System`' to a form name, unless it's
     # '' (meaning the rule applies to all forms).
     return '' if f == '' else ensure_context(f)
Example #31
0
    def contribute(self, definitions):
        from mathics.core.parser import parse_builtin_rule

        name = self.get_name()
        rules = []
        for pattern, function in self.get_functions():
            rules.append(BuiltinRule(pattern, function, system=True))
        for pattern, replace in self.rules.items():
            if not isinstance(pattern, BaseExpression):
                pattern = pattern % {'name': name}
                pattern = parse_builtin_rule(pattern)
            replace = replace % {'name': name}
            rules.append(
                Rule(pattern, parse_builtin_rule(replace), system=True))

        box_rules = []
        if name != 'System`MakeBoxes':
            new_rules = []
            for rule in rules:
                if rule.pattern.get_head_name() == 'System`MakeBoxes':
                    box_rules.append(rule)
                else:
                    new_rules.append(rule)
            rules = new_rules

        def extract_forms(name, pattern):
            # Handle a tuple of (forms, pattern) as well as a pattern
            # on the left-hand side of a format rule. 'forms' can be
            # an empty string (=> the rule applies to all forms), or a
            # form name (like 'System`TraditionalForm'), or a sequence
            # of form names.
            def contextify_form_name(f):
                # Handle adding 'System`' to a form name, unless it's
                # '' (meaning the rule applies to all forms).
                return '' if f == '' else ensure_context(f)

            if isinstance(pattern, tuple):
                forms, pattern = pattern
                if isinstance(forms, str):
                    forms = [contextify_form_name(forms)]
                else:
                    forms = [contextify_form_name(f) for f in forms]
            else:
                forms = ['']
            return forms, pattern

        formatvalues = {'': []}
        for pattern, function in self.get_functions('format_'):
            forms, pattern = extract_forms(name, pattern)
            for form in forms:
                if form not in formatvalues:
                    formatvalues[form] = []
                formatvalues[form].append(
                    BuiltinRule(pattern, function, system=True))
        for pattern, replace in self.formats.items():
            forms, pattern = extract_forms(name, pattern)
            for form in forms:
                if not form in formatvalues:
                    formatvalues[form] = []
                if not isinstance(pattern, BaseExpression):
                    pattern = parse_builtin_rule(pattern)
                formatvalues[form].append(
                    Rule(pattern, parse_builtin_rule(replace), system=True))
        for form, formatrules in formatvalues.items():
            formatrules.sort()

        messages = [
            Rule(Expression('MessageName', Symbol(name), String(msg)),
                 String(value),
                 system=True) for msg, value in self.messages.items()
        ]

        if name == 'System`MakeBoxes':
            attributes = []
        else:
            attributes = ['System`Protected']
        attributes += list(ensure_context(a) for a in self.attributes)
        options = {}
        for option, value in self.options.iteritems():
            option = ensure_context(option)
            options[option] = parse_builtin_rule(value)
            if option.startswith('System`'):
                # Create a definition for the option's symbol.
                # Otherwise it'll be created in Global` when it's
                # used, so it won't work.
                if option not in definitions.builtin:
                    definitions.builtin[option] = Definition(name=name,
                                                             attributes=set())
        defaults = []
        for spec, value in self.defaults.iteritems():
            value = parse_builtin_rule(value)
            pattern = None
            if spec is None:
                pattern = Expression('Default', Symbol(name))
            elif isinstance(spec, int):
                pattern = Expression('Default', Symbol(name), Integer(spec))
            if pattern is not None:
                defaults.append(Rule(pattern, value, system=True))
        definition = Definition(name=name,
                                rules=rules,
                                formatvalues=formatvalues,
                                messages=messages,
                                attributes=attributes,
                                options=options,
                                defaultvalues=defaults)
        definitions.builtin[name] = definition

        makeboxes_def = definitions.builtin['System`MakeBoxes']
        for rule in box_rules:
            makeboxes_def.add_rule(rule)
Example #32
0
 def filter_leaves(self, head_name):
     head_name = ensure_context(head_name)
     return [leaf for leaf in self.leaves
             if leaf.get_head_name() == head_name]
Example #33
0
    def contribute(self, definitions, pymodule=False):
        from mathics.core.parser import parse_builtin_rule

        name = self.get_name()

        options = {}
        option_syntax = 'Warn'
        for option, value in self.options.items():
            if option == '$OptionSyntax':
                option_syntax = value
                continue
            option = ensure_context(option)
            options[option] = parse_builtin_rule(value)
            if option.startswith('System`'):
                # Create a definition for the option's symbol.
                # Otherwise it'll be created in Global` when it's
                # used, so it won't work.
                if option not in definitions.builtin:
                    definitions.builtin[option] = Definition(name=name,
                                                             attributes=set())

        # Check if the given options are actually supported by the Builtin.
        # If not, we might issue an optx error and abort. Using '$OptionSyntax'
        # in your Builtin's 'options', you can specify the exact behaviour
        # using one of the following values:

        # - 'Strict': warn and fail with unsupported options
        # - 'Warn': warn about unsupported options, but continue
        # - 'Ignore': allow unsupported options, do not warn

        if option_syntax in ('Strict', 'Warn', 'System`Strict', 'System`Warn'):

            def check_options(options_to_check, evaluation):
                name = self.get_name()
                for key, value in options_to_check.items():
                    short_key = strip_context(key)
                    if not has_option(options, short_key, evaluation):
                        evaluation.message(
                            name, 'optx', Expression('Rule', short_key, value),
                            strip_context(name))
                        if option_syntax in ('Strict', 'System`Strict'):
                            return False
                return True
        elif option_syntax in ("Ignore", "System`Ignore"):
            check_options = None
        else:
            raise ValueError('illegal option mode %s; check $OptionSyntax.' %
                             option_syntax)

        rules = []
        for pattern, function in self.get_functions():
            rules.append(
                BuiltinRule(name,
                            pattern,
                            function,
                            check_options,
                            system=True))
        for pattern, replace in self.rules.items():
            if not isinstance(pattern, BaseExpression):
                pattern = pattern % {'name': name}
                pattern = parse_builtin_rule(pattern)
            replace = replace % {'name': name}
            rules.append(
                Rule(pattern, parse_builtin_rule(replace), system=True))

        box_rules = []
        if name != 'System`MakeBoxes':
            new_rules = []
            for rule in rules:
                if rule.pattern.get_head_name() == 'System`MakeBoxes':
                    box_rules.append(rule)
                else:
                    new_rules.append(rule)
            rules = new_rules

        def extract_forms(name, pattern):
            # Handle a tuple of (forms, pattern) as well as a pattern
            # on the left-hand side of a format rule. 'forms' can be
            # an empty string (=> the rule applies to all forms), or a
            # form name (like 'System`TraditionalForm'), or a sequence
            # of form names.
            def contextify_form_name(f):
                # Handle adding 'System`' to a form name, unless it's
                # '' (meaning the rule applies to all forms).
                return '' if f == '' else ensure_context(f)

            if isinstance(pattern, tuple):
                forms, pattern = pattern
                if isinstance(forms, str):
                    forms = [contextify_form_name(forms)]
                else:
                    forms = [contextify_form_name(f) for f in forms]
            else:
                forms = ['']
            return forms, pattern

        formatvalues = {'': []}
        for pattern, function in self.get_functions('format_'):
            forms, pattern = extract_forms(name, pattern)
            for form in forms:
                if form not in formatvalues:
                    formatvalues[form] = []
                formatvalues[form].append(
                    BuiltinRule(name, pattern, function, None, system=True))
        for pattern, replace in self.formats.items():
            forms, pattern = extract_forms(name, pattern)
            for form in forms:
                if form not in formatvalues:
                    formatvalues[form] = []
                if not isinstance(pattern, BaseExpression):
                    pattern = pattern % {'name': name}
                    pattern = parse_builtin_rule(pattern)
                replace = replace % {'name': name}
                formatvalues[form].append(
                    Rule(pattern, parse_builtin_rule(replace), system=True))
        for form, formatrules in formatvalues.items():
            formatrules.sort()

        messages = [
            Rule(Expression('MessageName', Symbol(name), String(msg)),
                 String(value),
                 system=True) for msg, value in self.messages.items()
        ]

        messages.append(
            Rule(Expression('MessageName', Symbol(name), String('optx')),
                 String('`1` is not a supported option for `2`[].'),
                 system=True))

        if name == 'System`MakeBoxes':
            attributes = []
        else:
            attributes = ['System`Protected']
        attributes += list(ensure_context(a) for a in self.attributes)
        options = {}
        for option, value in self.options.items():
            option = ensure_context(option)
            options[option] = parse_builtin_rule(value)
            if option.startswith('System`'):
                # Create a definition for the option's symbol.
                # Otherwise it'll be created in Global` when it's
                # used, so it won't work.
                if option not in definitions.builtin:
                    definitions.builtin[option] = Definition(name=name,
                                                             attributes=set())
        defaults = []
        for spec, value in self.defaults.items():
            value = parse_builtin_rule(value)
            pattern = None
            if spec is None:
                pattern = Expression('Default', Symbol(name))
            elif isinstance(spec, int):
                pattern = Expression('Default', Symbol(name), Integer(spec))
            if pattern is not None:
                defaults.append(Rule(pattern, value, system=True))
        definition = Definition(name=name,
                                rules=rules,
                                formatvalues=formatvalues,
                                messages=messages,
                                attributes=attributes,
                                options=options,
                                defaultvalues=defaults)
        if pymodule:
            definitions.pymathics[name] = definition
        else:
            definitions.builtin[name] = definition

        makeboxes_def = definitions.builtin['System`MakeBoxes']
        for rule in box_rules:
            makeboxes_def.add_rule(rule)
Example #34
0
 def filter_leaves(self, head_name):
     head_name = ensure_context(head_name)
     return [
         leaf for leaf in self.leaves if leaf.get_head_name() == head_name
     ]
Example #35
0
 def contextify_form_name(f):
     # Handle adding 'System`' to a form name, unless it's
     # '' (meaning the rule applies to all forms).
     return '' if f == '' else ensure_context(f)