Commit 20a52359 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Add issubclass, and fix 0-arg raise statement

parent acbc8021
......@@ -1800,8 +1800,21 @@ private:
}
void doRaise(AST_Raise* node, ExcInfo exc_info) {
std::vector<llvm::Value*> args;
// It looks like ommitting the second and third arguments are equivalent to passing None,
// but ommitting the first argument is *not* the same as passing None.
if (node->arg0 == NULL) {
assert(!node->arg1);
assert(!node->arg2);
emitter.createCall(exc_info, g.funcs.raise0, std::vector<llvm::Value*>());
emitter.getBuilder()->CreateUnreachable();
endBlock(DEAD);
return;
}
std::vector<llvm::Value*> args;
for (auto a : { node->arg0, node->arg1, node->arg2 }) {
if (a) {
CompilerVariable* v = evalExpr(a, exc_info);
......
......@@ -223,6 +223,7 @@ void initGlobalFuncs(GlobalState& g) {
GET(__cxa_begin_catch);
g.funcs.__cxa_end_catch = addFunc((void*)__cxa_end_catch, g.void_);
GET(raise0);
GET(raise3);
g.funcs.div_i64_i64 = getFunc((void*)div_i64_i64, "div_i64_i64");
......
......@@ -45,7 +45,7 @@ struct GlobalFuncs {
llvm::Value* reoptCompiledFunc, *compilePartialFunc;
llvm::Value* __cxa_begin_catch, *__cxa_end_catch;
llvm::Value* raise3;
llvm::Value* raise0, *raise3;
llvm::Value* div_i64_i64, *mod_i64_i64, *pow_i64_i64;
llvm::Value* div_float_float, *mod_float_float, *pow_float_float;
......
......@@ -1707,6 +1707,7 @@ CFG* computeCFG(SourceInfo* source, std::vector<AST_stmt*> body) {
AST_Assign* module_assign = new AST_Assign();
module_assign->targets.push_back(makeName("__module__", AST_TYPE::Store));
module_assign->value = new AST_Str(static_cast<BoxedString*>(module_name)->s);
module_assign->lineno = 0;
visitor.push_back(module_assign);
// If the first statement is just a single string, transform it to an assignment to __doc__
......@@ -1716,6 +1717,7 @@ CFG* computeCFG(SourceInfo* source, std::vector<AST_stmt*> body) {
AST_Assign* doc_assign = new AST_Assign();
doc_assign->targets.push_back(makeName("__doc__", AST_TYPE::Store));
doc_assign->value = first_expr->value;
doc_assign->lineno = 0;
visitor.push_back(doc_assign);
}
}
......
......@@ -310,6 +310,14 @@ Box* isinstance_func(Box* obj, Box* cls) {
return boxBool(isinstance(obj, cls, 0));
}
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)));
}
Box* getattrFunc(Box* obj, Box* _str, Box* default_value) {
if (_str->cls != str_cls) {
raiseExcHelper(TypeError, "getattr(): attribute name must be string");
......@@ -463,6 +471,7 @@ void setupBuiltins() {
Warning = makeBuiltinException(Exception, "Warning");
/*ImportWarning =*/makeBuiltinException(Warning, "ImportWarning");
/*PendingDeprecationWarning =*/makeBuiltinException(Warning, "PendingDeprecationWarning");
/*DeprecationWarning =*/makeBuiltinException(Warning, "DeprecationWarning");
repr_obj = new BoxedFunction(boxRTFunction((void*)repr, UNKNOWN, 1));
builtins_module->giveAttr("repr", repr_obj);
......@@ -499,6 +508,9 @@ void setupBuiltins() {
Box* isinstance_obj = new BoxedFunction(boxRTFunction((void*)isinstance_func, BOXED_BOOL, 2));
builtins_module->giveAttr("isinstance", isinstance_obj);
Box* issubclass_obj = new BoxedFunction(boxRTFunction((void*)issubclass_func, BOXED_BOOL, 2));
builtins_module->giveAttr("issubclass", issubclass_obj);
CLFunction* sorted_func = createRTFunction(1, 0, false, false);
addRTFunction(sorted_func, (void*)sortedList, LIST, { LIST });
addRTFunction(sorted_func, (void*)sorted, LIST, { UNKNOWN });
......
......@@ -61,3 +61,10 @@ def f3():
print a.foo()
f3()
print isinstance(1, int)
print isinstance(1, object)
print isinstance(1, float)
print issubclass(int, int)
print issubclass(int, object)
print issubclass(int, float)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment