Commit 89c5f52b authored by Kevin Modzelewski's avatar Kevin Modzelewski

Add NONZERO support to irgen, and fix some bugs

parent 4b36c835
...@@ -372,6 +372,8 @@ private: ...@@ -372,6 +372,8 @@ private:
return UNKNOWN; return UNKNOWN;
case AST_LangPrimitive::NONE: case AST_LangPrimitive::NONE:
return NONE; return NONE;
case AST_LangPrimitive::NONZERO:
return BOOL;
default: default:
RELEASE_ASSERT(0, "%d", node->opcode); RELEASE_ASSERT(0, "%d", node->opcode);
} }
......
...@@ -404,9 +404,9 @@ Value ASTInterpreter::visit_slice(AST_Slice* node) { ...@@ -404,9 +404,9 @@ Value ASTInterpreter::visit_slice(AST_Slice* node) {
Value ASTInterpreter::visit_branch(AST_Branch* node) { Value ASTInterpreter::visit_branch(AST_Branch* node) {
Value v = visit_expr(node->test); Value v = visit_expr(node->test);
ASSERT(v.n == 0 || v.n == 1, "Should have called NONZERO before this branch"); ASSERT(v.o == True || v.o == False, "Should have called NONZERO before this branch");
if (v.b) if (v.o == True)
next_block = node->iftrue; next_block = node->iftrue;
else else
next_block = node->iffalse; next_block = node->iffalse;
...@@ -585,9 +585,7 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) { ...@@ -585,9 +585,7 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) {
} else if (node->opcode == AST_LangPrimitive::NONZERO) { } else if (node->opcode == AST_LangPrimitive::NONZERO) {
assert(node->args.size() == 1); assert(node->args.size() == 1);
Value obj = visit_expr(node->args[0]); Value obj = visit_expr(node->args[0]);
// TODO we could not add the int64_t, which would only set the lower byte of v, v = boxBool(nonzero(obj.o));
// since that's all we're going to look at later.
v = (int64_t)nonzero(obj.o);
} else } else
RELEASE_ASSERT(0, "not implemented"); RELEASE_ASSERT(0, "not implemented");
return v; return v;
......
...@@ -752,7 +752,7 @@ static void emitBBs(IRGenState* irstate, const char* bb_type, GuardList& out_gua ...@@ -752,7 +752,7 @@ static void emitBBs(IRGenState* irstate, const char* bb_type, GuardList& out_gua
// TODO: inneficient // TODO: inneficient
sym_table = new SymbolTable(*sym_table); sym_table = new SymbolTable(*sym_table);
assert(sym_table->count(name->id)); ASSERT(sym_table->count(name->id), "%d %s\n", block->idx, name->id.c_str());
sym_table->erase(name->id); sym_table->erase(name->id);
created_new_sym_table = true; created_new_sym_table = true;
} }
......
...@@ -543,6 +543,18 @@ private: ...@@ -543,6 +543,18 @@ private:
case AST_LangPrimitive::NONE: { case AST_LangPrimitive::NONE: {
return getNone(); return getNone();
} }
case AST_LangPrimitive::NONZERO: {
assert(node->args.size() == 1);
CompilerVariable* obj = evalExpr(node->args[0], unw_info);
ConcreteCompilerVariable* converted_obj = obj->makeConverted(emitter, obj->getBoxType());
obj->decvref(emitter);
llvm::Value* v = emitter.createCall(unw_info, g.funcs.nonzero, { converted_obj->getValue() });
assert(v->getType() == g.i1);
return boolFromI1(emitter, v);
}
default: default:
RELEASE_ASSERT(0, "%d", node->opcode); RELEASE_ASSERT(0, "%d", node->opcode);
} }
......
...@@ -736,7 +736,10 @@ private: ...@@ -736,7 +736,10 @@ private:
for (AST_expr* if_condition : c->ifs) { for (AST_expr* if_condition : c->ifs) {
AST_If* if_block = new AST_If(); AST_If* if_block = new AST_If();
if_block->test = callNonzero(if_condition); // Note: don't call callNonzero here, since we are generating
// AST inside a new functiondef which will go through the CFG
// process again.
if_block->test = if_condition;
insert_point->push_back(if_block); insert_point->push_back(if_block);
insert_point = &if_block->body; insert_point = &if_block->body;
......
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