builtins.cpp 24.3 KB
Newer Older
Kevin Modzelewski's avatar
Kevin Modzelewski committed
1
// Copyright (c) 2014 Dropbox, Inc.
Kevin Modzelewski's avatar
Kevin Modzelewski committed
2
//
Kevin Modzelewski's avatar
Kevin Modzelewski committed
3 4 5
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
Kevin Modzelewski's avatar
Kevin Modzelewski committed
6
//
Kevin Modzelewski's avatar
Kevin Modzelewski committed
7
//    http://www.apache.org/licenses/LICENSE-2.0
Kevin Modzelewski's avatar
Kevin Modzelewski committed
8
//
Kevin Modzelewski's avatar
Kevin Modzelewski committed
9 10 11 12 13 14 15
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <algorithm>
16
#include <cstddef>
Kevin Modzelewski's avatar
Kevin Modzelewski committed
17
#include <err.h>
Kevin Modzelewski's avatar
Kevin Modzelewski committed
18

19 20
#include "llvm/Support/FileSystem.h"

21
#include "codegen/compvars.h"
Kevin Modzelewski's avatar
Kevin Modzelewski committed
22 23
#include "core/ast.h"
#include "core/types.h"
24 25
#include "gc/collector.h"
#include "runtime/inline/xrange.h"
26 27
#include "runtime/list.h"
#include "runtime/long.h"
Kevin Modzelewski's avatar
Kevin Modzelewski committed
28
#include "runtime/objmodel.h"
Kevin Modzelewski's avatar
Kevin Modzelewski committed
29
#include "runtime/set.h"
Kevin Modzelewski's avatar
Kevin Modzelewski committed
30 31
#include "runtime/types.h"
#include "runtime/util.h"
32

