Example #1
0
    def check(self, expr1, expr2):
        if isinstance(expr1, six.string_types):
            expr1 = parse(expr1)
        if isinstance(expr2, six.string_types):
            expr2 = parse(expr2)

        self.assertTrue(expr1.same(expr2))
Example #2
0
    def check(self, expr1, expr2):
        if isinstance(expr1, basestring):
            expr1 = parse(expr1)
        if isinstance(expr2, basestring):
            expr2 = parse(expr2)

        self.assertTrue(expr1.same(expr2))
Example #3
0
    def check(self, expr1, expr2):
        if isinstance(expr1, basestring):
            expr1 = parse(expr1)
        if isinstance(expr2, basestring):
            expr2 = parse(expr2)

        self.assertTrue(expr1.same(expr2))
Example #4
0
    def check(self, expr1, expr2):
        if isinstance(expr1, six.string_types):
            expr1 = parse(expr1)
        if isinstance(expr2, six.string_types):
            expr2 = parse(expr2)

        if expr1 is None:
            self.assertTrue(expr2 is None)
        else:
            self.assertTrue(expr1.same(expr2))
Example #5
0
    def test_CompoundExpression(self):
        self.check('f[a;\nb]', 'f[CompoundExpression[a, b]]')
        self.check('f[a;\nb;\nc;]', 'f[CompoundExpression[a, b, c, Null]]')
        self.check('f[a;\nb;\nc;\n]', 'f[CompoundExpression[a, b, c, Null]]')

        self.check('a;^b', 'Power[CompoundExpression[a, Null], b]')

        feeder = MultiLineFeeder('a;\n^b')
        self.compare(parse(definitions, feeder), self.parse('CompoundExpression[a, Null]'))
        self.assertRaises(InvalidSyntaxError, lambda f: parse(definitions, f), feeder)
Example #6
0
    def test_CompoundExpression(self):
        self.check("f[a;\nb]", "f[CompoundExpression[a, b]]")
        self.check("f[a;\nb;\nc;]", "f[CompoundExpression[a, b, c, Null]]")
        self.check("f[a;\nb;\nc;\n]", "f[CompoundExpression[a, b, c, Null]]")

        self.check("a;^b", "Power[CompoundExpression[a, Null], b]")

        feeder = MultiLineFeeder("a;\n^b")
        self.compare(parse(definitions, feeder),
                     self.parse("CompoundExpression[a, Null]"))
        self.assertRaises(InvalidSyntaxError, lambda f: parse(definitions, f),
                          feeder)
Example #7
0
    def apply(self, seq, evaluation):
        "ToExpression[seq__]"

        # Organise Arguments
        py_seq = seq.get_sequence()
        if len(py_seq) == 1:
            (inp, form, head) = (py_seq[0], Symbol("InputForm"), None)
        elif len(py_seq) == 2:
            (inp, form, head) = (py_seq[0], py_seq[1], None)
        elif len(py_seq) == 3:
            (inp, form, head) = (py_seq[0], py_seq[1], py_seq[2])
        else:
            assert len(py_seq) > 3  # 0 case handled by apply_empty
            evaluation.message(
                "ToExpression",
                "argb",
                "ToExpression",
                Integer(len(py_seq)),
                Integer1,
                Integer(3),
            )
            return

        # Apply the different forms
        if form == Symbol("InputForm"):
            if isinstance(inp, String):

                # TODO: turn the below up into a function and call that.
                s = inp.get_string_value()
                short_s = s[:15] + "..." if len(s) > 16 else s
                with io.StringIO(s) as f:
                    f.name = """ToExpression['%s']""" % short_s
                    feeder = MathicsFileLineFeeder(f)
                    while not feeder.empty():
                        try:
                            query = parse(evaluation.definitions, feeder)
                        except TranslateError:
                            return SymbolFailed
                        finally:
                            feeder.send_messages(evaluation)
                        if query is None:  # blank line / comment
                            continue
                        result = query.evaluate(evaluation)

            else:
                result = inp
        else:
            evaluation.message("ToExpression", "interpfmt", form)
            return

        # Apply head if present
        if head is not None:
            result = Expression(head, result).evaluate(evaluation)

        return result
Example #8
0
 def parse_feeder(self, feeder):
     'Parse a single expression from feeder and print the messages.'
     from mathics.core.parser import parse, TranslateError
     try:
         result = parse(self.definitions, feeder)
     except TranslateError as exc:
         self.recursion_depth = 0
         self.stopped = False
         result = None
     feeder.send_messages(self)
     return result
Example #9
0
 def parse(self, query, timeout=None):
     'parse a single line and capture the exceptions as messages'
     from mathics.core.parser import parse, TranslateError
     try:
         expr = parse(query, self.definitions)
     except TranslateError as exc:
         self.recursion_depth = 0
         self.stopped = False
         self.message('Syntax', exc.msg, *exc.args)
         return []
     return [expr]
Example #10
0
 def parse_feeder(self, feeder):
     'Parse a single expression from feeder and print the messages.'
     from mathics.core.parser import parse, TranslateError
     try:
         result = parse(self.definitions, feeder)
     except TranslateError as exc:
         self.recursion_depth = 0
         self.stopped = False
         result = None
     feeder.send_messages(self)
     return result
Example #11
0
 def parse(self, query, timeout=None):
     'parse a single line and capture the exceptions as messages'
     from mathics.core.parser import parse, TranslateError
     try:
         expr = parse(query, self.definitions)
     except TranslateError as exc:
         self.recursion_depth = 0
         self.stopped = False
         self.message('Syntax', exc.msg, *exc.args)
         return []
     return [expr]
Example #12
0
    def apply_int(self, n, prop, evaluation):
        "ElementData[n_?IntegerQ, prop_]"

        from mathics.core.parser import parse

        py_n = n.to_python()
        py_prop = prop.to_python()

        # Check element specifier n or "name"
        if isinstance(py_n, int):
            if not 1 <= py_n <= 118:
                evaluation.message("ElementData", "noent", n)
                return
        elif isinstance(py_n, six.string_types):
            pass
        else:
            evaluation.message("ElementData", "noent", n)
            return

        # Check property specifier
        if isinstance(py_prop, six.string_types):
            py_prop = str(py_prop)

        if py_prop == '"Properties"':
            result = []
            for i, p in enumerate(_ELEMENT_DATA[py_n]):
                if p not in ["NOT_AVAILABLE", "NOT_APPLICABLE", "NOT_KNOWN"]:
                    result.append(_ELEMENT_DATA[0][i])
            return from_python(sorted(result))

        if not (isinstance(py_prop, six.string_types)
                and py_prop[0] == py_prop[-1] == '"'
                and py_prop.strip('"') in _ELEMENT_DATA[0]):
            evaluation.message("ElementData", "noprop", prop)
            return

        iprop = _ELEMENT_DATA[0].index(py_prop.strip('"'))
        result = _ELEMENT_DATA[py_n][iprop]

        if result == "NOT_AVAILABLE":
            return Expression("Missing", "NotAvailable")

        if result == "NOT_APPLICABLE":
            return Expression("Missing", "NotApplicable")

        if result == "NOT_KNOWN":
            return Expression("Missing", "Unknown")

        result = parse(result, evaluation.definitions)
        if isinstance(result, Symbol):
            result = String(strip_context(result.get_name()))
        return result
Example #13
0
    def apply_int(self, n, prop, evaluation):
        "ElementData[n_?IntegerQ, prop_]"

        from mathics.core.parser import parse

        py_n = n.to_python()
        py_prop = prop.to_python()

        # Check element specifier n or "name"
        if isinstance(py_n, int):
            if not 1 <= py_n <= 118:
                evaluation.message("ElementData", "noent", n)
                return
        elif isinstance(py_n, six.string_types):
            pass
        else:
            evaluation.message("ElementData", "noent", n)
            return

        # Check property specifier
        if isinstance(py_prop, six.string_types):
            py_prop = str(py_prop)

        if py_prop == '"Properties"':
            result = []
            for i, p in enumerate(_ELEMENT_DATA[py_n]):
                if p not in ["NOT_AVAILABLE", "NOT_APPLICABLE", "NOT_KNOWN"]:
                    result.append(_ELEMENT_DATA[0][i])
            return from_python(sorted(result))

        if not (isinstance(py_prop, six.string_types) and
                py_prop[0] == py_prop[-1] == '"' and
                py_prop.strip('"') in _ELEMENT_DATA[0]):
            evaluation.message("ElementData", "noprop", prop)
            return

        iprop = _ELEMENT_DATA[0].index(py_prop.strip('"'))
        result = _ELEMENT_DATA[py_n][iprop]

        if result == "NOT_AVAILABLE":
            return Expression("Missing", "NotAvailable")

        if result == "NOT_APPLICABLE":
            return Expression("Missing", "NotApplicable")

        if result == "NOT_KNOWN":
            return Expression("Missing", "Unknown")

        result = parse(result, evaluation.definitions)
        if isinstance(result, Symbol):
            result = String(strip_context(result.get_name()))
        return result
Example #14
0
    def __init__(self,
                 input=None,
                 definitions=None,
                 timeout=None,
                 out_callback=None,
                 format='text',
                 catch_interrupt=True):
        from mathics.core.definitions import Definitions

        if definitions is None:
            definitions = Definitions()
        self.definitions = definitions
        self.recursion_depth = 0
        self.timeout = False
        self.stopped = False
        self.out = []
        self.out_callback = out_callback
        self.listeners = {}
        self.options = None

        self.quiet_all = False
        self.quiet_messages = set()

        self.format = format

        queries = []
        last_parse_error = None
        if input is not None:
            from mathics.core.parser import parse, TranslateError

            lines = input.splitlines()
            query = ''
            for line in lines:
                if line:
                    query += line
                    try:
                        expression = parse(query)
                        if expression is not None:
                            queries.append(expression)
                        query = ''
                        last_parse_error = None
                    except TranslateError, exc:
                        last_parse_error = exc
                else:
                    query += ' '
Example #15
0
 def get_functions(self, prefix='apply'):
     from mathics.core.parser import parse
          
     for name in dir(self):
         if name.startswith(prefix):
             function = getattr(self, name)
             pattern = function.__doc__
             m = re.match(r'([\w,]+)\:\s*(.*)', pattern)
             if m is not None:
                 attrs = m.group(1).split(',')
                 pattern = m.group(2)
             else:
                 attrs = []
             pattern = pattern % {'name': self.get_name()}
             pattern = parse(pattern)
             if attrs:
                 yield (attrs, pattern), function
             else:
                 yield (pattern, function)
Example #16
0
    def __init__(self, input=None, definitions=None, timeout=None,
                 out_callback=None, format='text', catch_interrupt=True):
        from mathics.core.definitions import Definitions

        if definitions is None:
            definitions = Definitions()
        self.definitions = definitions
        self.recursion_depth = 0
        self.timeout = False
        self.stopped = False
        self.out = []
        self.out_callback = out_callback
        self.listeners = {}
        self.options = None

        self.quiet_all = False
        self.quiet_messages = set()

        self.format = format

        queries = []
        last_parse_error = None
        if input is not None:
            from mathics.core.parser import parse, TranslateError

            lines = input.splitlines()
            query = ''
            for line in lines:
                if line:
                    query += line
                    try:
                        expression = parse(query)
                        if expression is not None:
                            queries.append(expression)
                        query = ''
                        last_parse_error = None
                    except TranslateError, exc:
                        last_parse_error = exc
                else:
                    query += ' '
