Mercurial > cpython-lru_cache-weakref
annotate Python/bltinmodule.c @ 208:f352ea4dff70 legacy-trunk
Initial revision
| author | Guido van Rossum <guido@python.org> |
|---|---|
| date | Tue, 16 Apr 1991 08:45:40 +0000 |
| parents | 59ffb6d4b34c |
| children | 6693c5d87f3a |
| rev | line source |
|---|---|
|
145
853b736a6a9e
Added copyright notice.
Guido van Rossum <guido@python.org>
parents:
139
diff
changeset
|
1 /*********************************************************** |
|
853b736a6a9e
Added copyright notice.
Guido van Rossum <guido@python.org>
parents:
139
diff
changeset
|
2 Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The |
|
853b736a6a9e
Added copyright notice.
Guido van Rossum <guido@python.org>
parents:
139
diff
changeset
|
3 Netherlands. |
|
853b736a6a9e
Added copyright notice.
Guido van Rossum <guido@python.org>
parents:
139
diff
changeset
|
4 |
|
853b736a6a9e
Added copyright notice.
Guido van Rossum <guido@python.org>
parents:
139
diff
changeset
|
5 All Rights Reserved |
|
853b736a6a9e
Added copyright notice.
Guido van Rossum <guido@python.org>
parents:
139
diff
changeset
|
6 |
|
853b736a6a9e
Added copyright notice.
Guido van Rossum <guido@python.org>
parents:
139
diff
changeset
|
7 Permission to use, copy, modify, and distribute this software and its |
|
853b736a6a9e
Added copyright notice.
Guido van Rossum <guido@python.org>
parents:
139
diff
changeset
|
8 documentation for any purpose and without fee is hereby granted, |
|
853b736a6a9e
Added copyright notice.
Guido van Rossum <guido@python.org>
parents:
139
diff
changeset
|
9 provided that the above copyright notice appear in all copies and that |
|
853b736a6a9e
Added copyright notice.
Guido van Rossum <guido@python.org>
parents:
139
diff
changeset
|
10 both that copyright notice and this permission notice appear in |
|
853b736a6a9e
Added copyright notice.
Guido van Rossum <guido@python.org>
parents:
139
diff
changeset
|
11 supporting documentation, and that the names of Stichting Mathematisch |
|
853b736a6a9e
Added copyright notice.
Guido van Rossum <guido@python.org>
parents:
139
diff
changeset
|
12 Centrum or CWI not be used in advertising or publicity pertaining to |
|
853b736a6a9e
Added copyright notice.
Guido van Rossum <guido@python.org>
parents:
139
diff
changeset
|
13 distribution of the software without specific, written prior permission. |
|
853b736a6a9e
Added copyright notice.
Guido van Rossum <guido@python.org>
parents:
139
diff
changeset
|
14 |
|
853b736a6a9e
Added copyright notice.
Guido van Rossum <guido@python.org>
parents:
139
diff
changeset
|
15 STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO |
|
853b736a6a9e
Added copyright notice.
Guido van Rossum <guido@python.org>
parents:
139
diff
changeset
|
16 THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND |
|
853b736a6a9e
Added copyright notice.
Guido van Rossum <guido@python.org>
parents:
139
diff
changeset
|
17 FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE |
|
853b736a6a9e
Added copyright notice.
Guido van Rossum <guido@python.org>
parents:
139
diff
changeset
|
18 FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
853b736a6a9e
Added copyright notice.
Guido van Rossum <guido@python.org>
parents:
139
diff
changeset
|
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|
853b736a6a9e
Added copyright notice.
Guido van Rossum <guido@python.org>
parents:
139
diff
changeset
|
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT |
|
853b736a6a9e
Added copyright notice.
Guido van Rossum <guido@python.org>
parents:
139
diff
changeset
|
21 OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
853b736a6a9e
Added copyright notice.
Guido van Rossum <guido@python.org>
parents:
139
diff
changeset
|
22 |
|
853b736a6a9e
Added copyright notice.
Guido van Rossum <guido@python.org>
parents:
139
diff
changeset
|
23 ******************************************************************/ |
|
853b736a6a9e
Added copyright notice.
Guido van Rossum <guido@python.org>
parents:
139
diff
changeset
|
24 |
| 86 | 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" | |
| 119 | 33 #include "bltinmodule.h" |
| 86 | 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 static object * | |
| 41 builtin_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 | |
| 65 static object * | |
| 66 builtin_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 | |
| 85 static object * | |
| 86 builtin_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 | |
| 110 static object * | |
| 111 builtin_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 | |
| 158 static object * | |
| 159 exec_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 | |
| 186 static object * | |
| 187 builtin_eval(self, v) | |
| 188 object *self; | |
| 189 object *v; | |
| 190 { | |
| 191 return exec_eval(v, eval_input); | |
| 192 } | |
| 193 | |
| 194 static object * | |
| 195 builtin_exec(self, v) | |
| 196 object *self; | |
| 197 object *v; | |
| 198 { | |
| 199 return exec_eval(v, file_input); | |
| 200 } | |
| 201 | |
| 202 static object * | |
| 203 builtin_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 | |
| 222 static object * | |
| 223 builtin_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 | |
| 240 static object * | |
| 241 builtin_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 | |
| 260 static object * | |
| 261 builtin_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 | |
| 285 static object * | |
| 286 min_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 | |
| 321 static object * | |
| 322 builtin_min(self, v) | |
| 323 object *self; | |
| 324 object *v; | |
| 325 { | |
| 326 return min_max(v, -1); | |
| 327 } | |
| 328 | |
| 329 static object * | |
| 330 builtin_max(self, v) | |
| 331 object *self; | |
| 332 object *v; | |
| 333 { | |
| 334 return min_max(v, 1); | |
| 335 } | |
| 336 | |
| 337 static object * | |
| 338 builtin_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 | |
| 353 static object * | |
| 354 builtin_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 | |
| 369 static object * | |
| 370 builtin_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 | |
| 434 static object * | |
| 435 builtin_raw_input(self, v) | |
| 436 object *self; | |
| 437 object *v; | |
| 438 { | |
| 439 FILE *out = sysgetfile("stdout", stdout); | |
| 440 flushline(); | |
| 441 if (v != NULL) | |
| 442 printobject(v, out, PRINT_RAW); | |
|
182
59ffb6d4b34c
Use fileobject's filegetline() to implement unlimited raw_input().
Guido van Rossum <guido@python.org>
parents:
145
diff
changeset
|
443 return filegetline(sysget("stdin"), -1); |
| 86 | 444 } |
| 445 | |
| 446 static object * | |
| 447 builtin_reload(self, v) | |
| 448 object *self; | |
| 449 object *v; | |
| 450 { | |
| 451 return reload_module(v); | |
| 452 } | |
| 453 | |
| 454 static object * | |
| 455 builtin_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 | |
| 468 static 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}, | |
|
139
c294a8caebb9
Reversed min and max (to alphabetical order).
Guido van Rossum <guido@python.org>
parents:
119
diff
changeset
|
479 {"max", builtin_max}, |
| 86 | 480 {"min", builtin_min}, |
| 481 {"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 | |
| 490 static object *builtin_dict; | |
| 491 | |
| 492 object * | |
| 493 getbuiltin(name) | |
| 494 char *name; | |
| 495 { | |
| 496 return dictlookup(builtin_dict, name); | |
| 497 } | |
| 498 | |
| 499 /* Predefined exceptions */ | |
| 500 | |
| 501 object *RuntimeError; | |
| 502 object *EOFError; | |
| 503 object *TypeError; | |
| 504 object *MemoryError; | |
| 505 object *NameError; | |
| 506 object *SystemError; | |
| 507 object *KeyboardInterrupt; | |
| 508 | |
| 509 static object * | |
| 510 newstdexception(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 | |
| 519 static void | |
| 520 initerrors() | |
| 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 | |
| 532 void | |
| 533 initbuiltin() | |
| 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 } |