Kevin Modzelewski's avatar
Kevin Modzelewski committed
33 34 35 36 37 38 39 40
namespace pyston {

extern "C" Box* trap() {
    raise(SIGTRAP);

    return None;
}

41 42 43 44 45 46 47
extern "C" Box* dir(Box* obj) {
    if (obj == NULL) {
        // TODO: This should actually return the elements in the current local
        // scope not the content of the builtins_module
        obj = builtins_module;
    }

48 49
    // TODO: Recursive class traversal for lookup of types and eliminating
    // duplicates afterwards
Vinzenz Feenstra's avatar
Vinzenz Feenstra committed
50
    BoxedList* result = nullptr;
51 52
    // If __dir__ is present just call it and return what it returns
    static std::string attr_dir = "__dir__";
53 54
    Box* dir_result = callattrInternal(obj, &attr_dir, CLASS_ONLY, nullptr, ArgPassSpec(0), nullptr, nullptr, nullptr,
                                       nullptr, nullptr);
55 56 57
    if (dir_result && dir_result->cls == list_cls) {
        return dir_result;
    }
58

59
    // If __dict__ is present use its keys and add the reset below
60
    Box* obj_dict = getattrInternal(obj, "__dict__", nullptr);
61 62 63 64
    if (obj_dict && obj_dict->cls == dict_cls) {
        result = new BoxedList();
        for (auto& kv : static_cast<BoxedDict*>(obj_dict)->d) {
            listAppend(result, kv.first);
65 66
        }
    }
Vinzenz Feenstra's avatar
Vinzenz Feenstra committed
67
    if (!result) {
68 69 70
        result = new BoxedList();
    }

71
    for (auto const& kv : obj->cls->attrs.hcls->attr_offsets) {
72 73
        listAppend(result, boxString(kv.first));
    }
74 75 76
    if (obj->cls->instancesHaveAttrs()) {
        HCAttrs* attrs = obj->getAttrsPtr();
        for (auto const& kv : attrs->hcls->attr_offsets) {
77 78 79 80 81 82
            listAppend(result, boxString(kv.first));
        }
    }
    return result;
}

Kevin Modzelewski's avatar
Kevin Modzelewski committed
83 84 85 86 87 88 89 90 91 92 93 94
extern "C" Box* abs_(Box* x) {
    if (x->cls == int_cls) {
        i64 n = static_cast<BoxedInt*>(x)->n;
        return boxInt(n >= 0 ? n : -n);
    } else if (x->cls == float_cls) {
        double d = static_cast<BoxedFloat*>(x)->d;
        return boxFloat(d >= 0 ? d : -d);
    } else {
        RELEASE_ASSERT(0, "%s", getTypeName(x)->c_str());
    }
}

95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
extern "C" Box* all(Box* container) {
    for (Box* e : container->pyElements()) {
        if (!nonzero(e)) {
            return boxBool(false);
        }
    }
    return boxBool(true);
}

extern "C" Box* any(Box* container) {
    for (Box* e : container->pyElements()) {
        if (nonzero(e)) {
            return boxBool(true);
        }
    }
    return boxBool(false);
}

113 114 115 116 117 118 119 120 121 122 123 124 125
extern "C" Box* min(Box* arg0, BoxedTuple* args) {
    assert(args->cls == tuple_cls);

    Box* minElement;
    Box* container;
    if (args->elts.size() == 0) {
        minElement = nullptr;
        container = arg0;
    } else {
        minElement = arg0;
        container = args;
    }

Marius Wachtler's avatar
Marius Wachtler committed
126
    for (Box* e : container->pyElements()) {
127 128 129 130 131 132 133 134 135 136 137
        if (!minElement) {
            minElement = e;
        } else {
            Box* comp_result = compareInternal(minElement, e, AST_TYPE::Gt, NULL);
            if (nonzero(comp_result)) {
                minElement = e;
            }
        }
    }

    if (!minElement) {
138
        raiseExcHelper(ValueError, "min() arg is an empty sequence");
139 140 141 142
    }
    return minElement;
}

143 144 145 146 147 148 149 150 151 152 153
extern "C" Box* max(Box* arg0, BoxedTuple* args) {
    assert(args->cls == tuple_cls);

    Box* maxElement;
    Box* container;
    if (args->elts.size() == 0) {
        maxElement = nullptr;
        container = arg0;
    } else {
        maxElement = arg0;
        container = args;
Kevin Modzelewski's avatar
Kevin Modzelewski committed
154 155
    }

Marius Wachtler's avatar
Marius Wachtler committed
156
    for (Box* e : container->pyElements()) {
157 158 159 160 161 162 163 164 165 166 167
        if (!maxElement) {
            maxElement = e;
        } else {
            Box* comp_result = compareInternal(maxElement, e, AST_TYPE::Lt, NULL);
            if (nonzero(comp_result)) {
                maxElement = e;
            }
        }
    }

    if (!maxElement) {
168
        raiseExcHelper(ValueError, "max() arg is an empty sequence");
169 170 171 172
    }
    return maxElement;
}

173
extern "C" Box* sum(Box* container, Box* initial) {
174 175 176 177 178
    if (initial->cls == str_cls)
        raiseExcHelper(TypeError, "sum() can't sum strings [use ''.join(seq) instead]");

    Box* cur = initial;
    for (Box* e : container->pyElements()) {
179
        cur = binopInternal(cur, e, AST_TYPE::Add, false, NULL);
180 181 182 183
    }
    return cur;
}

184
extern "C" Box* id(Box* arg) {
185
    i64 addr = (i64)(arg) ^ 0xdeadbeef00000003;
186 187 188 189
    return boxInt(addr);
}


190 191
Box* open(Box* arg1, Box* arg2) {
    assert(arg2);
192

Kevin Modzelewski's avatar
Kevin Modzelewski committed
193
    if (arg1->cls != str_cls) {
194 195
        fprintf(stderr, "TypeError: coercing to Unicode: need string of buffer, %s found\n",
                getTypeName(arg1)->c_str());
196
        raiseExcHelper(TypeError, "");
Kevin Modzelewski's avatar
Kevin Modzelewski committed
197 198
    }
    if (arg2->cls != str_cls) {
199 200
        fprintf(stderr, "TypeError: coercing to Unicode: need string of buffer, %s found\n",
                getTypeName(arg2)->c_str());
201
        raiseExcHelper(TypeError, "");
Kevin Modzelewski's avatar
Kevin Modzelewski committed
202 203
    }

204 205
    const std::string& fn = static_cast<BoxedString*>(arg1)->s;
    const std::string& mode = static_cast<BoxedString*>(arg2)->s;
Kevin Modzelewski's avatar
Kevin Modzelewski committed
206 207

    FILE* f = fopen(fn.c_str(), mode.c_str());
Kevin Modzelewski's avatar
Kevin Modzelewski committed
208 209
    if (!f)
        raiseExcHelper(IOError, "%s: '%s' '%s'", strerror(errno), fn.c_str());
Kevin Modzelewski's avatar
Kevin Modzelewski committed
210 211 212 213 214 215

    return new BoxedFile(f);
}

extern "C" Box* chr(Box* arg) {
    if (arg->cls != int_cls) {
216
        raiseExcHelper(TypeError, "an integer is required");
Kevin Modzelewski's avatar
Kevin Modzelewski committed
217 218
    }
    i64 n = static_cast<BoxedInt*>(arg)->n;
219 220 221
    if (n < 0 || n >= 256) {
        raiseExcHelper(ValueError, "chr() arg not in range(256)");
    }
Kevin Modzelewski's avatar
Kevin Modzelewski committed
222 223 224 225

    return boxString(std::string(1, (char)n));
}

226 227 228 229 230 231 232 233 234 235 236 237
extern "C" Box* ord(Box* arg) {
    if (arg->cls != str_cls) {
        raiseExcHelper(TypeError, "ord() expected string of length 1, but %s found", getTypeName(arg)->c_str());
    }
    const std::string& s = static_cast<BoxedString*>(arg)->s;

    if (s.size() != 1)
        raiseExcHelper(TypeError, "ord() expected string of length 1, but string of length %d found", s.size());

    return boxInt(s[0]);
}

238 239 240 241
Box* range(Box* start, Box* stop, Box* step) {
    i64 istart, istop, istep;
    if (stop == NULL) {
        RELEASE_ASSERT(start->cls == int_cls, "%s", getTypeName(start)->c_str());
Kevin Modzelewski's avatar
Kevin Modzelewski committed
242

243 244 245 246 247 248
        istart = 0;
        istop = static_cast<BoxedInt*>(start)->n;
        istep = 1;
    } else if (step == NULL) {
        RELEASE_ASSERT(start->cls == int_cls, "%s", getTypeName(start)->c_str());
        RELEASE_ASSERT(stop->cls == int_cls, "%s", getTypeName(stop)->c_str());
Kevin Modzelewski's avatar
Kevin Modzelewski committed
249

250 251 252 253 254 255 256 257 258 259 260 261
        istart = static_cast<BoxedInt*>(start)->n;
        istop = static_cast<BoxedInt*>(stop)->n;
        istep = 1;
    } else {
        RELEASE_ASSERT(start->cls == int_cls, "%s", getTypeName(start)->c_str());
        RELEASE_ASSERT(stop->cls == int_cls, "%s", getTypeName(stop)->c_str());
        RELEASE_ASSERT(step->cls == int_cls, "%s", getTypeName(step)->c_str());

        istart = static_cast<BoxedInt*>(start)->n;
        istop = static_cast<BoxedInt*>(stop)->n;
        istep = static_cast<BoxedInt*>(step)->n;
        RELEASE_ASSERT(istep != 0, "step can't be 0");
Kevin Modzelewski's avatar
Kevin Modzelewski committed
262 263
    }

264
    BoxedList* rtn = new BoxedList();
265
    rtn->ensure(std::max(0l, 1 + (istop - istart) / istep));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
266
    if (istep > 0) {
267
        for (i64 i = istart; i < istop; i += istep) {
268
            Box* bi = boxInt(i);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
269 270 271
            listAppendInternal(rtn, bi);
        }
    } else {
272
        for (i64 i = istart; i > istop; i += istep) {
273
            Box* bi = boxInt(i);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
274 275 276 277 278 279 280 281 282 283 284 285
            listAppendInternal(rtn, bi);
        }
    }
    return rtn;
}

Box* notimplementedRepr(Box* self) {
    assert(self == NotImplemented);
    return boxStrConstant("NotImplemented");
}

Box* sorted(Box* obj) {
286 287 288 289 290 291 292 293 294 295 296
    BoxedList* rtn = new BoxedList();
    for (Box* e : obj->pyElements()) {
        listAppendInternal(rtn, e);
    }

    std::sort<Box**, PyLt>(rtn->elts->elts, rtn->elts->elts + rtn->size, PyLt());

    return rtn;
}

Box* sortedList(Box* obj) {
Kevin Modzelewski's avatar
Kevin Modzelewski committed
297 298
    RELEASE_ASSERT(obj->cls == list_cls, "");

299 300
    BoxedList* lobj = static_cast<BoxedList*>(obj);
    BoxedList* rtn = new BoxedList();
Kevin Modzelewski's avatar
Kevin Modzelewski committed
301 302

    int size = lobj->size;
303
    rtn->elts = new (size) GCdArray();
Kevin Modzelewski's avatar
Kevin Modzelewski committed
304 305 306 307 308 309 310 311 312 313 314
    rtn->size = size;
    rtn->capacity = size;
    for (int i = 0; i < size; i++) {
        Box* t = rtn->elts->elts[i] = lobj->elts->elts[i];
    }

    std::sort<Box**, PyLt>(rtn->elts->elts, rtn->elts->elts + size, PyLt());

    return rtn;
}

315 316
Box* isinstance_func(Box* obj, Box* cls) {
    return boxBool(isinstance(obj, cls, 0));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
317 318
}

319 320 321 322 323 324 325 326
Box* issubclass_func(Box* child, Box* parent) {
    RELEASE_ASSERT(child->cls == type_cls, "");
    // TODO parent can also be a tuple of classes
    RELEASE_ASSERT(parent->cls == type_cls, "");

    return boxBool(isSubclass(static_cast<BoxedClass*>(child), static_cast<BoxedClass*>(parent)));
}

327
Box* getattrFunc(Box* obj, Box* _str, Box* default_value) {
Kevin Modzelewski's avatar
Kevin Modzelewski committed
328
    if (_str->cls != str_cls) {
329
        raiseExcHelper(TypeError, "getattr(): attribute name must be string");
Kevin Modzelewski's avatar
Kevin Modzelewski committed
330 331 332
    }

    BoxedString* str = static_cast<BoxedString*>(_str);
333
    Box* rtn = getattrInternal(obj, str->s, NULL);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
334 335

    if (!rtn) {
336 337 338 339 340
        if (default_value)
            return default_value;
        else
            raiseExcHelper(AttributeError, "'%s' object has no attribute '%s'", getTypeName(obj)->c_str(),
                           str->s.c_str());
Kevin Modzelewski's avatar
Kevin Modzelewski committed
341 342 343 344 345
    }

    return rtn;
}

346 347 348 349 350 351 352 353 354 355
Box* setattrFunc(Box* obj, Box* _str, Box* value) {
    if (_str->cls != str_cls) {
        raiseExcHelper(TypeError, "getattr(): attribute name must be string");
    }

    BoxedString* str = static_cast<BoxedString*>(_str);
    setattrInternal(obj, str->s, value, NULL);
    return None;
}

356 357 358 359 360 361
Box* hasattr(Box* obj, Box* _str) {
    if (_str->cls != str_cls) {
        raiseExcHelper(TypeError, "hasattr(): attribute name must be string");
    }

    BoxedString* str = static_cast<BoxedString*>(_str);
362
    Box* attr = getattrInternal(obj, str->s, NULL);
363 364 365 366 367

    Box* rtn = attr ? True : False;
    return rtn;
}

368 369
Box* map2(Box* f, Box* container) {
    Box* rtn = new BoxedList();
Marius Wachtler's avatar
Marius Wachtler committed
370
    for (Box* e : container->pyElements()) {
371
        listAppendInternal(rtn, runtimeCall(f, ArgPassSpec(1), e, NULL, NULL, NULL, NULL));
372 373 374 375
    }
    return rtn;
}

376
Box* filter2(Box* f, Box* container) {
377 378 379 380 381 382 383 384
    // If the filter-function argument is None, filter() works by only returning
    // the elements that are truthy.  This is equivalent to using the bool() constructor.
    // - actually since we call nonzero() afterwards, we could use an ident() function
    //   but we don't have one.
    // If this is a common case we could speed it up with special handling.
    if (f == None)
        f = bool_cls;

385 386 387 388 389 390 391 392 393 394
    Box* rtn = new BoxedList();
    for (Box* e : container->pyElements()) {
        Box* r = runtimeCall(f, ArgPassSpec(1), e, NULL, NULL, NULL, NULL);
        bool b = nonzero(r);
        if (b)
            listAppendInternal(rtn, e);
    }
    return rtn;
}

395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410
Box* zip2(Box* container1, Box* container2) {
    BoxedList* rtn = new BoxedList();

    llvm::iterator_range<BoxIterator> range1 = container1->pyElements();
    llvm::iterator_range<BoxIterator> range2 = container2->pyElements();

    BoxIterator it1 = range1.begin();
    BoxIterator it2 = range2.begin();

    for (; it1 != range1.end() && it2 != range2.end(); ++it1, ++it2) {
        BoxedTuple::GCVector elts{ *it1, *it2 };
        listAppendInternal(rtn, new BoxedTuple(std::move(elts)));
    }
    return rtn;
}

411
BoxedClass* notimplemented_cls;
Kevin Modzelewski's avatar
Kevin Modzelewski committed
412 413
BoxedModule* builtins_module;

414
// TODO looks like CPython and pypy put this into an "exceptions" module:
415
extern "C" {
416 417
BoxedClass* Exception, *AssertionError, *AttributeError, *GeneratorExit, *TypeError, *NameError, *KeyError, *IndexError,
    *IOError, *OSError, *ZeroDivisionError, *ValueError, *UnboundLocalError, *RuntimeError, *ImportError,
Marius Wachtler's avatar
Marius Wachtler committed
418
    *StopIteration, *Warning, *SyntaxError, *OverflowError, *DeprecationWarning, *MemoryError;
419
}
420 421 422 423 424

Box* exceptionNew1(BoxedClass* cls) {
    return exceptionNew2(cls, boxStrConstant(""));
}

425 426 427
class BoxedException : public Box {
public:
    HCAttrs attrs;
428
    BoxedException(BoxedClass* cls) : Box(cls) {}
429 430
};

431
Box* exceptionNew2(BoxedClass* cls, Box* message) {
432
    assert(cls->tp_basicsize == sizeof(BoxedException));
433
    Box* r = new BoxedException(cls);
434 435 436 437 438 439
    r->giveAttr("message", message);
    return r;
}

Box* exceptionStr(Box* b) {
    // TODO In CPython __str__ and __repr__ pull from an internalized message field, but for now do this:
440
    Box* message = b->getattr("message");
441 442 443 444 445 446 447 448 449
    assert(message);
    message = str(message);
    assert(message->cls == str_cls);

    return message;
}

Box* exceptionRepr(Box* b) {
    // TODO In CPython __str__ and __repr__ pull from an internalized message field, but for now do this:
450
    Box* message = b->getattr("message");
451 452 453 454 455 456 457 458
    assert(message);
    message = repr(message);
    assert(message->cls == str_cls);

    BoxedString* message_s = static_cast<BoxedString*>(message);
    return boxString(*getTypeName(b) + "(" + message_s->s + ",)");
}

459
static BoxedClass* makeBuiltinException(BoxedClass* base, const char* name) {
Kevin Modzelewski's avatar
Kevin Modzelewski committed
460 461
    BoxedClass* cls
        = new BoxedClass(type_cls, base, NULL, offsetof(BoxedException, attrs), sizeof(BoxedException), false);
462 463 464
    cls->giveAttr("__name__", boxStrConstant(name));

    // TODO these should be on the base Exception class:
465 466 467
    cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)exceptionNew1, UNKNOWN, 1)));
    cls->giveAttr("__str__", new BoxedFunction(boxRTFunction((void*)exceptionStr, STR, 1)));
    cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)exceptionRepr, STR, 1)));
468 469 470 471 472 473
    cls->freeze();

    builtins_module->giveAttr(name, cls);
    return cls;
}

474 475 476
BoxedClass* enumerate_cls;
class BoxedEnumerate : public Box {
private:
477
    BoxIterator iterator, iterator_end;
478 479 480
    int64_t idx;

public:
481 482
    BoxedEnumerate(BoxIterator iterator_begin, BoxIterator iterator_end, int64_t idx)
        : Box(enumerate_cls), iterator(iterator_begin), iterator_end(iterator_end), idx(idx) {}
483 484 485 486 487 488

    static Box* new_(Box* cls, Box* obj, Box* start) {
        RELEASE_ASSERT(cls == enumerate_cls, "");
        RELEASE_ASSERT(start->cls == int_cls, "");
        int64_t idx = static_cast<BoxedInt*>(start)->n;

489 490
        llvm::iterator_range<BoxIterator> range = obj->pyElements();
        return new BoxedEnumerate(range.begin(), range.end(), idx);
491 492 493 494 495 496 497 498 499 500 501
    }

    static Box* iter(Box* _self) {
        assert(_self->cls == enumerate_cls);
        BoxedEnumerate* self = static_cast<BoxedEnumerate*>(_self);
        return self;
    }

    static Box* next(Box* _self) {
        assert(_self->cls == enumerate_cls);
        BoxedEnumerate* self = static_cast<BoxedEnumerate*>(_self);
502
        return new BoxedTuple({ boxInt(self->idx++), *self->iterator++ });
503 504 505 506 507
    }

    static Box* hasnext(Box* _self) {
        assert(_self->cls == enumerate_cls);
        BoxedEnumerate* self = static_cast<BoxedEnumerate*>(_self);
508
        return boxBool(self->iterator != self->iterator_end);
509 510
    }

511 512
    static void gcHandler(GCVisitor* v, Box* b) {
        boxGCHandler(v, b);
513

514
        BoxedEnumerate* it = (BoxedEnumerate*)b;
515 516
        it->iterator.gcHandler(v);
        it->iterator_end.gcHandler(v);
517 518 519
    }
};

520 521 522 523 524 525
Box* globals() {
    BoxedModule* m = getCurrentModule();
    // TODO is it ok that we don't return a real dict here?
    return makeAttrWrapper(m);
}

526 527 528 529
Box* divmod(Box* lhs, Box* rhs) {
    return binopInternal(lhs, rhs, AST_TYPE::DivMod, false, NULL);
}

530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552
Box* execfile(Box* _fn) {
    // The "globals" and "locals" arguments aren't implemented for now
    if (!isSubclass(_fn->cls, str_cls)) {
        raiseExcHelper(TypeError, "must be string, not %s", getTypeName(_fn)->c_str());
    }

    BoxedString* fn = static_cast<BoxedString*>(_fn);

    bool exists;
    llvm::error_code code = llvm::sys::fs::exists(fn->s, exists);
#if LLVMREV < 210072
    ASSERT(code == 0, "%s: %s", code.message().c_str(), fn->s.c_str());
#else
    assert(!code);
#endif
    if (!exists)
        raiseExcHelper(IOError, "No such file or directory: '%s'", fn->s.c_str());

    compileAndRunModule("aoeu", fn->s, false);

    return None;
}