Example #17
0
def parse_lines(lines, definitions):
    '''
    Given some lines of code try to construct a list of expressions.

    In the case of incomplete lines append more lines until a complete
    expression is found. If the end is reached and no complete expression is
    found then reraise the exception.

    We use a generator so that each expression can be evaluated (as the parser
    is dependent on defintions and evaluation may change the definitions).
    '''
    query = ''
    lines = lines.splitlines()

    incomplete_exc = None
    for line in lines:
        if not line:
            query += ' '
            continue
        query += line
        if query.endswith('\\'):
            query = query.rstrip('\\')
            incomplete_exc = IncompleteSyntaxError(len(query)-1)
            continue
        try:
            expression = parse(definitions, SingleLineFeeder(query))
        except IncompleteSyntaxError as exc:
            incomplete_exc = exc
        else:
            if expression is not None:
                yield expression
            query = ''
            incomplete_exc = None

    if incomplete_exc is not None:
        # ran out of lines
        raise incomplete_exc

    raise StopIteration
Example #18
0
def parse_lines(lines, definitions):
    '''
    Given some lines of code try to construct a list of expressions.

    In the case of incomplete lines append more lines until a complete
    expression is found. If the end is reached and no complete expression is
    found then reraise the exception.

    We use a generator so that each expression can be evaluated (as the parser
    is dependent on defintions and evaluation may change the definitions).
    '''
    query = ''
    lines = lines.splitlines()

    incomplete_exc = None
    for line in lines:
        if not line:
            query += ' '
            continue
        query += line
        if query.endswith('\\'):
            query = query.rstrip('\\')
            incomplete_exc = IncompleteSyntaxError(len(query) - 1)
            continue
        try:
            expression = parse(definitions, SingleLineFeeder(query))
        except IncompleteSyntaxError as exc:
            incomplete_exc = exc
        else:
            if expression is not None:
                yield expression
            query = ''
            incomplete_exc = None

    if incomplete_exc is not None:
        # ran out of lines
        raise incomplete_exc

    raise StopIteration
Example #19
0
    def apply(self, seq, evaluation):
        'ToExpression[seq__]'

        # Organise Arguments
        py_seq = seq.get_sequence()
        if len(py_seq) == 1:
            (inp, form, head) = (py_seq[0], Symbol('InputForm'), None)
        elif len(py_seq) == 2:
            (inp, form, head) = (py_seq[0], py_seq[1], None)
        elif len(py_seq) == 3:
            (inp, form, head) = (py_seq[0], py_seq[1], py_seq[2])
        else:
            assert len(py_seq) > 3  # 0 case handled by apply_empty
            evaluation.message('ToExpression', 'argb', 'ToExpression',
                               Integer(len(py_seq)), Integer(1), Integer(3))
            return

        # Apply the differnet forms
        if form == Symbol('InputForm'):
            if isinstance(inp, String):
                from mathics.core.parser import parse, ParseError
                try:
                    result = parse(
                        inp.get_string_value(), evaluation.definitions)
                except ParseError:
                    evaluation.message('ToExpression', 'sntxi', String(''))
                    return Symbol('$Failed')
            else:
                result = inp
        else:
            evaluation.message('ToExpression', 'interpfmt', form)
            return

        # Apply head if present
        if head is not None:
            result = Expression(head, result).evaluate(evaluation)

        return result
Example #20
0
def benchmark_parse(expression_string):
    print "  '{0}'".format(truncate_line(expression_string))
    timeit(lambda: parse(expression_string))
Example #21
0
def benchmark_expression(expression_string):
    print "  '{0}'".format(expression_string)
    expr = parse(expression_string)
    timeit(lambda: expr.evaluate(evaluation))
Example #22
0
def benchmark_format(section_name):
    print "  '{0}'".format(expression_string)
    expr = parse(expression_string)
    timeit(lambda: expr.default_format(evaluation, "FullForm"))
