summaryrefslogtreecommitdiffstats
path: root/Python/pythonmain.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1990-12-20 15:06:42 (GMT)
committerGuido van Rossum <guido@python.org>1990-12-20 15:06:42 (GMT)
commit3f5da24ea304e674a9abbdcffc4d671e32aa70f1 (patch)
treee932e31cb9381f40b7c87c377638216c043b5cfc /Python/pythonmain.c
parent226d79eb4a776dd54c9e4544b17deaf928bcef3a (diff)
downloadcpython-3f5da24ea304e674a9abbdcffc4d671e32aa70f1.zip
cpython-3f5da24ea304e674a9abbdcffc4d671e32aa70f1.tar.gz
cpython-3f5da24ea304e674a9abbdcffc4d671e32aa70f1.tar.bz2
"Compiling" version
Diffstat (limited to 'Python/pythonmain.c')
-rw-r--r--Python/pythonmain.c395
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" */