Kevin Modzelewski's avatar
Kevin Modzelewski committed
553
void setupBuiltins() {
554
    builtins_module = createModule("__builtin__", "__builtin__");
Kevin Modzelewski's avatar
Kevin Modzelewski committed
555

556
    builtins_module->giveAttr("None", None);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
557

Kevin Modzelewski's avatar
Kevin Modzelewski committed
558
    notimplemented_cls = new BoxedClass(type_cls, object_cls, NULL, 0, sizeof(Box), false);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
559
    notimplemented_cls->giveAttr("__name__", boxStrConstant("NotImplementedType"));
560
    notimplemented_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)notimplementedRepr, STR, 1)));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
561
    notimplemented_cls->freeze();
562
    NotImplemented = new Box(notimplemented_cls);
563
    gc::registerPermanentRoot(NotImplemented);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
564 565 566 567

    builtins_module->giveAttr("NotImplemented", NotImplemented);
    builtins_module->giveAttr("NotImplementedType", notimplemented_cls);

568 569
    builtins_module->giveAttr("all", new BoxedFunction(boxRTFunction((void*)all, BOXED_BOOL, 1)));
    builtins_module->giveAttr("any", new BoxedFunction(boxRTFunction((void*)any, BOXED_BOOL, 1)));
570

571 572 573
    Exception = makeBuiltinException(object_cls, "Exception");
    AssertionError = makeBuiltinException(Exception, "AssertionError");
    AttributeError = makeBuiltinException(Exception, "AttributeError");