Example #23
0
 def testNone(self):
     self.assertIs(parse(''), None)
     self.assertIs(parse('(*fdasf *)'), None)
Example #24
0
 def parse(self, code):
     return parse(definitions, SingleLineFeeder(code))
Example #25
0
def benchmark_format(expression_string):
    print("  '{0}'".format(expression_string))
    expr = parse(definitions, SingleLineFeeder(expression_string))
    timeit(lambda: expr.default_format(evaluation, "FullForm"))
Example #26
0
def benchmark_parse(expression_string):
    print("  '{0}'".format(truncate_line(expression_string)))
    timeit(lambda: parse(definitions, SingleLineFeeder(expression_string)))
Example #27
0
def benchmark_expression(expression_string):
    print "  '{0}'".format(expression_string)
    expr = parse(expression_string)
    timeit(lambda: expr.evaluate(evaluation))
Example #28
0
 def evaluate(self, str_expression, timeout=None, form=None):
     expr = parse(self.definitions, MathicsSingleLineFeeder(str_expression))
     if form is None:
         form = self.form
     self.last_result = expr.evaluate(self.evaluation)
     return self.last_result
Example #29
0
def main():
    argparser = argparse.ArgumentParser(
        prog='mathics',
        usage='%(prog)s [options] [FILE]',
        add_help=False,
        description="Mathics is a general-purpose computer algebra system.",
        epilog="""Please feel encouraged to contribute to Mathics! Create
            your own fork, make the desired changes, commit, and make a pull
            request.""")

    argparser.add_argument(
        'FILE', nargs='?', type=argparse.FileType('r'),
        help='execute commands from FILE')

    argparser.add_argument(
        '--help', '-h', help='show this help message and exit', action='help')

    argparser.add_argument(
        '--persist', help='go to interactive shell after evaluating FILE or -e',
        action='store_true')

    argparser.add_argument(
        '--quiet', '-q', help='don\'t print message at startup',
        action='store_true')

    argparser.add_argument(
        '-script', help='run a mathics file in script mode',
        action='store_true')

    argparser.add_argument(
        '--execute', '-e', action='append', metavar='EXPR',
        help='evaluate EXPR before processing any input files (may be given '
        'multiple times)')

    argparser.add_argument(
        '--colors', nargs='?', help='interactive shell colors')

    argparser.add_argument(
        '--no-completion', help="disable tab completion", action='store_true')

    argparser.add_argument(
        '--no-readline', help="disable line editing (implies --no-completion)",
        action='store_true')

    argparser.add_argument(
        '--version', '-v', action='version',
        version='%(prog)s ' + __version__)

    args = argparser.parse_args()

    quit_command = 'CTRL-BREAK' if sys.platform == 'win32' else 'CONTROL-D'

    definitions = Definitions(add_builtin=True)
    definitions.set_ownvalue('$Line', Integer(0))  # Reset the line number

    shell = TerminalShell(
        definitions, args.colors, want_readline=not(args.no_readline),
        want_completion=not(args.no_completion))

    if not (args.quiet or args.script):
        print()
        print(version_string + '\n')
        print(license_string + '\n')
        print("Quit by pressing {0}\n".format(quit_command))

    if args.execute:
        for expr in args.execute:
            print(shell.get_in_prompt() + expr)
            evaluation = Evaluation(shell.definitions, out_callback=shell.out_callback)
            exprs = evaluation.parse(expr)
            results = evaluation.evaluate(exprs, timeout=settings.TIMEOUT)
            shell.print_results(results)

        if not args.persist:
            return

    if args.FILE is not None:
        lines = args.FILE.readlines()
        if args.script and lines[0].startswith('#!'):
            lines[0] = ''

        results = []
        query_gen = parse_lines(lines, shell.definitions)
        evaluation = Evaluation(shell.definitions, out_callback=shell.out_callback)
        try:
            for query in query_gen:
                results.extend(evaluation.evaluate([query], timeout=settings.TIMEOUT))
        except TranslateError as exc:
            evaluation.recursion_depth = 0
            evaluation.stopped = False
            evaluation.message('Syntax', exc.msg, *exc.args)
        except (KeyboardInterrupt):
            print('\nKeyboardInterrupt')
        except (SystemExit, EOFError):
            print("\n\nGood bye!\n")

        if not args.persist:
            return

    total_input = ""
    while True:
        try:
            evaluation = Evaluation(shell.definitions, out_callback=shell.out_callback)
            line = shell.read_line(shell.get_in_prompt(continued=total_input != ''))
            total_input += line
            try:
                query = parse(total_input, shell.definitions)
            except TranslateError as exc:
                if line == '' or not isinstance(exc, IncompleteSyntaxError):
                    evaluation.message('Syntax', exc.msg, *exc.args)
                    total_input = ""
                continue
            total_input = ""
            if query is None:
                continue
            results = evaluation.evaluate([query], timeout=settings.TIMEOUT)
            shell.print_results(results)
        except (KeyboardInterrupt):
            print('\nKeyboardInterrupt')
        except (SystemExit, EOFError):
            print("\n\nGood bye!\n")
            break
