diff Python/pythonmain.c @ 86:a6934380c6e7 legacy-trunk

"Compiling" version
author Guido van Rossum <guido@python.org>
date Thu, 20 Dec 1990 15:06:42 +0000
parents de34f4a4d353
children dac8625c8d9b
line wrap: on
line diff
--- a/Python/pythonmain.c	Sun Nov 18 17:44:34 1990 +0000
+++ b/Python/pythonmain.c	Thu Dec 20 15:06:42 1990 +0000
@@ -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 @@
 {
 	char *filename = NULL;
 	FILE *fp = stdin;
-	int ret;
-
+	
 	initargs(&argc, &argv);
 	
-	initintr(); /* For intrcheck() */
-	
 	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 @@
 		}
 	}
 	
-	/* 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);
 	
-	initsys(argc-1, argv+1);
+	goaway(run(fp, filename == NULL ? "<stdin>" : filename));
+	/*NOTREACHED*/
+}
+
+/* Initialize all */
+
+void
+initall()
+{
+	static int inited;
+	
+	if (inited)
+		return;
+	
+	initimport();
+	
+	initbuiltin(); /* Also initializes builtin exceptions */
+	initsys();
 	inittime();
 	initmath();
 	
-	setpythonpath(getpythonpath());
+	initcalls(); /* Configuration-dependent initializations */
+	
+	initintr(); /* For intrcheck() */
 	
-	initrun();
-	initcalls();
-	
-	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 {
+		v = NULL;
+		ps1 = "";
+	}
+	if (w != NULL && is_stringobject(w)) {
+		INCREF(w);
+		ps2 = getstringvalue(w);
 	}
 	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;
-		}
+		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;
 	}
-	goaway(ret == E_DONE || ret == E_EOF ? 0 : 1);
-	/*NOTREACHED*/
+	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 @@
 
 #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" */