Example #1
0
 def contribute(self, definitions):
     from mathics.core.parser import parse
     
     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(pattern)
         replace = replace % {'name': name}
         rules.append(Rule(pattern, parse(replace), system=True))
         
     box_rules = []
     if name != 'MakeBoxes':
         new_rules = []
         for rule in rules:
             if rule.pattern.get_head_name() == 'MakeBoxes':
                 box_rules.append(rule)
             else:
                 new_rules.append(rule)
         rules = new_rules
         
     formatvalues = {'': []}
     for pattern, function in self.get_functions('format_'):
         if isinstance(pattern, tuple):
             forms, pattern = pattern
         else:
             forms = ['']
         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():
         if isinstance(pattern, tuple):
             forms, pattern = pattern
             if not isinstance(forms, tuple):
                 forms = [forms]
         else:
             forms, pattern = [''], pattern
         for form in forms:
             if not form in formatvalues:
                 formatvalues[form] = []
             formatvalues[form].append(Rule(parse(pattern), parse(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 == 'MakeBoxes':
         attributes = []
     else:
         attributes = ['Protected']
     attributes += list(self.attributes)
     options = {}
     for option, value in self.options.iteritems():
         options[option] = parse(value)
     defaults = []
     for spec, value in self.defaults.iteritems():
         value = parse(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['MakeBoxes']
     for rule in box_rules:
         makeboxes_def.add_rule(rule)
Example #2
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 #3
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)