Example #30
0
#!/usr/bin/env python3
# -*- coding: utf-8 -*-


import unittest
from mathics.core.expression import Expression, Integer, Rational, Symbol
from mathics.core.definitions import Definitions
from mathics.core.evaluation import Evaluation
from mathics.core.parser import SingleLineFeeder, parse

definitions = Definitions(add_builtin=True)

for i in range(1, 4):
  evaluation = Evaluation(definitions=definitions, catch_interrupt=False)

  expr = parse(definitions, SingleLineFeeder(f"<< GS{i}.m"))
  expr.evaluate(evaluation)


Example #31
0
 def testNone(self):
     self.assertIs(parse(''), None)
     self.assertIs(parse('(*fdasf *)'), None)
Example #32
0
 def test_Span(self):
     self.check('a;;^b', 'Power[Span[a, All], b]')
     feeder = MultiLineFeeder('a;;\n^b')
     self.compare(parse(definitions, feeder), self.parse('Span[a, All]'))
     self.assertRaises(InvalidSyntaxError, lambda f: parse(definitions, f), feeder)
Example #33
0
def benchmark_format(expression_string):
    print "  '{0}'".format(expression_string)
    expr = parse(expression_string)
    timeit(lambda: expr.default_format(evaluation, "FullForm"))
Example #34
0
 def do_parse():
     feeder = MultiLineFeeder(code)
     while not feeder.empty():
         parse(definitions, feeder)
Example #35
0
 def parse(self, code):
     return parse(definitions, MultiLineFeeder(code))
Example #36
0
def benchmark_expression(expression_string):
    print("  '{0}'".format(expression_string))
    expr = parse(definitions, SingleLineFeeder(expression_string))
    timeit(lambda: expr.evaluate(evaluation))
Example #37
0
def benchmark_parse(expression_string):
    print "  '{0}'".format(truncate_line(expression_string))
    timeit(lambda: parse(expression_string))
Example #38
0
 def test_Span(self):
     self.check("a;;^b", "Power[Span[a, All], b]")
     feeder = MultiLineFeeder("a;;\n^b")
     self.compare(parse(definitions, feeder), self.parse("Span[a, All]"))
     self.assertRaises(InvalidSyntaxError, lambda f: parse(definitions, f),
                       feeder)
Example #39
0
def _evaluate(str_expression):
    expr = parse(definitions, SingleLineFeeder(str_expression))
    return expr.evaluate(evaluation)
