blob: f095cdd10abb1a6a347014e91b64cd056058a7c8 [file] [log] [blame]
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001/* Python interpreter main program */
2
Guido van Rossum3f5da241990-12-20 15:06:42 +00003#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005#include "grammar.h"
6#include "node.h"
7#include "parsetok.h"
8#include "graminit.h"
9#include "errcode.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010#include "sysmodule.h"
Guido van Rossum3f5da241990-12-20 15:06:42 +000011#include "compile.h"
12#include "ceval.h"
13#include "pythonrun.h"
14#include "import.h"
15
16extern char *getpythonpath();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000017
18extern grammar gram; /* From graminit.c */
19
Guido van Rossum3f5da241990-12-20 15:06:42 +000020#ifdef DEBUG
21int debugging; /* Needed by parser.c */
22#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000023
24main(argc, argv)
25 int argc;
26 char **argv;
27{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000028 char *filename = NULL;
29 FILE *fp = stdin;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000030
Guido van Rossum3f5da241990-12-20 15:06:42 +000031 initargs(&argc, &argv);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000032
33 if (argc > 1 && strcmp(argv[1], "-") != 0)
34 filename = argv[1];
Guido van Rossum3f5da241990-12-20 15:06:42 +000035
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000036 if (filename != NULL) {
37 if ((fp = fopen(filename, "r")) == NULL) {
38 fprintf(stderr, "python: can't open file '%s'\n",
39 filename);
40 exit(2);
41 }
42 }
43
Guido van Rossum3f5da241990-12-20 15:06:42 +000044 initall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000045
Guido van Rossumda0c6bd1990-11-18 17:28:24 +000046 setpythonpath(getpythonpath());
Guido van Rossum3f5da241990-12-20 15:06:42 +000047 setpythonargv(argc-1, argv+1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000048
Guido van Rossum3f5da241990-12-20 15:06:42 +000049 goaway(run(fp, filename == NULL ? "<stdin>" : filename));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000050 /*NOTREACHED*/
51}
52
Guido van Rossum3f5da241990-12-20 15:06:42 +000053/* Initialize all */
54
55void
56initall()
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000057{
Guido van Rossum3f5da241990-12-20 15:06:42 +000058 static int inited;
59
60 if (inited)
61 return;
62
63 initimport();
64
65 initbuiltin(); /* Also initializes builtin exceptions */
66 initsys();
67 inittime();
68 initmath();
69
70 initcalls(); /* Configuration-dependent initializations */
71
72 initintr(); /* For intrcheck() */
73
74 inited = 1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000075}
76
77/* Parse input from a file and execute it */
78
Guido van Rossum3f5da241990-12-20 15:06:42 +000079int
80run(fp, filename)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000081 FILE *fp;
Guido van Rossum3f5da241990-12-20 15:06:42 +000082 char *filename;
83{
84 if (filename == NULL)
85 filename = "???";
86 if (isatty(fileno(fp)))
87 return run_tty_loop(fp, filename);
88 else
89 return run_script(fp, filename);
90}
91
92int
93run_tty_loop(fp, filename)
94 FILE *fp;
95 char *filename;
96{
97 object *v;
98 int ret;
99 v = sysget("ps1");
100 if (v == NULL) {
101 sysset("ps1", v = newstringobject(">>> "));
102 XDECREF(v);
103 }
104 v = sysget("ps2");
105 if (v == NULL) {
106 sysset("ps2", v = newstringobject("... "));
107 XDECREF(v);
108 }
109 for (;;) {
110 ret = run_tty_1(fp, filename);
111#ifdef REF_DEBUG
112 fprintf(stderr, "[%ld refs]\n", ref_total);
113#endif
114 if (ret == E_EOF)
115 return 0;
116 /*
117 if (ret == E_NOMEM)
118 return -1;
119 */
120 }
121}
122
123int
124run_tty_1(fp, filename)
125 FILE *fp;
126 char *filename;
127{
128 object *m, *d, *v, *w;
129 node *n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000130 char *ps1, *ps2;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000131 int err;
132 v = sysget("ps1");
133 w = sysget("ps2");
134 if (v != NULL && is_stringobject(v)) {
135 INCREF(v);
136 ps1 = getstringvalue(v);
137 }
138 else {
139 v = NULL;
140 ps1 = "";
141 }
142 if (w != NULL && is_stringobject(w)) {
143 INCREF(w);
144 ps2 = getstringvalue(w);
145 }
146 else {
147 w = NULL;
148 ps2 = "";
149 }
150 err = parsefile(fp, filename, &gram, single_input, ps1, ps2, &n);
151 XDECREF(v);
152 XDECREF(w);
153 if (err == E_EOF)
154 return E_EOF;
155 if (err != E_DONE) {
156 err_input(err);
157 print_error();
158 return err;
159 }
160 m = add_module("__main__");
161 if (m == NULL)
162 return -1;
163 d = getmoduledict(m);
164 v = run_node(n, filename, d, d);
165 flushline();
166 if (v == NULL) {
167 print_error();
168 return -1;
169 }
170 DECREF(v);
171 return 0;
172}
173
174int
175run_script(fp, filename)
176 FILE *fp;
177 char *filename;
178{
179 object *m, *d, *v;
180 m = add_module("__main__");
181 if (m == NULL)
182 return -1;
183 d = getmoduledict(m);
184 v = run_file(fp, filename, file_input, d, d);
185 flushline();
186 if (v == NULL) {
187 print_error();
188 return -1;
189 }
190 DECREF(v);
191 return 0;
192}
193
194void
195print_error()
196{
197 object *exception, *v;
198 err_get(&exception, &v);
199 fprintf(stderr, "Unhandled exception: ");
200 printobject(exception, stderr, PRINT_RAW);
201 if (v != NULL && v != None) {
202 fprintf(stderr, ": ");
203 printobject(v, stderr, PRINT_RAW);
204 }
205 fprintf(stderr, "\n");
206 XDECREF(exception);
207 XDECREF(v);
208 printtraceback(stderr);
209}
210
211object *
212run_string(str, start, globals, locals)
213 char *str;
214 int start;
215 /*dict*/object *globals, *locals;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000216{
217 node *n;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000218 int err;
219 err = parse_string(str, start, &n);
220 return run_err_node(err, n, "<string>", globals, locals);
221}
222
223object *
224run_file(fp, filename, start, globals, locals)
225 FILE *fp;
226 char *filename;
227 int start;
228 /*dict*/object *globals, *locals;
229{
230 node *n;
231 int err;
232 err = parse_file(fp, filename, start, &n);
233 return run_err_node(err, n, filename, globals, locals);
234}
235
236object *
237run_err_node(err, n, filename, globals, locals)
238 int err;
239 node *n;
240 char *filename;
241 /*dict*/object *globals, *locals;
242{
243 if (err != E_DONE) {
244 err_input(err);
245 return NULL;
246 }
247 return run_node(n, filename, globals, locals);
248}
249
250object *
251run_node(n, filename, globals, locals)
252 node *n;
253 char *filename;
254 /*dict*/object *globals, *locals;
255{
256 if (globals == NULL) {
257 globals = getglobals();
258 if (locals == NULL)
259 locals = getlocals();
260 }
261 else {
262 if (locals == NULL)
263 locals = globals;
264 }
265 return eval_node(n, filename, globals, locals);
266}
267
268object *
269eval_node(n, filename, globals, locals)
270 node *n;
271 char *filename;
272 object *globals;
273 object *locals;
274{
275 codeobject *co;
276 object *v;
277 co = compile(n, filename);
278 freetree(n);
279 if (co == NULL)
280 return NULL;
281 v = eval_code(co, globals, locals, (object *)NULL);
282 DECREF(co);
283 return v;
284}
285
286/* Simplified interface to parsefile */
287
288int
289parse_file(fp, filename, start, n_ret)
290 FILE *fp;
291 char *filename;
292 int start;
293 node **n_ret;
294{
295 return parsefile(fp, filename, &gram, start,
296 (char *)0, (char *)0, n_ret);
297}
298
299/* Simplified interface to parsestring */
300
301int
302parse_string(str, start, n_ret)
303 char *str;
304 int start;
305 node **n_ret;
306{
307 int err = parsestring(str, &gram, start, n_ret);
308 /* Don't confuse early end of string with early end of input */
309 if (err == E_EOF)
310 err = E_SYNTAX;
311 return err;
312}
313
314/* Print fatal error message and abort */
315
316void
317fatal(msg)
318 char *msg;
319{
320 fprintf(stderr, "Fatal error: %s\n", msg);
321 abort();
322}
323
324/* Clean up and exit */
325
326void
327goaway(sts)
328 int sts;
329{
330 flushline();
331
332 /* XXX Call doneimport() before donecalls(), since donecalls()
333 calls wdone(), and doneimport() may close windows */
334 doneimport();
335 donecalls();
336
337 err_clear();
338
339#ifdef REF_DEBUG
340 fprintf(stderr, "[%ld refs]\n", ref_total);
341#endif
342
343#ifdef THINK_C
344 if (sts == 0)
345 Click_On(0);
346#endif
347
348#ifdef TRACE_REFS
349 if (askyesno("Print left references?")) {
350#ifdef THINK_C
351 Click_On(1);
352#endif
353 printrefs(stderr);
354 }
355#endif /* TRACE_REFS */
356
357 exit(sts);
358 /*NOTREACHED*/
359}
360
361static
362finaloutput()
363{
364#ifdef TRACE_REFS
365 if (!askyesno("Print left references?"))
366 return;
367#ifdef THINK_C
368 Click_On(1);
369#endif /* THINK_C */
370 printrefs(stderr);
371#endif /* TRACE_REFS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000372}
373
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000374/* Ask a yes/no question */
375
Guido van Rossum3f5da241990-12-20 15:06:42 +0000376static int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000377askyesno(prompt)
378 char *prompt;
379{
380 char buf[256];
381
382 printf("%s [ny] ", prompt);
383 if (fgets(buf, sizeof buf, stdin) == NULL)
384 return 0;
385 return buf[0] == 'y' || buf[0] == 'Y';
386}
387
Guido van Rossumda0c6bd1990-11-18 17:28:24 +0000388#ifdef THINK_C
389
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000390/* Check for file descriptor connected to interactive device.
391 Pretend that stdin is always interactive, other files never. */
392
393int
394isatty(fd)
395 int fd;
396{
397 return fd == fileno(stdin);
398}
399
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000400#endif
401
Guido van Rossum3f5da241990-12-20 15:06:42 +0000402/* XXX WISH LIST
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000403
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000404 - possible new types:
405 - iterator (for range, keys, ...)
406 - improve interpreter error handling, e.g., true tracebacks
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000407 - save precompiled modules on file?
408 - fork threads, locking
409 - allow syntax extensions
410*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000411
412/* "Floccinaucinihilipilification" */