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