blob: 8fac03c5988052987c4cefe13217d784206edf2d [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();
Guido van Rossumdc8a1081991-10-20 20:11:03 +000081 INCREF(d);
Guido van Rossum3f5da241990-12-20 15:06:42 +000082 }
83 else {
Guido van Rossumdc8a1081991-10-20 20:11:03 +000084 d = getattr(v, "__dict__");
85 if (d == NULL) {
Guido van Rossum3f5da241990-12-20 15:06:42 +000086 err_setstr(TypeError,
Guido van Rossumdc8a1081991-10-20 20:11:03 +000087 "dir() argument has no variable attributes");
Guido van Rossum3f5da241990-12-20 15:06:42 +000088 return NULL;
89 }
Guido van Rossum3f5da241990-12-20 15:06:42 +000090 }
Guido van Rossumdc8a1081991-10-20 20:11:03 +000091 if (!is_dictobject(d)) { /* Assume it is None */
92 v = newlistobject(0);
Guido van Rossum3f5da241990-12-20 15:06:42 +000093 }
Guido van Rossumdc8a1081991-10-20 20:11:03 +000094 else {
95 v = getdictkeys(d);
96 if (sortlist(v) != 0) {
97 DECREF(v);
98 v = NULL;
99 }
100 }
101 DECREF(d);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000102 return v;
103}
104
105static object *
Guido van Rossumc6bb8f71991-07-01 18:42:41 +0000106builtin_divmod(self, args)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000107 object *self;
Guido van Rossumc6bb8f71991-07-01 18:42:41 +0000108 object *args;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000109{
Guido van Rossumc6bb8f71991-07-01 18:42:41 +0000110 object *v, *w, *x;
111 if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2) {
Guido van Rossumd4905451991-05-05 20:00:36 +0000112 err_setstr(TypeError, "divmod() requires 2 arguments");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000113 return NULL;
114 }
Guido van Rossumc6bb8f71991-07-01 18:42:41 +0000115 v = gettupleitem(args, 0);
116 w = gettupleitem(args, 1);
117 if (v->ob_type->tp_as_number == NULL ||
118 w->ob_type->tp_as_number == NULL) {
Guido van Rossumd4905451991-05-05 20:00:36 +0000119 err_setstr(TypeError, "divmod() requires numeric arguments");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000120 return NULL;
121 }
Guido van Rossumc6bb8f71991-07-01 18:42:41 +0000122 if (coerce(&v, &w) != 0)
123 return NULL;
124 x = (*v->ob_type->tp_as_number->nb_divmod)(v, w);
125 DECREF(v);
126 DECREF(w);
127 return x;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000128}
129
130static object *
131exec_eval(v, start)
132 object *v;
133 int start;
134{
135 object *str = NULL, *globals = NULL, *locals = NULL;
136 int n;
137 if (v != NULL) {
138 if (is_stringobject(v))
139 str = v;
140 else if (is_tupleobject(v) &&
141 ((n = gettuplesize(v)) == 2 || n == 3)) {
142 str = gettupleitem(v, 0);
143 globals = gettupleitem(v, 1);
144 if (n == 3)
145 locals = gettupleitem(v, 2);
146 }
147 }
148 if (str == NULL || !is_stringobject(str) ||
149 globals != NULL && !is_dictobject(globals) ||
150 locals != NULL && !is_dictobject(locals)) {
151 err_setstr(TypeError,
152 "exec/eval arguments must be string[,dict[,dict]]");
153 return NULL;
154 }
155 return run_string(getstringvalue(str), start, globals, locals);
156}
157
158static object *
159builtin_eval(self, v)
160 object *self;
161 object *v;
162{
163 return exec_eval(v, eval_input);
164}
165
166static object *
167builtin_exec(self, v)
168 object *self;
169 object *v;
170{
171 return exec_eval(v, file_input);
172}
173
174static object *
175builtin_float(self, v)
176 object *self;
177 object *v;
178{
179 if (v == NULL) {
180 /* */
181 }
Guido van Rossum3f5da241990-12-20 15:06:42 +0000182 else if (is_intobject(v)) {
183 long x = getintvalue(v);
184 return newfloatobject((double)x);
185 }
Guido van Rossumd4905451991-05-05 20:00:36 +0000186 else if (is_longobject(v)) {
Guido van Rossumd4905451991-05-05 20:00:36 +0000187 return newfloatobject(dgetlongvalue(v));
188 }
189 else if (is_floatobject(v)) {
190 INCREF(v);
191 return v;
192 }
193 err_setstr(TypeError, "float() argument must be int, long or float");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000194 return NULL;
195}
196
197static object *
198builtin_input(self, v)
199 object *self;
200 object *v;
201{
202 FILE *in = sysgetfile("stdin", stdin);
203 FILE *out = sysgetfile("stdout", stdout);
204 node *n;
205 int err;
206 object *m, *d;
207 flushline();
Guido van Rossum90933611991-06-07 16:10:43 +0000208 if (v != NULL) {
209 if (printobject(v, out, PRINT_RAW) != 0)
210 return NULL;
211 }
Guido van Rossum3f5da241990-12-20 15:06:42 +0000212 m = add_module("__main__");
213 d = getmoduledict(m);
214 return run_file(in, "<stdin>", expr_input, d, d);
215}
216
217static object *
218builtin_int(self, v)
219 object *self;
220 object *v;
221{
222 if (v == NULL) {
223 /* */
224 }
225 else if (is_intobject(v)) {
226 INCREF(v);
227 return v;
228 }
Guido van Rossumd4905451991-05-05 20:00:36 +0000229 else if (is_longobject(v)) {
230 long x;
231 x = getlongvalue(v);
Guido van Rossumad405311991-06-03 10:58:01 +0000232 if (err_occurred())
Guido van Rossumd4905451991-05-05 20:00:36 +0000233 return NULL;
234 return newintobject(x);
235 }
Guido van Rossum3f5da241990-12-20 15:06:42 +0000236 else if (is_floatobject(v)) {
237 double x = getfloatvalue(v);
Guido van Rossumad405311991-06-03 10:58:01 +0000238 /* XXX should check for overflow */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000239 return newintobject((long)x);
240 }
Guido van Rossumd4905451991-05-05 20:00:36 +0000241 err_setstr(TypeError, "int() argument must be int, long or float");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000242 return NULL;
243}
244
245static object *
246builtin_len(self, v)
247 object *self;
248 object *v;
249{
250 long len;
251 typeobject *tp;
252 if (v == NULL) {
253 err_setstr(TypeError, "len() without argument");
254 return NULL;
255 }
256 tp = v->ob_type;
257 if (tp->tp_as_sequence != NULL) {
258 len = (*tp->tp_as_sequence->sq_length)(v);
259 }
260 else if (tp->tp_as_mapping != NULL) {
261 len = (*tp->tp_as_mapping->mp_length)(v);
262 }
263 else {
264 err_setstr(TypeError, "len() of unsized object");
265 return NULL;
266 }
267 return newintobject(len);
268}
269
270static object *
Guido van Rossumd4905451991-05-05 20:00:36 +0000271builtin_long(self, v)
272 object *self;
273 object *v;
274{
275 if (v == NULL) {
276 /* */
277 }
278 else if (is_intobject(v)) {
279 return newlongobject(getintvalue(v));
280 }
281 else if (is_longobject(v)) {
282 INCREF(v);
283 return v;
284 }
285 else if (is_floatobject(v)) {
286 double x = getfloatvalue(v);
Guido van Rossumad405311991-06-03 10:58:01 +0000287 return dnewlongobject(x);
Guido van Rossumd4905451991-05-05 20:00:36 +0000288 }
289 err_setstr(TypeError, "long() argument must be int, long or float");
290 return NULL;
291}
292
293static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000294min_max(v, sign)
295 object *v;
296 int sign;
297{
298 int i, n, cmp;
299 object *w, *x;
300 sequence_methods *sq;
301 if (v == NULL) {
302 err_setstr(TypeError, "min() or max() without argument");
303 return NULL;
304 }
305 sq = v->ob_type->tp_as_sequence;
306 if (sq == NULL) {
307 err_setstr(TypeError, "min() or max() of non-sequence");
308 return NULL;
309 }
310 n = (*sq->sq_length)(v);
311 if (n == 0) {
312 err_setstr(RuntimeError, "min() or max() of empty sequence");
313 return NULL;
314 }
315 w = (*sq->sq_item)(v, 0); /* Implies INCREF */
316 for (i = 1; i < n; i++) {
317 x = (*sq->sq_item)(v, i); /* Implies INCREF */
318 cmp = cmpobject(x, w);
319 if (cmp * sign > 0) {
320 DECREF(w);
321 w = x;
322 }
323 else
324 DECREF(x);
325 }
326 return w;
327}
328
329static object *
330builtin_min(self, v)
331 object *self;
332 object *v;
333{
334 return min_max(v, -1);
335}
336
337static object *
338builtin_max(self, v)
339 object *self;
340 object *v;
341{
342 return min_max(v, 1);
343}
344
345static object *
346builtin_open(self, v)
347 object *self;
348 object *v;
349{
350 object *name, *mode;
351 if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 2 ||
352 !is_stringobject(name = gettupleitem(v, 0)) ||
353 !is_stringobject(mode = gettupleitem(v, 1))) {
354 err_setstr(TypeError, "open() requires 2 string arguments");
355 return NULL;
356 }
357 v = newfileobject(getstringvalue(name), getstringvalue(mode));
358 return v;
359}
360
361static object *
362builtin_ord(self, v)
363 object *self;
364 object *v;
365{
366 if (v == NULL || !is_stringobject(v)) {
367 err_setstr(TypeError, "ord() must have string argument");
368 return NULL;
369 }
370 if (getstringsize(v) != 1) {
371 err_setstr(RuntimeError, "ord() arg must have length 1");
372 return NULL;
373 }
374 return newintobject((long)(getstringvalue(v)[0] & 0xff));
375}
376
377static object *
Guido van Rossumc6bb8f71991-07-01 18:42:41 +0000378builtin_pow(self, args)
Guido van Rossumd4905451991-05-05 20:00:36 +0000379 object *self;
Guido van Rossumc6bb8f71991-07-01 18:42:41 +0000380 object *args;
Guido van Rossumd4905451991-05-05 20:00:36 +0000381{
Guido van Rossumc6bb8f71991-07-01 18:42:41 +0000382 object *v, *w, *x;
383 if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2) {
Guido van Rossumd4905451991-05-05 20:00:36 +0000384 err_setstr(TypeError, "pow() requires 2 arguments");
385 return NULL;
386 }
Guido van Rossumc6bb8f71991-07-01 18:42:41 +0000387 v = gettupleitem(args, 0);
388 w = gettupleitem(args, 1);
389 if (v->ob_type->tp_as_number == NULL ||
390 w->ob_type->tp_as_number == NULL) {
Guido van Rossumd4905451991-05-05 20:00:36 +0000391 err_setstr(TypeError, "pow() requires numeric arguments");
392 return NULL;
393 }
Guido van Rossumc6bb8f71991-07-01 18:42:41 +0000394 if (coerce(&v, &w) != 0)
395 return NULL;
396 x = (*v->ob_type->tp_as_number->nb_power)(v, w);
397 DECREF(v);
398 DECREF(w);
399 return x;
Guido van Rossumd4905451991-05-05 20:00:36 +0000400}
401
402static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000403builtin_range(self, v)
404 object *self;
405 object *v;
406{
407 static char *errmsg = "range() requires 1-3 int arguments";
408 int i, n;
409 long ilow, ihigh, istep;
410 if (v != NULL && is_intobject(v)) {
411 ilow = 0; ihigh = getintvalue(v); istep = 1;
412 }
413 else if (v == NULL || !is_tupleobject(v)) {
414 err_setstr(TypeError, errmsg);
415 return NULL;
416 }
417 else {
418 n = gettuplesize(v);
419 if (n < 1 || n > 3) {
420 err_setstr(TypeError, errmsg);
421 return NULL;
422 }
423 for (i = 0; i < n; i++) {
424 if (!is_intobject(gettupleitem(v, i))) {
425 err_setstr(TypeError, errmsg);
426 return NULL;
427 }
428 }
429 if (n == 3) {
430 istep = getintvalue(gettupleitem(v, 2));
431 --n;
432 }
433 else
434 istep = 1;
435 ihigh = getintvalue(gettupleitem(v, --n));
436 if (n > 0)
437 ilow = getintvalue(gettupleitem(v, 0));
438 else
439 ilow = 0;
440 }
441 if (istep == 0) {
442 err_setstr(RuntimeError, "zero step for range()");
443 return NULL;
444 }
445 /* XXX ought to check overflow of subtraction */
446 if (istep > 0)
447 n = (ihigh - ilow + istep - 1) / istep;
448 else
449 n = (ihigh - ilow + istep + 1) / istep;
450 if (n < 0)
451 n = 0;
452 v = newlistobject(n);
453 if (v == NULL)
454 return NULL;
455 for (i = 0; i < n; i++) {
456 object *w = newintobject(ilow);
457 if (w == NULL) {
458 DECREF(v);
459 return NULL;
460 }
461 setlistitem(v, i, w);
462 ilow += istep;
463 }
464 return v;
465}
466
467static object *
468builtin_raw_input(self, v)
469 object *self;
470 object *v;
471{
Guido van Rossum3f5da241990-12-20 15:06:42 +0000472 FILE *out = sysgetfile("stdout", stdout);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000473 flushline();
Guido van Rossum90933611991-06-07 16:10:43 +0000474 if (v != NULL) {
475 if (printobject(v, out, PRINT_RAW) != 0)
476 return NULL;
477 }
Guido van Rossum26203aa1991-04-04 15:20:41 +0000478 return filegetline(sysget("stdin"), -1);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000479}
480
481static object *
482builtin_reload(self, v)
483 object *self;
484 object *v;
485{
486 return reload_module(v);
487}
488
489static object *
490builtin_type(self, v)
491 object *self;
492 object *v;
493{
494 if (v == NULL) {
495 err_setstr(TypeError, "type() requres an argument");
496 return NULL;
497 }
498 v = (object *)v->ob_type;
499 INCREF(v);
500 return v;
501}
502
503static struct methodlist builtin_methods[] = {
504 {"abs", builtin_abs},
505 {"chr", builtin_chr},
506 {"dir", builtin_dir},
507 {"divmod", builtin_divmod},
508 {"eval", builtin_eval},
509 {"exec", builtin_exec},
510 {"float", builtin_float},
511 {"input", builtin_input},
512 {"int", builtin_int},
513 {"len", builtin_len},
Guido van Rossumd4905451991-05-05 20:00:36 +0000514 {"long", builtin_long},
Guido van Rossum3f5da241990-12-20 15:06:42 +0000515 {"max", builtin_max},
Guido van Rossum865828d1991-02-19 12:21:50 +0000516 {"min", builtin_min},
Guido van Rossum3f5da241990-12-20 15:06:42 +0000517 {"open", builtin_open}, /* XXX move to OS module */
518 {"ord", builtin_ord},
Guido van Rossumd4905451991-05-05 20:00:36 +0000519 {"pow", builtin_pow},
Guido van Rossum3f5da241990-12-20 15:06:42 +0000520 {"range", builtin_range},
521 {"raw_input", builtin_raw_input},
522 {"reload", builtin_reload},
523 {"type", builtin_type},
524 {NULL, NULL},
525};
526
527static object *builtin_dict;
528
529object *
530getbuiltin(name)
Guido van Rossuma57fb011991-08-16 08:54:58 +0000531 object *name;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000532{
Guido van Rossuma57fb011991-08-16 08:54:58 +0000533 return dict2lookup(builtin_dict, name);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000534}
535
536/* Predefined exceptions */
537
538object *RuntimeError;
539object *EOFError;
540object *TypeError;
541object *MemoryError;
542object *NameError;
543object *SystemError;
544object *KeyboardInterrupt;
545
546static object *
547newstdexception(name, message)
548 char *name, *message;
549{
550 object *v = newstringobject(message);
551 if (v == NULL || dictinsert(builtin_dict, name, v) != 0)
552 fatal("no mem for new standard exception");
553 return v;
554}
555
556static void
557initerrors()
558{
559 RuntimeError = newstdexception("RuntimeError", "run-time error");
560 EOFError = newstdexception("EOFError", "end-of-file read");
561 TypeError = newstdexception("TypeError", "type error");
562 MemoryError = newstdexception("MemoryError", "out of memory");
563 NameError = newstdexception("NameError", "undefined name");
564 SystemError = newstdexception("SystemError", "system error");
565 KeyboardInterrupt =
566 newstdexception("KeyboardInterrupt", "keyboard interrupt");
567}
568
569void
570initbuiltin()
571{
572 object *m;
573 m = initmodule("builtin", builtin_methods);
574 builtin_dict = getmoduledict(m);
575 INCREF(builtin_dict);
576 initerrors();
577 (void) dictinsert(builtin_dict, "None", None);
578}
Guido van Rossumc6bb8f71991-07-01 18:42:41 +0000579
580/* Coerce two numeric types to the "larger" one.
581 Increment the reference count on each argument.
582 Return -1 and raise an exception if no coercion is possible
583 (and then no reference count is incremented).
584 XXX This should be distributed over the various numeric types,
585 XXX but for now I don't see how to implement that.
586 XXX So, for now, if you add a new numeric type,
587 XXX you must add to this function as well. */
588
589int
590coerce(pv, pw)
591 object **pv, **pw;
592{
593 register object *v = *pv;
594 register object *w = *pw;
595 if (v->ob_type == w->ob_type) {
596 INCREF(v);
597 INCREF(w);
598 return 0;
599 }
600 if (v->ob_type->tp_as_number == NULL ||
601 w->ob_type->tp_as_number == NULL) {
602 err_setstr(TypeError, "mixing number and non-number");
603 return -1;
604 }
605 if (is_floatobject(v) || is_floatobject(w)) {
606 v = builtin_float((object *)0, v);
607 w = builtin_float((object *)0, w);
608 }
609 else if (is_longobject(v) || is_longobject(w)) {
610 v = builtin_long((object *)0, v);
611 w = builtin_long((object *)0, w);
612 }
613 else {
614 err_setstr(TypeError, "can't coerce numeric types?!?!?");
615 return -1;
616 }
617 if (v == NULL || w == NULL) {
618 XDECREF(v);
619 XDECREF(w);
620 return -1;
621 }
622 *pv = v;
623 *pw = w;
624 return 0;
625}