Example #40
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 #41
0
def main():
    argparser = argparse.ArgumentParser(
        prog='mathics',
        usage='%(prog)s [options] [FILE]',
        add_help=False,
        description="Mathics is a general-purpose computer algebra system.",
        epilog="""Please feel encouraged to contribute to Mathics! Create
            your own fork, make the desired changes, commit, and make a pull
            request.""")

    argparser.add_argument('FILE',
                           nargs='?',
                           type=argparse.FileType('r'),
                           help='execute commands from FILE')

    argparser.add_argument('--help',
                           '-h',
                           help='show this help message and exit',
                           action='help')

    argparser.add_argument(
        '--persist',
        help='go to interactive shell after evaluating FILE or -e',
        action='store_true')

    argparser.add_argument('--quiet',
                           '-q',
                           help='don\'t print message at startup',
                           action='store_true')

    argparser.add_argument('-script',
                           help='run a mathics file in script mode',
                           action='store_true')

    argparser.add_argument(
        '--execute',
        '-e',
        action='append',
        metavar='EXPR',
        help='evaluate EXPR before processing any input files (may be given '
        'multiple times)')

    argparser.add_argument('--colors',
                           nargs='?',
                           help='interactive shell colors')

    argparser.add_argument('--no-completion',
                           help="disable tab completion",
                           action='store_true')

    argparser.add_argument(
        '--no-readline',
        help="disable line editing (implies --no-completion)",
        action='store_true')

    argparser.add_argument('--version',
                           '-v',
                           action='version',
                           version='%(prog)s ' + __version__)

    args = argparser.parse_args()

    quit_command = 'CTRL-BREAK' if sys.platform == 'win32' else 'CONTROL-D'

    definitions = Definitions(add_builtin=True)
    definitions.set_line_no(0)  # Reset the line number

    shell = TerminalShell(definitions,
                          args.colors,
                          want_readline=not (args.no_readline),
                          want_completion=not (args.no_completion))

    if not (args.quiet or args.script):
        print()
        print(version_string + '\n')
        print(license_string + '\n')
        print("Quit by pressing {0}\n".format(quit_command))

    if args.execute:
        for expr in args.execute:
            print(shell.get_in_prompt() + expr)
            evaluation = Evaluation(shell.definitions,
                                    out_callback=shell.out_callback)
            exprs = evaluation.parse(expr)
            results = evaluation.evaluate(exprs, timeout=settings.TIMEOUT)
            shell.print_results(results)

        if not args.persist:
            return

    if args.FILE is not None:
        lines = args.FILE.readlines()
        if args.script and lines[0].startswith('#!'):
            lines[0] = ''

        results = []
        query_gen = parse_lines(lines, shell.definitions)
        evaluation = Evaluation(shell.definitions,
                                out_callback=shell.out_callback)
        try:
            for query in query_gen:
                results.extend(
                    evaluation.evaluate([query], timeout=settings.TIMEOUT))
        except TranslateError as exc:
            evaluation.recursion_depth = 0
            evaluation.stopped = False
            evaluation.message('Syntax', exc.msg, *exc.args)
        except (KeyboardInterrupt):
            print('\nKeyboardInterrupt')
        except (SystemExit, EOFError):
            print("\n\nGood bye!\n")

        if not args.persist:
            return

    total_input = ""
    while True:
        try:
            evaluation = Evaluation(shell.definitions,
                                    out_callback=shell.out_callback)
            line = shell.read_line(
                shell.get_in_prompt(continued=total_input != ''))
            total_input += line
            try:
                query = parse(total_input, shell.definitions)
            except TranslateError as exc:
                if line == '' or not isinstance(exc, IncompleteSyntaxError):
                    evaluation.message('Syntax', exc.msg, *exc.args)
                    total_input = ""
                continue
            total_input = ""
            if query is None:
                continue
            results = evaluation.evaluate([query], timeout=settings.TIMEOUT)
            shell.print_results(results)
        except (KeyboardInterrupt):
            print('\nKeyboardInterrupt')
        except (SystemExit, EOFError):
            print("\n\nGood bye!\n")
            break