574
    GeneratorExit = makeBuiltinException(Exception, "GeneratorExit");
575 576 577 578 579 580 581 582 583 584 585
    TypeError = makeBuiltinException(Exception, "TypeError");
    NameError = makeBuiltinException(Exception, "NameError");
    KeyError = makeBuiltinException(Exception, "KeyError");
    IndexError = makeBuiltinException(Exception, "IndexError");
    IOError = makeBuiltinException(Exception, "IOError");
    OSError = makeBuiltinException(Exception, "OSError");
    ZeroDivisionError = makeBuiltinException(Exception, "ZeroDivisionError");
    ValueError = makeBuiltinException(Exception, "ValueError");
    UnboundLocalError = makeBuiltinException(Exception, "UnboundLocalError");
    RuntimeError = makeBuiltinException(Exception, "RuntimeError");
    ImportError = makeBuiltinException(Exception, "ImportError");
586
    StopIteration = makeBuiltinException(Exception, "StopIteration");
587
    Warning = makeBuiltinException(Exception, "Warning");
588
    SyntaxError = makeBuiltinException(Exception, "SyntaxError");
589
    OverflowError = makeBuiltinException(Exception, "OverflowError");
590 591
    /*ImportWarning =*/makeBuiltinException(Warning, "ImportWarning");
    /*PendingDeprecationWarning =*/makeBuiltinException(Warning, "PendingDeprecationWarning");
