bltinmodule.c revision 006bcd42ac082f05560f60577c08c957a8d38371
1/*********************************************************** 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 25/* 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" 33#include "bltinmodule.h" 34#include "import.h" 35#include "pythonrun.h" 36#include "compile.h" /* For ceval.h */ 37#include "ceval.h" 38#include "modsupport.h" 39 40/* Should be in longobject.h */ 41extern stringobject *long_format PROTO((object *, int)); 42 43static object * 44builtin_abs(self, v) 45 object *self; 46 object *v; 47{ 48 number_methods *nm; 49 if (v == NULL || (nm = v->ob_type->tp_as_number) == NULL) { 50 err_setstr(TypeError, "abs() requires numeric argument"); 51 return NULL; 52 } 53 return (*nm->nb_absolute)(v); 54} 55 56static object * 57builtin_chr(self, v) 58 object *self; 59 object *v; 60{ 61 long x; 62 char s[1]; 63 if (v == NULL || !is_intobject(v)) { 64 err_setstr(TypeError, "chr() requires int argument"); 65 return NULL; 66 } 67 x = getintvalue(v); 68 if (x < 0 || x >= 256) { 69 err_setstr(RuntimeError, "chr() arg not in range(256)"); 70 return NULL; 71 } 72 s[0] = x; 73 return newsizedstringobject(s, 1); 74} 75 76static object * 77builtin_dir(self, v) 78 object *self; 79 object *v; 80{ 81 object *d; 82 if (v == NULL) { 83 d = getlocals(); 84 INCREF(d); 85 } 86 else { 87 d = getattr(v, "__dict__"); 88 if (d == NULL) { 89 err_setstr(TypeError, 90 "dir() argument must have __dict__ attribute"); 91 return NULL; 92 } 93 } 94 if (is_dictobject(d)) { 95 v = getdictkeys(d); 96 if (sortlist(v) != 0) { 97 DECREF(v); 98 v = NULL; 99 } 100 } 101 else { 102 v = newlistobject(0); 103 } 104 DECREF(d); 105 return v; 106} 107 108static object * 109builtin_divmod(self, args) 110 object *self; 111 object *args; 112{ 113 object *v, *w, *x; 114 if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2) { 115 err_setstr(TypeError, "divmod() requires 2 arguments"); 116 return NULL; 117 } 118 v = gettupleitem(args, 0); 119 w = gettupleitem(args, 1); 120 if (v->ob_type->tp_as_number == NULL || 121 w->ob_type->tp_as_number == NULL) { 122 err_setstr(TypeError, "divmod() requires numeric arguments"); 123 return NULL; 124 } 125 if (coerce(&v, &w) != 0) 126 return NULL; 127 x = (*v->ob_type->tp_as_number->nb_divmod)(v, w); 128 DECREF(v); 129 DECREF(w); 130 return x; 131} 132 133static object * 134exec_eval(v, start) 135 object *v; 136 int start; 137{ 138 object *str = NULL, *globals = NULL, *locals = NULL; 139 int n; 140 if (v != NULL) { 141 if (is_stringobject(v)) 142 str = v; 143 else if (is_tupleobject(v) && 144 ((n = gettuplesize(v)) == 2 || n == 3)) { 145 str = gettupleitem(v, 0); 146 globals = gettupleitem(v, 1); 147 if (n == 3) 148 locals = gettupleitem(v, 2); 149 } 150 } 151 if (str == NULL || !is_stringobject(str) || 152 globals != NULL && !is_dictobject(globals) || 153 locals != NULL && !is_dictobject(locals)) { 154 err_setstr(TypeError, 155 "exec/eval arguments must be string[,dict[,dict]]"); 156 return NULL; 157 } 158 return run_string(getstringvalue(str), start, globals, locals); 159} 160 161static object * 162builtin_eval(self, v) 163 object *self; 164 object *v; 165{ 166 return exec_eval(v, eval_input); 167} 168 169static object * 170builtin_exec(self, v) 171 object *self; 172 object *v; 173{ 174 return exec_eval(v, file_input); 175} 176 177static object * 178builtin_float(self, v) 179 object *self; 180 object *v; 181{ 182 if (v == NULL) { 183 /* */ 184 } 185 else if (is_intobject(v)) { 186 long x = getintvalue(v); 187 return newfloatobject((double)x); 188 } 189 else if (is_longobject(v)) { 190 return newfloatobject(dgetlongvalue(v)); 191 } 192 else if (is_floatobject(v)) { 193 INCREF(v); 194 return v; 195 } 196 err_setstr(TypeError, "float() argument must be int, long or float"); 197 return NULL; 198} 199 200static object * 201builtin_hex(self, v) 202 object *self; 203 object *v; 204{ 205 if (v != NULL) { 206 if (is_intobject(v)) { 207 char buf[20]; 208 long x = getintvalue(v); 209 if (x >= 0) 210 sprintf(buf, "0x%lx", x); 211 else 212 sprintf(buf, "-0x%lx", -x); 213 return newstringobject(buf); 214 } 215 if (is_longobject(v)) { 216 return (object *) long_format(v, 16); 217 } 218 } 219 err_setstr(TypeError, "hex() requires int/long argument"); 220 return NULL; 221} 222 223static object * 224builtin_input(self, v) 225 object *self; 226 object *v; 227{ 228 FILE *in = sysgetfile("stdin", stdin); 229 FILE *out = sysgetfile("stdout", stdout); 230 node *n; 231 int err; 232 object *m, *d; 233 flushline(); 234 if (v != NULL) { 235 if (printobject(v, out, PRINT_RAW) != 0) 236 return NULL; 237 } 238 m = add_module("__main__"); 239 d = getmoduledict(m); 240 return run_file(in, "<stdin>", expr_input, d, d); 241} 242 243static object * 244builtin_int(self, v) 245 object *self; 246 object *v; 247{ 248 if (v == NULL) { 249 /* */ 250 } 251 else if (is_intobject(v)) { 252 INCREF(v); 253 return v; 254 } 255 else if (is_longobject(v)) { 256 long x; 257 x = getlongvalue(v); 258 if (err_occurred()) 259 return NULL; 260 return newintobject(x); 261 } 262 else if (is_floatobject(v)) { 263 double x = getfloatvalue(v); 264 /* XXX should check for overflow */ 265 return newintobject((long)x); 266 } 267 err_setstr(TypeError, "int() argument must be int, long or float"); 268 return NULL; 269} 270 271static object * 272builtin_len(self, v) 273 object *self; 274 object *v; 275{ 276 long len; 277 typeobject *tp; 278 if (v == NULL) { 279 err_setstr(TypeError, "len() without argument"); 280 return NULL; 281 } 282 tp = v->ob_type; 283 if (tp->tp_as_sequence != NULL) { 284 len = (*tp->tp_as_sequence->sq_length)(v); 285 } 286 else if (tp->tp_as_mapping != NULL) { 287 len = (*tp->tp_as_mapping->mp_length)(v); 288 } 289 else { 290 err_setstr(TypeError, "len() of unsized object"); 291 return NULL; 292 } 293 return newintobject(len); 294} 295 296static object * 297builtin_long(self, v) 298 object *self; 299 object *v; 300{ 301 if (v == NULL) { 302 /* */ 303 } 304 else if (is_intobject(v)) { 305 return newlongobject(getintvalue(v)); 306 } 307 else if (is_longobject(v)) { 308 INCREF(v); 309 return v; 310 } 311 else if (is_floatobject(v)) { 312 double x = getfloatvalue(v); 313 return dnewlongobject(x); 314 } 315 err_setstr(TypeError, "long() argument must be int, long or float"); 316 return NULL; 317} 318 319static object * 320min_max(v, sign) 321 object *v; 322 int sign; 323{ 324 int i, n, cmp; 325 object *w, *x; 326 sequence_methods *sq; 327 if (v == NULL) { 328 err_setstr(TypeError, "min() or max() without argument"); 329 return NULL; 330 } 331 sq = v->ob_type->tp_as_sequence; 332 if (sq == NULL) { 333 err_setstr(TypeError, "min() or max() of non-sequence"); 334 return NULL; 335 } 336 n = (*sq->sq_length)(v); 337 if (n == 0) { 338 err_setstr(RuntimeError, "min() or max() of empty sequence"); 339 return NULL; 340 } 341 w = (*sq->sq_item)(v, 0); /* Implies INCREF */ 342 for (i = 1; i < n; i++) { 343 x = (*sq->sq_item)(v, i); /* Implies INCREF */ 344 cmp = cmpobject(x, w); 345 if (cmp * sign > 0) { 346 DECREF(w); 347 w = x; 348 } 349 else 350 DECREF(x); 351 } 352 return w; 353} 354 355static object * 356builtin_min(self, v) 357 object *self; 358 object *v; 359{ 360 return min_max(v, -1); 361} 362 363static object * 364builtin_max(self, v) 365 object *self; 366 object *v; 367{ 368 return min_max(v, 1); 369} 370 371static object * 372builtin_oct(self, v) 373 object *self; 374 object *v; 375{ 376 if (v != NULL) { 377 if (is_intobject(v)) { 378 char buf[20]; 379 long x = getintvalue(v); 380 if (x >= 0) 381 sprintf(buf, "0%lo", x); 382 else 383 sprintf(buf, "-0%lo", -x); 384 return newstringobject(buf); 385 } 386 if (is_longobject(v)) { 387 return (object *) long_format(v, 8); 388 } 389 } 390 err_setstr(TypeError, "oct() requires int/long argument"); 391 return NULL; 392} 393 394static object * 395builtin_open(self, v) 396 object *self; 397 object *v; 398{ 399 object *name, *mode; 400 if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 2 || 401 !is_stringobject(name = gettupleitem(v, 0)) || 402 !is_stringobject(mode = gettupleitem(v, 1))) { 403 err_setstr(TypeError, "open() requires 2 string arguments"); 404 return NULL; 405 } 406 v = newfileobject(getstringvalue(name), getstringvalue(mode)); 407 return v; 408} 409 410static object * 411builtin_ord(self, v) 412 object *self; 413 object *v; 414{ 415 if (v == NULL || !is_stringobject(v)) { 416 err_setstr(TypeError, "ord() must have string argument"); 417 return NULL; 418 } 419 if (getstringsize(v) != 1) { 420 err_setstr(RuntimeError, "ord() arg must have length 1"); 421 return NULL; 422 } 423 return newintobject((long)(getstringvalue(v)[0] & 0xff)); 424} 425 426static object * 427builtin_pow(self, args) 428 object *self; 429 object *args; 430{ 431 object *v, *w, *x; 432 if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2) { 433 err_setstr(TypeError, "pow() requires 2 arguments"); 434 return NULL; 435 } 436 v = gettupleitem(args, 0); 437 w = gettupleitem(args, 1); 438 if (v->ob_type->tp_as_number == NULL || 439 w->ob_type->tp_as_number == NULL) { 440 err_setstr(TypeError, "pow() requires numeric arguments"); 441 return NULL; 442 } 443 if (coerce(&v, &w) != 0) 444 return NULL; 445 x = (*v->ob_type->tp_as_number->nb_power)(v, w); 446 DECREF(v); 447 DECREF(w); 448 return x; 449} 450 451static object * 452builtin_range(self, v) 453 object *self; 454 object *v; 455{ 456 static char *errmsg = "range() requires 1-3 int arguments"; 457 int i, n; 458 long ilow, ihigh, istep; 459 if (v != NULL && is_intobject(v)) { 460 ilow = 0; ihigh = getintvalue(v); istep = 1; 461 } 462 else if (v == NULL || !is_tupleobject(v)) { 463 err_setstr(TypeError, errmsg); 464 return NULL; 465 } 466 else { 467 n = gettuplesize(v); 468 if (n < 1 || n > 3) { 469 err_setstr(TypeError, errmsg); 470 return NULL; 471 } 472 for (i = 0; i < n; i++) { 473 if (!is_intobject(gettupleitem(v, i))) { 474 err_setstr(TypeError, errmsg); 475 return NULL; 476 } 477 } 478 if (n == 3) { 479 istep = getintvalue(gettupleitem(v, 2)); 480 --n; 481 } 482 else 483 istep = 1; 484 ihigh = getintvalue(gettupleitem(v, --n)); 485 if (n > 0) 486 ilow = getintvalue(gettupleitem(v, 0)); 487 else 488 ilow = 0; 489 } 490 if (istep == 0) { 491 err_setstr(RuntimeError, "zero step for range()"); 492 return NULL; 493 } 494 /* XXX ought to check overflow of subtraction */ 495 if (istep > 0) 496 n = (ihigh - ilow + istep - 1) / istep; 497 else 498 n = (ihigh - ilow + istep + 1) / istep; 499 if (n < 0) 500 n = 0; 501 v = newlistobject(n); 502 if (v == NULL) 503 return NULL; 504 for (i = 0; i < n; i++) { 505 object *w = newintobject(ilow); 506 if (w == NULL) { 507 DECREF(v); 508 return NULL; 509 } 510 setlistitem(v, i, w); 511 ilow += istep; 512 } 513 return v; 514} 515 516static object * 517builtin_raw_input(self, v) 518 object *self; 519 object *v; 520{ 521 FILE *out = sysgetfile("stdout", stdout); 522 flushline(); 523 if (v != NULL) { 524 if (printobject(v, out, PRINT_RAW) != 0) 525 return NULL; 526 } 527 return filegetline(sysget("stdin"), -1); 528} 529 530static object * 531builtin_reload(self, v) 532 object *self; 533 object *v; 534{ 535 return reload_module(v); 536} 537 538static object * 539builtin_type(self, v) 540 object *self; 541 object *v; 542{ 543 if (v == NULL) { 544 err_setstr(TypeError, "type() requres an argument"); 545 return NULL; 546 } 547 v = (object *)v->ob_type; 548 INCREF(v); 549 return v; 550} 551 552static struct methodlist builtin_methods[] = { 553 {"abs", builtin_abs}, 554 {"chr", builtin_chr}, 555 {"dir", builtin_dir}, 556 {"divmod", builtin_divmod}, 557 {"eval", builtin_eval}, 558 {"exec", builtin_exec}, 559 {"float", builtin_float}, 560 {"hex", builtin_hex}, 561 {"input", builtin_input}, 562 {"int", builtin_int}, 563 {"len", builtin_len}, 564 {"long", builtin_long}, 565 {"max", builtin_max}, 566 {"min", builtin_min}, 567 {"oct", builtin_oct}, 568 {"open", builtin_open}, /* XXX move to OS module */ 569 {"ord", builtin_ord}, 570 {"pow", builtin_pow}, 571 {"range", builtin_range}, 572 {"raw_input", builtin_raw_input}, 573 {"reload", builtin_reload}, 574 {"type", builtin_type}, 575 {NULL, NULL}, 576}; 577 578static object *builtin_dict; 579 580object * 581getbuiltin(name) 582 object *name; 583{ 584 return dict2lookup(builtin_dict, name); 585} 586 587/* Predefined exceptions */ 588 589object *RuntimeError; 590object *EOFError; 591object *TypeError; 592object *MemoryError; 593object *NameError; 594object *SystemError; 595object *KeyboardInterrupt; 596 597static object * 598newstdexception(name, message) 599 char *name, *message; 600{ 601 object *v = newstringobject(message); 602 if (v == NULL || dictinsert(builtin_dict, name, v) != 0) 603 fatal("no mem for new standard exception"); 604 return v; 605} 606 607static void 608initerrors() 609{ 610 RuntimeError = newstdexception("RuntimeError", "run-time error"); 611 EOFError = newstdexception("EOFError", "end-of-file read"); 612 TypeError = newstdexception("TypeError", "type error"); 613 MemoryError = newstdexception("MemoryError", "out of memory"); 614 NameError = newstdexception("NameError", "undefined name"); 615 SystemError = newstdexception("SystemError", "system error"); 616 KeyboardInterrupt = 617 newstdexception("KeyboardInterrupt", "keyboard interrupt"); 618} 619 620void 621initbuiltin() 622{ 623 object *m; 624 m = initmodule("builtin", builtin_methods); 625 builtin_dict = getmoduledict(m); 626 INCREF(builtin_dict); 627 initerrors(); 628 (void) dictinsert(builtin_dict, "None", None); 629} 630 631/* Coerce two numeric types to the "larger" one. 632 Increment the reference count on each argument. 633 Return -1 and raise an exception if no coercion is possible 634 (and then no reference count is incremented). 635 XXX This should be distributed over the various numeric types, 636 XXX but for now I don't see how to implement that. 637 XXX So, for now, if you add a new numeric type, 638 XXX you must add to this function as well. */ 639 640int 641coerce(pv, pw) 642 object **pv, **pw; 643{ 644 register object *v = *pv; 645 register object *w = *pw; 646 if (v->ob_type == w->ob_type) { 647 INCREF(v); 648 INCREF(w); 649 return 0; 650 } 651 if (v->ob_type->tp_as_number == NULL || 652 w->ob_type->tp_as_number == NULL) { 653 err_setstr(TypeError, "mixing number and non-number"); 654 return -1; 655 } 656 if (is_floatobject(v) || is_floatobject(w)) { 657 v = builtin_float((object *)0, v); 658 w = builtin_float((object *)0, w); 659 } 660 else if (is_longobject(v) || is_longobject(w)) { 661 v = builtin_long((object *)0, v); 662 w = builtin_long((object *)0, w); 663 } 664 else { 665 err_setstr(TypeError, "can't coerce numeric types?!?!?"); 666 return -1; 667 } 668 if (v == NULL || w == NULL) { 669 XDECREF(v); 670 XDECREF(w); 671 return -1; 672 } 673 *pv = v; 674 *pw = w; 675 return 0; 676} 677