blob: 08f34bc5e655561150182e43e3b31f8bdaec1c2c [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{
45 /* XXX This should be a method in the as_number struct in the type */
46 if (v == NULL) {
47 /* */
48 }
49 else if (is_intobject(v)) {
50 long x = getintvalue(v);
51 if (x < 0)
52 x = -x;
53 return newintobject(x);
54 }
55 else if (is_floatobject(v)) {
56 double x = getfloatvalue(v);
57 if (x < 0)
58 x = -x;
59 return newfloatobject(x);
60 }
61 err_setstr(TypeError, "abs() argument must be float or int");
62 return NULL;
63}
64
65static object *
66builtin_chr(self, v)
67 object *self;
68 object *v;
69{
70 long x;
71 char s[1];
72 if (v == NULL || !is_intobject(v)) {
73 err_setstr(TypeError, "chr() must have int argument");
74 return NULL;
75 }
76 x = getintvalue(v);
77 if (x < 0 || x >= 256) {
78 err_setstr(RuntimeError, "chr() arg not in range(256)");
79 return NULL;
80 }
81 s[0] = x;
82 return newsizedstringobject(s, 1);
83}
84
85static object *
86builtin_dir(self, v)
87 object *self;
88 object *v;
89{
90 object *d;
91 if (v == NULL) {
92 d = getlocals();
93 }
94 else {
95 if (!is_moduleobject(v)) {
96 err_setstr(TypeError,
97 "dir() argument, must be module or absent");
98 return NULL;
99 }
100 d = getmoduledict(v);
101 }
102 v = getdictkeys(d);
103 if (sortlist(v) != 0) {
104 DECREF(v);
105 v = NULL;
106 }
107 return v;
108}
109
110static object *
111builtin_divmod(self, v)
112 object *self;
113 object *v;
114{
115 object *x, *y;
116 long xi, yi, xdivy, xmody;
117 if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 2) {
118 err_setstr(TypeError, "divmod() requires 2 int arguments");
119 return NULL;
120 }
121 x = gettupleitem(v, 0);
122 y = gettupleitem(v, 1);
123 if (!is_intobject(x) || !is_intobject(y)) {
124 err_setstr(TypeError, "divmod() requires 2 int arguments");
125 return NULL;
126 }
127 xi = getintvalue(x);
128 yi = getintvalue(y);
129 if (yi == 0) {
130 err_setstr(TypeError, "divmod() division by zero");
131 return NULL;
132 }
133 if (yi < 0) {
134 xdivy = -xi / -yi;
135 }
136 else {
137 xdivy = xi / yi;
138 }
139 xmody = xi - xdivy*yi;
140 if (xmody < 0 && yi > 0 || xmody > 0 && yi < 0) {
141 xmody += yi;
142 xdivy -= 1;
143 }
144 v = newtupleobject(2);
145 x = newintobject(xdivy);
146 y = newintobject(xmody);
147 if (v == NULL || x == NULL || y == NULL ||
148 settupleitem(v, 0, x) != 0 ||
149 settupleitem(v, 1, y) != 0) {
150 XDECREF(v);
151 XDECREF(x);
152 XDECREF(y);
153 return NULL;
154 }
155 return v;
156}
157
158static object *
159exec_eval(v, start)
160 object *v;
161 int start;
162{
163 object *str = NULL, *globals = NULL, *locals = NULL;
164 int n;
165 if (v != NULL) {
166 if (is_stringobject(v))
167 str = v;
168 else if (is_tupleobject(v) &&
169 ((n = gettuplesize(v)) == 2 || n == 3)) {
170 str = gettupleitem(v, 0);
171 globals = gettupleitem(v, 1);
172 if (n == 3)
173 locals = gettupleitem(v, 2);
174 }
175 }
176 if (str == NULL || !is_stringobject(str) ||
177 globals != NULL && !is_dictobject(globals) ||
178 locals != NULL && !is_dictobject(locals)) {
179 err_setstr(TypeError,
180 "exec/eval arguments must be string[,dict[,dict]]");
181 return NULL;
182 }
183 return run_string(getstringvalue(str), start, globals, locals);
184}
185
186static object *
187builtin_eval(self, v)
188 object *self;
189 object *v;
190{
191 return exec_eval(v, eval_input);
192}
193
194static object *
195builtin_exec(self, v)
196 object *self;
197 object *v;
198{
199 return exec_eval(v, file_input);
200}
201
202static object *
203builtin_float(self, v)
204 object *self;
205 object *v;
206{
207 if (v == NULL) {
208 /* */
209 }
210 else if (is_floatobject(v)) {
211 INCREF(v);
212 return v;
213 }
214 else if (is_intobject(v)) {
215 long x = getintvalue(v);
216 return newfloatobject((double)x);
217 }
218 err_setstr(TypeError, "float() argument must be float or int");
219 return NULL;
220}
221
222static object *
223builtin_input(self, v)
224 object *self;
225 object *v;
226{
227 FILE *in = sysgetfile("stdin", stdin);
228 FILE *out = sysgetfile("stdout", stdout);
229 node *n;
230 int err;
231 object *m, *d;
232 flushline();
233 if (v != NULL)
234 printobject(v, out, PRINT_RAW);
235 m = add_module("__main__");
236 d = getmoduledict(m);
237 return run_file(in, "<stdin>", expr_input, d, d);
238}
239
240static object *
241builtin_int(self, v)
242 object *self;
243 object *v;
244{
245 if (v == NULL) {
246 /* */
247 }
248 else if (is_intobject(v)) {
249 INCREF(v);
250 return v;
251 }
252 else if (is_floatobject(v)) {
253 double x = getfloatvalue(v);
254 return newintobject((long)x);
255 }
256 err_setstr(TypeError, "int() argument must be float or int");
257 return NULL;
258}
259
260static object *
261builtin_len(self, v)
262 object *self;
263 object *v;
264{
265 long len;
266 typeobject *tp;
267 if (v == NULL) {
268 err_setstr(TypeError, "len() without argument");
269 return NULL;
270 }
271 tp = v->ob_type;
272 if (tp->tp_as_sequence != NULL) {
273 len = (*tp->tp_as_sequence->sq_length)(v);
274 }
275 else if (tp->tp_as_mapping != NULL) {
276 len = (*tp->tp_as_mapping->mp_length)(v);
277 }
278 else {
279 err_setstr(TypeError, "len() of unsized object");
280 return NULL;
281 }
282 return newintobject(len);
283}
284
285static object *
286min_max(v, sign)
287 object *v;
288 int sign;
289{
290 int i, n, cmp;
291 object *w, *x;
292 sequence_methods *sq;
293 if (v == NULL) {
294 err_setstr(TypeError, "min() or max() without argument");
295 return NULL;
296 }
297 sq = v->ob_type->tp_as_sequence;
298 if (sq == NULL) {
299 err_setstr(TypeError, "min() or max() of non-sequence");
300 return NULL;
301 }
302 n = (*sq->sq_length)(v);
303 if (n == 0) {
304 err_setstr(RuntimeError, "min() or max() of empty sequence");
305 return NULL;
306 }
307 w = (*sq->sq_item)(v, 0); /* Implies INCREF */
308 for (i = 1; i < n; i++) {
309 x = (*sq->sq_item)(v, i); /* Implies INCREF */
310 cmp = cmpobject(x, w);
311 if (cmp * sign > 0) {
312 DECREF(w);
313 w = x;
314 }
315 else
316 DECREF(x);
317 }
318 return w;
319}
320
321static object *
322builtin_min(self, v)
323 object *self;
324 object *v;
325{
326 return min_max(v, -1);
327}
328
329static object *
330builtin_max(self, v)
331 object *self;
332 object *v;
333{
334 return min_max(v, 1);
335}
336
337static object *
338builtin_open(self, v)
339 object *self;
340 object *v;
341{
342 object *name, *mode;
343 if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 2 ||
344 !is_stringobject(name = gettupleitem(v, 0)) ||
345 !is_stringobject(mode = gettupleitem(v, 1))) {
346 err_setstr(TypeError, "open() requires 2 string arguments");
347 return NULL;
348 }
349 v = newfileobject(getstringvalue(name), getstringvalue(mode));
350 return v;
351}
352
353static object *
354builtin_ord(self, v)
355 object *self;
356 object *v;
357{
358 if (v == NULL || !is_stringobject(v)) {
359 err_setstr(TypeError, "ord() must have string argument");
360 return NULL;
361 }
362 if (getstringsize(v) != 1) {
363 err_setstr(RuntimeError, "ord() arg must have length 1");
364 return NULL;
365 }
366 return newintobject((long)(getstringvalue(v)[0] & 0xff));
367}
368
369static object *
370builtin_range(self, v)
371 object *self;
372 object *v;
373{
374 static char *errmsg = "range() requires 1-3 int arguments";
375 int i, n;
376 long ilow, ihigh, istep;
377 if (v != NULL && is_intobject(v)) {
378 ilow = 0; ihigh = getintvalue(v); istep = 1;
379 }
380 else if (v == NULL || !is_tupleobject(v)) {
381 err_setstr(TypeError, errmsg);
382 return NULL;
383 }
384 else {
385 n = gettuplesize(v);
386 if (n < 1 || n > 3) {
387 err_setstr(TypeError, errmsg);
388 return NULL;
389 }
390 for (i = 0; i < n; i++) {
391 if (!is_intobject(gettupleitem(v, i))) {
392 err_setstr(TypeError, errmsg);
393 return NULL;
394 }
395 }
396 if (n == 3) {
397 istep = getintvalue(gettupleitem(v, 2));
398 --n;
399 }
400 else
401 istep = 1;
402 ihigh = getintvalue(gettupleitem(v, --n));
403 if (n > 0)
404 ilow = getintvalue(gettupleitem(v, 0));
405 else
406 ilow = 0;
407 }
408 if (istep == 0) {
409 err_setstr(RuntimeError, "zero step for range()");
410 return NULL;
411 }
412 /* XXX ought to check overflow of subtraction */
413 if (istep > 0)
414 n = (ihigh - ilow + istep - 1) / istep;
415 else
416 n = (ihigh - ilow + istep + 1) / istep;
417 if (n < 0)
418 n = 0;
419 v = newlistobject(n);
420 if (v == NULL)
421 return NULL;
422 for (i = 0; i < n; i++) {
423 object *w = newintobject(ilow);
424 if (w == NULL) {
425 DECREF(v);
426 return NULL;
427 }
428 setlistitem(v, i, w);
429 ilow += istep;
430 }
431 return v;
432}
433
434static object *
435builtin_raw_input(self, v)
436 object *self;
437 object *v;
438{
Guido van Rossum3f5da241990-12-20 15:06:42 +0000439 FILE *out = sysgetfile("stdout", stdout);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000440 flushline();
441 if (v != NULL)
442 printobject(v, out, PRINT_RAW);
Guido van Rossum26203aa1991-04-04 15:20:41 +0000443 return filegetline(sysget("stdin"), -1);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000444}
445
446static object *
447builtin_reload(self, v)
448 object *self;
449 object *v;
450{
451 return reload_module(v);
452}
453
454static object *
455builtin_type(self, v)
456 object *self;
457 object *v;
458{
459 if (v == NULL) {
460 err_setstr(TypeError, "type() requres an argument");
461 return NULL;
462 }
463 v = (object *)v->ob_type;
464 INCREF(v);
465 return v;
466}
467
468static struct methodlist builtin_methods[] = {
469 {"abs", builtin_abs},
470 {"chr", builtin_chr},
471 {"dir", builtin_dir},
472 {"divmod", builtin_divmod},
473 {"eval", builtin_eval},
474 {"exec", builtin_exec},
475 {"float", builtin_float},
476 {"input", builtin_input},
477 {"int", builtin_int},
478 {"len", builtin_len},
Guido van Rossum3f5da241990-12-20 15:06:42 +0000479 {"max", builtin_max},
Guido van Rossum865828d1991-02-19 12:21:50 +0000480 {"min", builtin_min},
Guido van Rossum3f5da241990-12-20 15:06:42 +0000481 {"open", builtin_open}, /* XXX move to OS module */
482 {"ord", builtin_ord},
483 {"range", builtin_range},
484 {"raw_input", builtin_raw_input},
485 {"reload", builtin_reload},
486 {"type", builtin_type},
487 {NULL, NULL},
488};
489
490static object *builtin_dict;
491
492object *
493getbuiltin(name)
494 char *name;
495{
496 return dictlookup(builtin_dict, name);
497}
498
499/* Predefined exceptions */
500
501object *RuntimeError;
502object *EOFError;
503object *TypeError;
504object *MemoryError;
505object *NameError;
506object *SystemError;
507object *KeyboardInterrupt;
508
509static object *
510newstdexception(name, message)
511 char *name, *message;
512{
513 object *v = newstringobject(message);
514 if (v == NULL || dictinsert(builtin_dict, name, v) != 0)
515 fatal("no mem for new standard exception");
516 return v;
517}
518
519static void
520initerrors()
521{
522 RuntimeError = newstdexception("RuntimeError", "run-time error");
523 EOFError = newstdexception("EOFError", "end-of-file read");
524 TypeError = newstdexception("TypeError", "type error");
525 MemoryError = newstdexception("MemoryError", "out of memory");
526 NameError = newstdexception("NameError", "undefined name");
527 SystemError = newstdexception("SystemError", "system error");
528 KeyboardInterrupt =
529 newstdexception("KeyboardInterrupt", "keyboard interrupt");
530}
531
532void
533initbuiltin()
534{
535 object *m;
536 m = initmodule("builtin", builtin_methods);
537 builtin_dict = getmoduledict(m);
538 INCREF(builtin_dict);
539 initerrors();
540 (void) dictinsert(builtin_dict, "None", None);
541}