592
    DeprecationWarning = makeBuiltinException(Warning, "DeprecationWarning");
593
    /*BytesWarning =*/makeBuiltinException(Warning, "BytesWarning");
Marius Wachtler's avatar
Marius Wachtler committed
594
    MemoryError = makeBuiltinException(Exception, "MemoryError");
595

596
    repr_obj = new BoxedFunction(boxRTFunction((void*)repr, UNKNOWN, 1));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
597
    builtins_module->giveAttr("repr", repr_obj);
598
    len_obj = new BoxedFunction(boxRTFunction((void*)len, UNKNOWN, 1));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
599
    builtins_module->giveAttr("len", len_obj);
600
    hash_obj = new BoxedFunction(boxRTFunction((void*)hash, UNKNOWN, 1));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
601
    builtins_module->giveAttr("hash", hash_obj);
602
    abs_obj = new BoxedFunction(boxRTFunction((void*)abs_, UNKNOWN, 1));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
603
    builtins_module->giveAttr("abs", abs_obj);
604

605
    min_obj = new BoxedFunction(boxRTFunction((void*)min, UNKNOWN, 1, 0, true, false));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
606
    builtins_module->giveAttr("min", min_obj);
607

608
    max_obj = new BoxedFunction(boxRTFunction((void*)max, UNKNOWN, 1, 0, true, false));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
609
    builtins_module->giveAttr("max", max_obj);
610

611 612
    builtins_module->giveAttr("sum",
                              new BoxedFunction(boxRTFunction((void*)sum, UNKNOWN, 2, 1, false, false), { boxInt(0) }));
613

614 615
    id_obj = new BoxedFunction(boxRTFunction((void*)id, BOXED_INT, 1));
    builtins_module->giveAttr("id", id_obj);
616
    chr_obj = new BoxedFunction(boxRTFunction((void*)chr, STR, 1));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
617
    builtins_module->giveAttr("chr", chr_obj);
618
    ord_obj = new BoxedFunction(boxRTFunction((void*)ord, BOXED_INT, 1));
619
    builtins_module->giveAttr("ord", ord_obj);
620
    trap_obj = new BoxedFunction(boxRTFunction((void*)trap, UNKNOWN, 0));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
621 622
    builtins_module->giveAttr("trap", trap_obj);

623 624
    builtins_module->giveAttr(
        "getattr", new BoxedFunction(boxRTFunction((void*)getattrFunc, UNKNOWN, 3, 1, false, false), { NULL }));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
625

626 627 628
    builtins_module->giveAttr("setattr",
                              new BoxedFunction(boxRTFunction((void*)setattrFunc, UNKNOWN, 3, 0, false, false)));

629
    Box* hasattr_obj = new BoxedFunction(boxRTFunction((void*)hasattr, BOXED_BOOL, 2));
630 631 632
    builtins_module->giveAttr("hasattr", hasattr_obj);


633
    Box* isinstance_obj = new BoxedFunction(boxRTFunction((void*)isinstance_func, BOXED_BOOL, 2));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
634 635
    builtins_module->giveAttr("isinstance", isinstance_obj);

636 637 638
    Box* issubclass_obj = new BoxedFunction(boxRTFunction((void*)issubclass_func, BOXED_BOOL, 2));
    builtins_module->giveAttr("issubclass", issubclass_obj);

639

Kevin Modzelewski's avatar
Kevin Modzelewski committed
640
    enumerate_cls = new BoxedClass(type_cls, object_cls, &BoxedEnumerate::gcHandler, 0, sizeof(BoxedEnumerate), false);
641
    enumerate_cls->giveAttr("__name__", boxStrConstant("enumerate"));
