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
def load_settings(shell): autoload_files(shell.definitions, get_srcdir(), "autoload") settings_file = ensure_settings() if settings_file == "": return with open(settings_file, "r") as src: feeder = MathicsFileLineFeeder(src) try: while not feeder.empty(): evaluation = Evaluation( shell.definitions, output=TerminalOutput(shell), catch_interrupt=False, format="text", ) query = evaluation.parse_feeder(feeder) if query is None: continue evaluation.evaluate(query) except (KeyboardInterrupt): print("\nKeyboardInterrupt") return True
def main() -> int: """ Command-line entry. Return exit code we want to give status of """ exit_rc = 0 argparser = argparse.ArgumentParser( prog="mathics", usage="%(prog)s [options] [FILE]", add_help=False, description="A simple command-line interface to Mathics", epilog= """For a more extensive command-line interface see "mathicsscript". Please contribute to Mathics!""", ) 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( "--full-form", "-F", help="Show how input was parsed to FullForm", action="store_true", ) argparser.add_argument( "--pyextensions", "-l", action="append", metavar="PYEXT", help="directory to load extensions in python", ) argparser.add_argument( "--persist", help="go to interactive shell after evaluating FILE or -e", action="store_true", ) # --initfile is different from the combination FILE --persist since the first one # leaves the history empty and sets the current $Line to 1. argparser.add_argument( "--initfile", help="the same that FILE and --persist together", type=argparse.FileType("r"), ) 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. Use value 'NoColor' or 'None' to disable ANSI color decoration", ) 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__) argparser.add_argument( "--strict-wl-output", help="Most WL-output compatible (at the expense of useability).", action="store_true", ) args, script_args = argparser.parse_known_args() quit_command = "CTRL-BREAK" if sys.platform == "win32" else "CONTROL-D" extension_modules = [] if args.pyextensions: for ext in args.pyextensions: extension_modules.append(ext) else: from mathics.settings import default_pymathics_modules extension_modules = default_pymathics_modules definitions = Definitions(add_builtin=True, extension_modules=extension_modules) definitions.set_line_no(0) shell = TerminalShell( definitions, args.colors, want_readline=not (args.no_readline), want_completion=not (args.no_completion), ) if args.initfile: feeder = MathicsFileLineFeeder(args.initfile) try: while not feeder.empty(): evaluation = Evaluation( shell.definitions, output=TerminalOutput(shell), catch_interrupt=False, ) query = evaluation.parse_feeder(feeder) if query is None: continue evaluation.evaluate(query, timeout=settings.TIMEOUT) except (KeyboardInterrupt): print("\nKeyboardInterrupt") definitions.set_line_no(0) if args.FILE is not None: feeder = MathicsFileLineFeeder(args.FILE) try: while not feeder.empty(): evaluation = Evaluation( shell.definitions, output=TerminalOutput(shell), catch_interrupt=False, ) query = evaluation.parse_feeder(feeder) if query is None: continue evaluation.evaluate(query, timeout=settings.TIMEOUT) except (KeyboardInterrupt): print("\nKeyboardInterrupt") if args.persist: definitions.set_line_no(0) elif not args.execute: return exit_rc if args.execute: for expr in args.execute: evaluation = Evaluation(shell.definitions, output=TerminalOutput(shell)) result = evaluation.parse_evaluate(expr, timeout=settings.TIMEOUT) shell.print_result(result, no_out_prompt=True, strict_wl_output=args.strict_wl_output) if evaluation.exc_result == Symbol("Null"): exit_rc = 0 elif evaluation.exc_result == Symbol("$Aborted"): exit_rc = -1 elif evaluation.exc_result == Symbol("Overflow"): exit_rc = -2 else: exit_rc = -3 if not args.persist: return exit_rc if not args.quiet: print() print(version_string + "\n") print(license_string + "\n") print(f"Quit by evaluating Quit[] or by pressing {quit_command}.\n") while True: try: evaluation = Evaluation(shell.definitions, output=TerminalOutput(shell)) query, source_code = evaluation.parse_feeder_returning_code(shell) if len(source_code) and source_code[0] == "!": subprocess.run(source_code[1:], shell=True) shell.definitions.increment_line_no(1) continue if query is None: continue if args.full_form: print(query) result = evaluation.evaluate(query, timeout=settings.TIMEOUT) if result is not None: shell.print_result(result, strict_wl_output=args.strict_wl_output) except (KeyboardInterrupt): print("\nKeyboardInterrupt") except EOFError: print("\n\nGoodbye!\n") break except SystemExit: print("\n\nGoodbye!\n") # raise to pass the error code on, e.g. Quit[1] raise finally: shell.reset_lineno() return exit_rc
def main( full_form, persist, quiet, readline, completion, unicode, prompt, pyextensions, execute, run, style, pygments_tokens, strict_wl_output, file, ) -> int: """A command-line interface to Mathics. Mathics is a general-purpose computer algebra system """ exit_rc = 0 quit_command = "CTRL-BREAK" if sys.platform == "win32" else "CONTROL-D" extension_modules = [] if pyextensions: for ext in pyextensions: extension_modules.append(ext) definitions = Definitions(add_builtin=True) definitions.set_line_no(0) # Set a default value for $ShowFullFormInput to False. # Then, it can be changed by the settings file (in WL) # and overwritten by the command line parameter. definitions.set_ownvalue( "Settings`$ShowFullFormInput", from_python(True if full_form else False) ) definitions.set_ownvalue( "Settings`$PygmentsShowTokens", from_python(True if pygments_tokens else False) ) readline = "none" if (execute or file and not persist) else readline.lower() if readline == "prompt": shell = TerminalShellPromptToolKit( definitions, style, completion, unicode, prompt ) else: want_readline = readline == "gnu" shell = TerminalShellGNUReadline( definitions, style, want_readline, completion, unicode, prompt ) load_settings(shell) if run: with open(run, "r") as ifile: feeder = MathicsFileLineFeeder(ifile) try: while not feeder.empty(): evaluation = Evaluation( shell.definitions, output=TerminalOutput(shell), catch_interrupt=False, format="text", ) query = evaluation.parse_feeder(feeder) if query is None: continue evaluation.evaluate(query, timeout=settings.TIMEOUT) except (KeyboardInterrupt): print("\nKeyboardInterrupt") definitions.set_line_no(0) if execute: for expr in execute: evaluation = Evaluation( shell.definitions, output=TerminalOutput(shell), format="text" ) shell.terminal_formatter = None result = evaluation.parse_evaluate(expr, timeout=settings.TIMEOUT) shell.print_result(result, prompt, "text", strict_wl_output) # After the next release, we can remove the hasattr test. if hasattr(evaluation, "exc_result"): if evaluation.exc_result == Symbol("Null"): exit_rc = 0 elif evaluation.exc_result == Symbol("$Aborted"): exit_rc = -1 elif evaluation.exc_result == Symbol("Overflow"): exit_rc = -2 else: exit_rc = -3 if not persist: return exit_rc if file is not None: with open(file, "r") as ifile: feeder = MathicsFileLineFeeder(ifile) try: while not feeder.empty(): evaluation = Evaluation( shell.definitions, output=TerminalOutput(shell), catch_interrupt=False, format="text", ) query = evaluation.parse_feeder(feeder) if query is None: continue evaluation.evaluate(query, timeout=settings.TIMEOUT) except (KeyboardInterrupt): print("\nKeyboardInterrupt") if not persist: return exit_rc if not quiet and prompt: print(f"\nMathicscript: {__version__}, {version_string}\n") print(license_string + "\n") print(f"Quit by evaluating Quit[] or by pressing {quit_command}.\n") # If defined, full_form and style overwrite the predefined values. definitions.set_ownvalue( "Settings`$ShowFullFormInput", SymbolTrue if full_form else SymbolFalse ) definitions.set_ownvalue( "Settings`$PygmentsStyle", from_python(shell.pygments_style) ) definitions.set_ownvalue( "Settings`$PygmentsShowTokens", from_python(pygments_tokens) ) definitions.set_ownvalue("Settings`MathicsScriptVersion", from_python(__version__)) definitions.set_attribute("Settings`MathicsScriptVersion", "System`Protected") definitions.set_attribute("Settings`MathicsScriptVersion", "System`Locked") TeXForm = Symbol("System`TeXForm") definitions.set_line_no(0) while True: try: if have_readline and shell.using_readline: import readline as GNU_readline last_pos = GNU_readline.get_current_history_length() full_form = definitions.get_ownvalue( "Settings`$ShowFullFormInput" ).replace.to_python() style = definitions.get_ownvalue("Settings`$PygmentsStyle") fmt = lambda x: x if style: style = style.replace.get_string_value() if shell.terminal_formatter: fmt = lambda x: highlight( str(query), mma_lexer, shell.terminal_formatter ) evaluation = Evaluation(shell.definitions, output=TerminalOutput(shell)) query, source_code = evaluation.parse_feeder_returning_code(shell) if ( have_readline and shell.using_readline and hasattr(GNU_readline, "remove_history_item") ): current_pos = GNU_readline.get_current_history_length() for pos in range(last_pos, current_pos - 1): GNU_readline.remove_history_item(pos) wl_input = source_code.rstrip() if unicode: wl_input = replace_wl_with_plain_text(wl_input) GNU_readline.add_history(wl_input) if query is None: continue if hasattr(query, "head") and query.head == TeXForm: output_style = "//TeXForm" else: output_style = "" if full_form: print(fmt(query)) result = evaluation.evaluate( query, timeout=settings.TIMEOUT, format="unformatted" ) if result is not None: shell.print_result( result, prompt, output_style, strict_wl_output=strict_wl_output ) except ShellEscapeException as e: source_code = e.line if len(source_code) and source_code[1] == "!": try: print(open(source_code[2:], "r").read()) except: print(str(sys.exc_info()[1])) else: subprocess.run(source_code[1:], shell=True) # Should we test exit code for adding to history? GNU_readline.add_history(source_code.rstrip()) # FIXME add this... when in Mathics core updated # shell.defintions.increment_line(1) except (KeyboardInterrupt): print("\nKeyboardInterrupt") except EOFError: if prompt: print("\n\nGoodbye!\n") break except SystemExit: print("\n\nGoodbye!\n") # raise to pass the error code on, e.g. Quit[1] raise finally: # Reset the input line that would be shown in a parse error. # This is not to be confused with the number of complete # inputs that have been seen, i.e. In[] shell.reset_lineno() return exit_rc