diff options
author | Guido van Rossum <guido@python.org> | 1990-12-20 15:06:42 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1990-12-20 15:06:42 (GMT) |
commit | 3f5da24ea304e674a9abbdcffc4d671e32aa70f1 (patch) | |
tree | e932e31cb9381f40b7c87c377638216c043b5cfc /Python/pythonmain.c | |
parent | 226d79eb4a776dd54c9e4544b17deaf928bcef3a (diff) | |
download | cpython-3f5da24ea304e674a9abbdcffc4d671e32aa70f1.zip cpython-3f5da24ea304e674a9abbdcffc4d671e32aa70f1.tar.gz cpython-3f5da24ea304e674a9abbdcffc4d671e32aa70f1.tar.bz2 |
"Compiling" version
Diffstat (limited to 'Python/pythonmain.c')
-rw-r--r-- | Python/pythonmain.c | 395 |
1 files changed, 321 insertions, 74 deletions
diff --git a/Python/pythonmain.c b/Python/pythonmain.c index ffff0ae..f095cdd 100644 --- a/Python/pythonmain.c +++ b/Python/pythonmain.c @@ -1,24 +1,25 @@ /* Python interpreter main program */ -#include <stdio.h> -#include <ctype.h> -#include "string.h" +#include "allobjects.h" -extern char *getpythonpath(); - -#include "PROTO.h" #include "grammar.h" #include "node.h" #include "parsetok.h" #include "graminit.h" #include "errcode.h" -#include "object.h" -#include "stringobject.h" #include "sysmodule.h" +#include "compile.h" +#include "ceval.h" +#include "pythonrun.h" +#include "import.h" + +extern char *getpythonpath(); extern grammar gram; /* From graminit.c */ -int debugging; +#ifdef DEBUG +int debugging; /* Needed by parser.c */ +#endif main(argc, argv) int argc; @@ -26,15 +27,12 @@ main(argc, argv) { char *filename = NULL; FILE *fp = stdin; - int ret; - - initargs(&argc, &argv); - initintr(); /* For intrcheck() */ + initargs(&argc, &argv); if (argc > 1 && strcmp(argv[1], "-") != 0) filename = argv[1]; - + if (filename != NULL) { if ((fp = fopen(filename, "r")) == NULL) { fprintf(stderr, "python: can't open file '%s'\n", @@ -43,89 +41,339 @@ main(argc, argv) } } - /* XXX what is the ideal initialization order? */ - /* XXX exceptions are initialized by initrun but this - may be too late */ + initall(); + + setpythonpath(getpythonpath()); + setpythonargv(argc-1, argv+1); + + goaway(run(fp, filename == NULL ? "<stdin>" : filename)); + /*NOTREACHED*/ +} + +/* Initialize all */ + +void +initall() +{ + static int inited; + + if (inited) + return; + + initimport(); - initsys(argc-1, argv+1); + initbuiltin(); /* Also initializes builtin exceptions */ + initsys(); inittime(); initmath(); - setpythonpath(getpythonpath()); + initcalls(); /* Configuration-dependent initializations */ - initrun(); - initcalls(); + initintr(); /* For intrcheck() */ - if (!isatty(fileno(fp))) { - ret = runfile(fp, file_input, (char *)NULL, (char *)NULL); + inited = 1; +} + +/* Parse input from a file and execute it */ + +int +run(fp, filename) + FILE *fp; + char *filename; +{ + if (filename == NULL) + filename = "???"; + if (isatty(fileno(fp))) + return run_tty_loop(fp, filename); + else + return run_script(fp, filename); +} + +int +run_tty_loop(fp, filename) + FILE *fp; + char *filename; +{ + object *v; + int ret; + v = sysget("ps1"); + if (v == NULL) { + sysset("ps1", v = newstringobject(">>> ")); + XDECREF(v); + } + v = sysget("ps2"); + if (v == NULL) { + sysset("ps2", v = newstringobject("... ")); + XDECREF(v); + } + for (;;) { + ret = run_tty_1(fp, filename); +#ifdef REF_DEBUG + fprintf(stderr, "[%ld refs]\n", ref_total); +#endif + if (ret == E_EOF) + return 0; + /* + if (ret == E_NOMEM) + return -1; + */ + } +} + +int +run_tty_1(fp, filename) + FILE *fp; + char *filename; +{ + object *m, *d, *v, *w; + node *n; + char *ps1, *ps2; + int err; + v = sysget("ps1"); + w = sysget("ps2"); + if (v != NULL && is_stringobject(v)) { + INCREF(v); + ps1 = getstringvalue(v); } else { - object *v, *w; - sysset("ps1", v = newstringobject(">>> ")); - sysset("ps2", w = newstringobject("... ")); - DECREF(v); - DECREF(w); - for (;;) { - char *ps1 = NULL, *ps2 = NULL; - v = sysget("ps1"); - w = sysget("ps2"); - if (v != NULL && is_stringobject(v)) { - INCREF(v); - ps1 = getstringvalue(v); - } - else - v = NULL; - if (w != NULL && is_stringobject(w)) { - INCREF(w); - ps2 = getstringvalue(w); - } - else - w = NULL; - ret = runfile(fp, single_input, ps1, ps2); - if (v != NULL) - DECREF(v); - if (w != NULL) - DECREF(w); - if (ret == E_EOF || ret == E_NOMEM) - break; - } + v = NULL; + ps1 = ""; } - goaway(ret == E_DONE || ret == E_EOF ? 0 : 1); - /*NOTREACHED*/ + if (w != NULL && is_stringobject(w)) { + INCREF(w); + ps2 = getstringvalue(w); + } + else { + w = NULL; + ps2 = ""; + } + err = parsefile(fp, filename, &gram, single_input, ps1, ps2, &n); + XDECREF(v); + XDECREF(w); + if (err == E_EOF) + return E_EOF; + if (err != E_DONE) { + err_input(err); + print_error(); + return err; + } + m = add_module("__main__"); + if (m == NULL) + return -1; + d = getmoduledict(m); + v = run_node(n, filename, d, d); + flushline(); + if (v == NULL) { + print_error(); + return -1; + } + DECREF(v); + return 0; +} + +int +run_script(fp, filename) + FILE *fp; + char *filename; +{ + object *m, *d, *v; + m = add_module("__main__"); + if (m == NULL) + return -1; + d = getmoduledict(m); + v = run_file(fp, filename, file_input, d, d); + flushline(); + if (v == NULL) { + print_error(); + return -1; + } + DECREF(v); + return 0; +} + +void +print_error() +{ + object *exception, *v; + err_get(&exception, &v); + fprintf(stderr, "Unhandled exception: "); + printobject(exception, stderr, PRINT_RAW); + if (v != NULL && v != None) { + fprintf(stderr, ": "); + printobject(v, stderr, PRINT_RAW); + } + fprintf(stderr, "\n"); + XDECREF(exception); + XDECREF(v); + printtraceback(stderr); +} + +object * +run_string(str, start, globals, locals) + char *str; + int start; + /*dict*/object *globals, *locals; +{ + node *n; + int err; + err = parse_string(str, start, &n); + return run_err_node(err, n, "<string>", globals, locals); +} + +object * +run_file(fp, filename, start, globals, locals) + FILE *fp; + char *filename; + int start; + /*dict*/object *globals, *locals; +{ + node *n; + int err; + err = parse_file(fp, filename, start, &n); + return run_err_node(err, n, filename, globals, locals); +} + +object * +run_err_node(err, n, filename, globals, locals) + int err; + node *n; + char *filename; + /*dict*/object *globals, *locals; +{ + if (err != E_DONE) { + err_input(err); + return NULL; + } + return run_node(n, filename, globals, locals); +} + +object * +run_node(n, filename, globals, locals) + node *n; + char *filename; + /*dict*/object *globals, *locals; +{ + if (globals == NULL) { + globals = getglobals(); + if (locals == NULL) + locals = getlocals(); + } + else { + if (locals == NULL) + locals = globals; + } + return eval_node(n, filename, globals, locals); +} + +object * +eval_node(n, filename, globals, locals) + node *n; + char *filename; + object *globals; + object *locals; +{ + codeobject *co; + object *v; + co = compile(n, filename); + freetree(n); + if (co == NULL) + return NULL; + v = eval_code(co, globals, locals, (object *)NULL); + DECREF(co); + return v; +} + +/* Simplified interface to parsefile */ + +int +parse_file(fp, filename, start, n_ret) + FILE *fp; + char *filename; + int start; + node **n_ret; +{ + return parsefile(fp, filename, &gram, start, + (char *)0, (char *)0, n_ret); +} + +/* Simplified interface to parsestring */ + +int +parse_string(str, start, n_ret) + char *str; + int start; + node **n_ret; +{ + int err = parsestring(str, &gram, start, n_ret); + /* Don't confuse early end of string with early end of input */ + if (err == E_EOF) + err = E_SYNTAX; + return err; +} + +/* Print fatal error message and abort */ + +void +fatal(msg) + char *msg; +{ + fprintf(stderr, "Fatal error: %s\n", msg); + abort(); } +/* Clean up and exit */ + +void goaway(sts) int sts; { + flushline(); + + /* XXX Call doneimport() before donecalls(), since donecalls() + calls wdone(), and doneimport() may close windows */ + doneimport(); + donecalls(); + + err_clear(); + +#ifdef REF_DEBUG + fprintf(stderr, "[%ld refs]\n", ref_total); +#endif + #ifdef THINK_C if (sts == 0) Click_On(0); #endif - closerun(); - donecalls(); + +#ifdef TRACE_REFS + if (askyesno("Print left references?")) { +#ifdef THINK_C + Click_On(1); +#endif + printrefs(stderr); + } +#endif /* TRACE_REFS */ + exit(sts); /*NOTREACHED*/ } -/* Parse input from a file and execute it */ - -static int -runfile(fp, start, ps1, ps2) - FILE *fp; - int start; - char *ps1, *ps2; +static +finaloutput() { - node *n; - int ret; - ret = parsefile(fp, &gram, start, ps1, ps2, &n); - if (ret != E_DONE) - return ret; - return execute(n) == 0 ? E_DONE : E_ERROR; +#ifdef TRACE_REFS + if (!askyesno("Print left references?")) + return; +#ifdef THINK_C + Click_On(1); +#endif /* THINK_C */ + printrefs(stderr); +#endif /* TRACE_REFS */ } /* Ask a yes/no question */ -int +static int askyesno(prompt) char *prompt; { @@ -151,15 +399,14 @@ isatty(fd) #endif -/* WISH LIST +/* XXX WISH LIST - - improved per-module error handling; different use of errno - possible new types: - iterator (for range, keys, ...) - improve interpreter error handling, e.g., true tracebacks - - release parse trees when no longer needed (make them objects?) - - faster parser (for long modules) - save precompiled modules on file? - fork threads, locking - allow syntax extensions */ + +/* "Floccinaucinihilipilification" */ |