blob: 47dc9207b57c5c58dd097cba681c4031cf400ac1 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
2Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
3Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
Guido van Rossum3f5da241990-12-20 15:06:42 +000025/* Built-in functions */
26
27#include "allobjects.h"
28
29#include "node.h"
30#include "graminit.h"
31#include "errcode.h"
32#include "sysmodule.h"
Guido van Rossum86cd6e61991-01-21 15:12:35 +000033#include "bltinmodule.h"
Guido van Rossum3f5da241990-12-20 15:06:42 +000034#include "import.h"
35#include "pythonrun.h"
36#include "compile.h" /* For ceval.h */
37#include "ceval.h"
38#include "modsupport.h"
39
40static object *
41builtin_abs(self, v)
42 object *self;
43 object *v;
44{
Guido van Rossumd4905451991-05-05 20:00:36 +000045 number_methods *nm;
46 if (v == NULL || (nm = v->ob_type->tp_as_number) == NULL) {
47 err_setstr(TypeError, "abs() requires numeric argument");
48 return NULL;
Guido van Rossum3f5da241990-12-20 15:06:42 +000049 }
Guido van Rossumd4905451991-05-05 20:00:36 +000050 return (*nm->nb_absolute)(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +000051}
52
53static object *
54builtin_chr(self, v)
55 object *self;
56 object *v;
57{
58 long x;
59 char s[1];
60 if (v == NULL || !is_intobject(v)) {
61 err_setstr(TypeError, "chr() must have int argument");
62 return NULL;
63 }
64 x = getintvalue(v);
65 if (x < 0 || x >= 256) {
66 err_setstr(RuntimeError, "chr() arg not in range(256)");
67 return NULL;
68 }
69 s[0] = x;
70 return newsizedstringobject(s, 1);
71}
72
73static object *
74builtin_dir(self, v)
75 object *self;
76 object *v;
77{
78 object *d;
79 if (v == NULL) {
80 d = getlocals();
81 }
82 else {
83 if (!is_moduleobject(v)) {
84 err_setstr(TypeError,
85 "dir() argument, must be module or absent");
86 return NULL;
87 }
88 d = getmoduledict(v);
89 }
90 v = getdictkeys(d);
91 if (sortlist(v) != 0) {
92 DECREF(v);
93 v = NULL;
94 }
95 return v;
96}
97
98static object *
99builtin_divmod(self, v)
100 object *self;
101 object *v;
102{
Guido van Rossumd4905451991-05-05 20:00:36 +0000103 object *x;
104 number_methods *nm;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000105 if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 2) {
Guido van Rossumd4905451991-05-05 20:00:36 +0000106 err_setstr(TypeError, "divmod() requires 2 arguments");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000107 return NULL;
108 }
109 x = gettupleitem(v, 0);
Guido van Rossumd4905451991-05-05 20:00:36 +0000110 if ((nm = x->ob_type->tp_as_number) == NULL) {
111 err_setstr(TypeError, "divmod() requires numeric arguments");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000112 return NULL;
113 }
Guido van Rossumd4905451991-05-05 20:00:36 +0000114 return (*nm->nb_divmod)(x, gettupleitem(v, 1));
Guido van Rossum3f5da241990-12-20 15:06:42 +0000115}
116
117static object *
118exec_eval(v, start)
119 object *v;
120 int start;
121{
122 object *str = NULL, *globals = NULL, *locals = NULL;
123 int n;
124 if (v != NULL) {
125 if (is_stringobject(v))
126 str = v;
127 else if (is_tupleobject(v) &&
128 ((n = gettuplesize(v)) == 2 || n == 3)) {
129 str = gettupleitem(v, 0);
130 globals = gettupleitem(v, 1);
131 if (n == 3)
132 locals = gettupleitem(v, 2);
133 }
134 }
135 if (str == NULL || !is_stringobject(str) ||
136 globals != NULL && !is_dictobject(globals) ||
137 locals != NULL && !is_dictobject(locals)) {
138 err_setstr(TypeError,
139 "exec/eval arguments must be string[,dict[,dict]]");
140 return NULL;
141 }
142 return run_string(getstringvalue(str), start, globals, locals);
143}
144
145static object *
146builtin_eval(self, v)
147 object *self;
148 object *v;
149{
150 return exec_eval(v, eval_input);
151}
152
153static object *
154builtin_exec(self, v)
155 object *self;
156 object *v;
157{
158 return exec_eval(v, file_input);
159}
160
161static object *
162builtin_float(self, v)
163 object *self;
164 object *v;
165{
166 if (v == NULL) {
167 /* */
168 }
Guido van Rossum3f5da241990-12-20 15:06:42 +0000169 else if (is_intobject(v)) {
170 long x = getintvalue(v);
171 return newfloatobject((double)x);
172 }
Guido van Rossumd4905451991-05-05 20:00:36 +0000173 else if (is_longobject(v)) {
Guido van Rossumd4905451991-05-05 20:00:36 +0000174 return newfloatobject(dgetlongvalue(v));
175 }
176 else if (is_floatobject(v)) {
177 INCREF(v);
178 return v;
179 }
180 err_setstr(TypeError, "float() argument must be int, long or float");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000181 return NULL;
182}
183
184static object *
185builtin_input(self, v)
186 object *self;
187 object *v;
188{
189 FILE *in = sysgetfile("stdin", stdin);
190 FILE *out = sysgetfile("stdout", stdout);
191 node *n;
192 int err;
193 object *m, *d;
194 flushline();
195 if (v != NULL)
196 printobject(v, out, PRINT_RAW);
197 m = add_module("__main__");
198 d = getmoduledict(m);
199 return run_file(in, "<stdin>", expr_input, d, d);
200}
201
202static object *
203builtin_int(self, v)
204 object *self;
205 object *v;
206{
207 if (v == NULL) {
208 /* */
209 }
210 else if (is_intobject(v)) {
211 INCREF(v);
212 return v;
213 }
Guido van Rossumd4905451991-05-05 20:00:36 +0000214 else if (is_longobject(v)) {
215 long x;
216 x = getlongvalue(v);
Guido van Rossumad405311991-06-03 10:58:01 +0000217 if (err_occurred())
Guido van Rossumd4905451991-05-05 20:00:36 +0000218 return NULL;
219 return newintobject(x);
220 }
Guido van Rossum3f5da241990-12-20 15:06:42 +0000221 else if (is_floatobject(v)) {
222 double x = getfloatvalue(v);
Guido van Rossumad405311991-06-03 10:58:01 +0000223 /* XXX should check for overflow */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000224 return newintobject((long)x);
225 }
Guido van Rossumd4905451991-05-05 20:00:36 +0000226 err_setstr(TypeError, "int() argument must be int, long or float");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000227 return NULL;
228}
229
230static object *
231builtin_len(self, v)
232 object *self;
233 object *v;
234{
235 long len;
236 typeobject *tp;
237 if (v == NULL) {
238 err_setstr(TypeError, "len() without argument");
239 return NULL;
240 }
241 tp = v->ob_type;
242 if (tp->tp_as_sequence != NULL) {
243 len = (*tp->tp_as_sequence->sq_length)(v);
244 }
245 else if (tp->tp_as_mapping != NULL) {
246 len = (*tp->tp_as_mapping->mp_length)(v);
247 }
248 else {
249 err_setstr(TypeError, "len() of unsized object");
250 return NULL;
251 }
252 return newintobject(len);
253}
254
255static object *
Guido van Rossumd4905451991-05-05 20:00:36 +0000256builtin_long(self, v)
257 object *self;
258 object *v;
259{
260 if (v == NULL) {
261 /* */
262 }
263 else if (is_intobject(v)) {
264 return newlongobject(getintvalue(v));
265 }
266 else if (is_longobject(v)) {
267 INCREF(v);
268 return v;
269 }
270 else if (is_floatobject(v)) {
271 double x = getfloatvalue(v);
Guido van Rossumad405311991-06-03 10:58:01 +0000272 return dnewlongobject(x);
Guido van Rossumd4905451991-05-05 20:00:36 +0000273 }
274 err_setstr(TypeError, "long() argument must be int, long or float");
275 return NULL;
276}
277
278static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000279min_max(v, sign)
280 object *v;
281 int sign;
282{
283 int i, n, cmp;
284 object *w, *x;
285 sequence_methods *sq;
286 if (v == NULL) {
287 err_setstr(TypeError, "min() or max() without argument");
288 return NULL;
289 }
290 sq = v->ob_type->tp_as_sequence;
291 if (sq == NULL) {
292 err_setstr(TypeError, "min() or max() of non-sequence");
293 return NULL;
294 }
295 n = (*sq->sq_length)(v);
296 if (n == 0) {
297 err_setstr(RuntimeError, "min() or max() of empty sequence");
298 return NULL;
299 }
300 w = (*sq->sq_item)(v, 0); /* Implies INCREF */
301 for (i = 1; i < n; i++) {
302 x = (*sq->sq_item)(v, i); /* Implies INCREF */
303 cmp = cmpobject(x, w);
304 if (cmp * sign > 0) {
305 DECREF(w);
306 w = x;
307 }
308 else
309 DECREF(x);
310 }
311 return w;
312}
313
314static object *
315builtin_min(self, v)
316 object *self;
317 object *v;
318{
319 return min_max(v, -1);
320}
321
322static object *
323builtin_max(self, v)
324 object *self;
325 object *v;
326{
327 return min_max(v, 1);
328}
329
330static object *
331builtin_open(self, v)
332 object *self;
333 object *v;
334{
335 object *name, *mode;
336 if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 2 ||
337 !is_stringobject(name = gettupleitem(v, 0)) ||
338 !is_stringobject(mode = gettupleitem(v, 1))) {
339 err_setstr(TypeError, "open() requires 2 string arguments");
340 return NULL;
341 }
342 v = newfileobject(getstringvalue(name), getstringvalue(mode));
343 return v;
344}
345
346static object *
347builtin_ord(self, v)
348 object *self;
349 object *v;
350{
351 if (v == NULL || !is_stringobject(v)) {
352 err_setstr(TypeError, "ord() must have string argument");
353 return NULL;
354 }
355 if (getstringsize(v) != 1) {
356 err_setstr(RuntimeError, "ord() arg must have length 1");
357 return NULL;
358 }
359 return newintobject((long)(getstringvalue(v)[0] & 0xff));
360}
361
362static object *
Guido van Rossumd4905451991-05-05 20:00:36 +0000363builtin_pow(self, v)
364 object *self;
365 object *v;
366{
367 object *x;
368 number_methods *nm;
369 if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 2) {
370 err_setstr(TypeError, "pow() requires 2 arguments");
371 return NULL;
372 }
373 x = gettupleitem(v, 0);
374 if ((nm = x->ob_type->tp_as_number) == NULL) {
375 err_setstr(TypeError, "pow() requires numeric arguments");
376 return NULL;
377 }
378 return (*nm->nb_power)(x, gettupleitem(v, 1));
379}
380
381static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000382builtin_range(self, v)
383 object *self;
384 object *v;
385{
386 static char *errmsg = "range() requires 1-3 int arguments";
387 int i, n;
388 long ilow, ihigh, istep;
389 if (v != NULL && is_intobject(v)) {
390 ilow = 0; ihigh = getintvalue(v); istep = 1;
391 }
392 else if (v == NULL || !is_tupleobject(v)) {
393 err_setstr(TypeError, errmsg);
394 return NULL;
395 }
396 else {
397 n = gettuplesize(v);
398 if (n < 1 || n > 3) {
399 err_setstr(TypeError, errmsg);
400 return NULL;
401 }
402 for (i = 0; i < n; i++) {
403 if (!is_intobject(gettupleitem(v, i))) {
404 err_setstr(TypeError, errmsg);
405 return NULL;
406 }
407 }
408 if (n == 3) {
409 istep = getintvalue(gettupleitem(v, 2));
410 --n;
411 }
412 else
413 istep = 1;
414 ihigh = getintvalue(gettupleitem(v, --n));
415 if (n > 0)
416 ilow = getintvalue(gettupleitem(v, 0));
417 else
418 ilow = 0;
419 }
420 if (istep == 0) {
421 err_setstr(RuntimeError, "zero step for range()");
422 return NULL;
423 }
424 /* XXX ought to check overflow of subtraction */
425 if (istep > 0)
426 n = (ihigh - ilow + istep - 1) / istep;
427 else
428 n = (ihigh - ilow + istep + 1) / istep;
429 if (n < 0)
430 n = 0;
431 v = newlistobject(n);
432 if (v == NULL)
433 return NULL;
434 for (i = 0; i < n; i++) {
435 object *w = newintobject(ilow);
436 if (w == NULL) {
437 DECREF(v);
438 return NULL;
439 }
440 setlistitem(v, i, w);
441 ilow += istep;
442 }
443 return v;
444}
445
446static object *
447builtin_raw_input(self, v)
448 object *self;
449 object *v;
450{
Guido van Rossum3f5da241990-12-20 15:06:42 +0000451 FILE *out = sysgetfile("stdout", stdout);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000452 flushline();
453 if (v != NULL)
454 printobject(v, out, PRINT_RAW);
Guido van Rossum26203aa1991-04-04 15:20:41 +0000455 return filegetline(sysget("stdin"), -1);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000456}
457
458static object *
459builtin_reload(self, v)
460 object *self;
461 object *v;
462{
463 return reload_module(v);
464}
465
466static object *
467builtin_type(self, v)
468 object *self;
469 object *v;
470{
471 if (v == NULL) {
472 err_setstr(TypeError, "type() requres an argument");
473 return NULL;
474 }
475 v = (object *)v->ob_type;
476 INCREF(v);
477 return v;
478}
479
480static struct methodlist builtin_methods[] = {
481 {"abs", builtin_abs},
482 {"chr", builtin_chr},
483 {"dir", builtin_dir},
484 {"divmod", builtin_divmod},
485 {"eval", builtin_eval},
486 {"exec", builtin_exec},
487 {"float", builtin_float},
488 {"input", builtin_input},
489 {"int", builtin_int},
490 {"len", builtin_len},
Guido van Rossumd4905451991-05-05 20:00:36 +0000491 {"long", builtin_long},
Guido van Rossum3f5da241990-12-20 15:06:42 +0000492 {"max", builtin_max},
Guido van Rossum865828d1991-02-19 12:21:50 +0000493 {"min", builtin_min},
Guido van Rossum3f5da241990-12-20 15:06:42 +0000494 {"open", builtin_open}, /* XXX move to OS module */
495 {"ord", builtin_ord},
Guido van Rossumd4905451991-05-05 20:00:36 +0000496 {"pow", builtin_pow},
Guido van Rossum3f5da241990-12-20 15:06:42 +0000497 {"range", builtin_range},
498 {"raw_input", builtin_raw_input},
499 {"reload", builtin_reload},
500 {"type", builtin_type},
501 {NULL, NULL},
502};
503
504static object *builtin_dict;
505
506object *
507getbuiltin(name)
508 char *name;
509{
510 return dictlookup(builtin_dict, name);
511}
512
513/* Predefined exceptions */
514
515object *RuntimeError;
516object *EOFError;
517object *TypeError;
518object *MemoryError;
519object *NameError;
520object *SystemError;
521object *KeyboardInterrupt;
522
523static object *
524newstdexception(name, message)
525 char *name, *message;
526{
527 object *v = newstringobject(message);
528 if (v == NULL || dictinsert(builtin_dict, name, v) != 0)
529 fatal("no mem for new standard exception");
530 return v;
531}
532
533static void
534initerrors()
535{
536 RuntimeError = newstdexception("RuntimeError", "run-time error");
537 EOFError = newstdexception("EOFError", "end-of-file read");
538 TypeError = newstdexception("TypeError", "type error");
539 MemoryError = newstdexception("MemoryError", "out of memory");
540 NameError = newstdexception("NameError", "undefined name");
541 SystemError = newstdexception("SystemError", "system error");
542 KeyboardInterrupt =
543 newstdexception("KeyboardInterrupt", "keyboard interrupt");
544}
545
546void
547initbuiltin()
548{
549 object *m;
550 m = initmodule("builtin", builtin_methods);
551 builtin_dict = getmoduledict(m);
552 INCREF(builtin_dict);
553 initerrors();
554 (void) dictinsert(builtin_dict, "None", None);
555}