642 643 644 645 646 647 648 649 650
    enumerate_cls->giveAttr(
        "__new__",
        new BoxedFunction(boxRTFunction((void*)BoxedEnumerate::new_, UNKNOWN, 3, 1, false, false), { boxInt(0) }));
    enumerate_cls->giveAttr(
        "__iter__", new BoxedFunction(boxRTFunction((void*)BoxedEnumerate::iter, typeFromClass(enumerate_cls), 1)));
    enumerate_cls->giveAttr(
        "next", new BoxedFunction(boxRTFunction((void*)BoxedEnumerate::next, typeFromClass(enumerate_cls), 1)));
    enumerate_cls->giveAttr("__hasnext__", new BoxedFunction(boxRTFunction((void*)BoxedEnumerate::hasnext,
                                                                           typeFromClass(enumerate_cls), 1)));
651 652 653 654
    enumerate_cls->freeze();
    builtins_module->giveAttr("enumerate", enumerate_cls);


655 656 657
    CLFunction* sorted_func = createRTFunction(1, 0, false, false);
    addRTFunction(sorted_func, (void*)sortedList, LIST, { LIST });
    addRTFunction(sorted_func, (void*)sorted, LIST, { UNKNOWN });
658
    builtins_module->giveAttr("sorted", new BoxedFunction(sorted_func));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
659

660 661
    builtins_module->giveAttr("True", True);
    builtins_module->giveAttr("False", False);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
662

663
    range_obj = new BoxedFunction(boxRTFunction((void*)range, LIST, 3, 2, false, false), { NULL, NULL });
Kevin Modzelewski's avatar
Kevin Modzelewski committed
664 665 666 667 668
    builtins_module->giveAttr("range", range_obj);

    setupXrange();
    builtins_module->giveAttr("xrange", xrange_cls);

669 670
    open_obj = new BoxedFunction(boxRTFunction((void*)open, typeFromClass(file_cls), 2, 1, false, false),
                                 { boxStrConstant("r") });
Kevin Modzelewski's avatar
Kevin Modzelewski committed
671 672
    builtins_module->giveAttr("open", open_obj);

673 674
    builtins_module->giveAttr("globals", new BoxedFunction(boxRTFunction((void*)globals, UNKNOWN, 0, 0, false, false)));

675 676
    builtins_module->giveAttr("iter", new BoxedFunction(boxRTFunction((void*)getiter, UNKNOWN, 1, 0, false, false)));

677 678
    builtins_module->giveAttr("divmod", new BoxedFunction(boxRTFunction((void*)divmod, UNKNOWN, 2)));

679 680
    builtins_module->giveAttr("execfile", new BoxedFunction(boxRTFunction((void*)execfile, UNKNOWN, 1)));

681
    builtins_module->giveAttr("map", new BoxedFunction(boxRTFunction((void*)map2, LIST, 2)));
682
    builtins_module->giveAttr("filter", new BoxedFunction(boxRTFunction((void*)filter2, LIST, 2)));
683 684
    builtins_module->giveAttr("zip", new BoxedFunction(boxRTFunction((void*)zip2, LIST, 2)));
    builtins_module->giveAttr("dir", new BoxedFunction(boxRTFunction((void*)dir, LIST, 1, 1, false, false), { NULL }));
685
    builtins_module->giveAttr("object", object_cls);
686
    builtins_module->giveAttr("str", str_cls);
Travis Hance's avatar
Travis Hance committed
687
    builtins_module->giveAttr("basestring", basestring_cls);
688
    builtins_module->giveAttr("int", int_cls);
689
    builtins_module->giveAttr("long", long_cls);
690 691 692 693 694 695 696 697
    builtins_module->giveAttr("float", float_cls);
    builtins_module->giveAttr("list", list_cls);
    builtins_module->giveAttr("slice", slice_cls);
    builtins_module->giveAttr("type", type_cls);
    builtins_module->giveAttr("file", file_cls);
    builtins_module->giveAttr("bool", bool_cls);
    builtins_module->giveAttr("dict", dict_cls);
    builtins_module->giveAttr("set", set_cls);
698
    builtins_module->giveAttr("frozenset", frozenset_cls);
699 700
    builtins_module->giveAttr("tuple", tuple_cls);
    builtins_module->giveAttr("instancemethod", instancemethod_cls);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
701 702
}
}