From be4df96e4b80a3307b3661fd5ca3114478499daf Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 12 Apr 2016 13:30:52 -0700 Subject: passing all tests --- src/eval.cpp | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 93 insertions(+), 12 deletions(-) (limited to 'src/eval.cpp') diff --git a/src/eval.cpp b/src/eval.cpp index 41263bfcb7..1e386e0368 100644 --- a/src/eval.cpp +++ b/src/eval.cpp @@ -70,6 +70,7 @@ static bool eval_block(EvalFn *ef, AstNode *node, ConstExprValue *out) { for (int i = 0; i < node->data.block.statements.length; i += 1) { AstNode *child = node->data.block.statements.at(i); + memset(out, 0, sizeof(ConstExprValue)); if (eval_expr(ef, child, out)) return true; } @@ -109,7 +110,6 @@ void eval_const_expr_bin_op(ConstExprValue *op1_val, TypeTableEntry *op1_type, { assert(op1_val->ok); assert(op2_val->ok); - assert(op1_type == op2_type); switch (bin_op) { case BinOpTypeAssign: @@ -275,6 +275,7 @@ static bool eval_symbol_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) Buf *name = &node->data.symbol_expr.symbol; EvalVar *var = find_var(ef, name); + assert(var); *out_val = var->value; @@ -374,6 +375,8 @@ void eval_const_expr_implicit_cast(CastOp cast_op, *const_val = *other_val; break; case CastOpPointerReinterpret: + if (other_type->id == TypeTableEntryIdPointer && + new_type->id == TypeTableEntryIdPointer) { TypeTableEntry *other_child_type = other_type->data.pointer.child_type; TypeTableEntry *new_child_type = new_type->data.pointer.child_type; @@ -393,8 +396,47 @@ void eval_const_expr_implicit_cast(CastOp cast_op, } else { zig_panic("TODO"); } - break; + } else if (other_type->id == TypeTableEntryIdMaybe && + new_type->id == TypeTableEntryIdMaybe) + { + if (!other_val->data.x_maybe) { + *const_val = *other_val; + break; + } + + TypeTableEntry *other_ptr_type = other_type->data.maybe.child_type; + TypeTableEntry *new_ptr_type = new_type->data.maybe.child_type; + + if (other_ptr_type->id == TypeTableEntryIdPointer && + new_ptr_type->id == TypeTableEntryIdPointer) + { + TypeTableEntry *other_child_type = other_ptr_type->data.pointer.child_type; + TypeTableEntry *new_child_type = new_ptr_type->data.pointer.child_type; + + if ((other_child_type->id == TypeTableEntryIdInt || + other_child_type->id == TypeTableEntryIdFloat) && + (new_child_type->id == TypeTableEntryIdInt || + new_child_type->id == TypeTableEntryIdFloat)) + { + ConstExprValue *ptr_parent = allocate(1); + ConstExprValue **ptr_val = allocate(1); + *ptr_val = other_val->data.x_maybe->data.x_ptr.ptr[0]; + ptr_parent->data.x_ptr.ptr = ptr_val; + ptr_parent->data.x_ptr.len = 1; + ptr_parent->ok = true; + + const_val->data.x_maybe = ptr_parent; + const_val->ok = true; + const_val->undef = other_val->undef; + const_val->depends_on_compile_var = other_val->depends_on_compile_var; + } else { + zig_panic("TODO"); + } + } else { + zig_panic("TODO"); + } } + break; case CastOpPtrToInt: case CastOpIntToPtr: // can't do it @@ -684,6 +726,7 @@ static bool eval_field_access_expr(EvalFn *ef, AstNode *node, ConstExprValue *ou if (eval_expr(ef, struct_expr, &struct_val)) return true; ConstExprValue *field_value = struct_val.data.x_struct.fields[tsf->src_index]; *out_val = *field_value; + assert(out_val->ok); } else { zig_panic("TODO"); } @@ -916,11 +959,45 @@ static bool eval_char_literal_expr(EvalFn *ef, AstNode *node, ConstExprValue *ou return false; } +static bool eval_while_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) { + assert(node->type == NodeTypeWhileExpr); + + AstNode *cond_node = node->data.while_expr.condition; + AstNode *body_node = node->data.while_expr.body; + + EvalScope *my_scope = allocate(1); + my_scope->block_context = body_node->block_context; + ef->scope_stack.append(my_scope); + + for (;;) { + my_scope->vars.resize(0); + + ConstExprValue cond_val = {0}; + if (eval_expr(ef, cond_node, &cond_val)) return true; + + if (!cond_val.data.x_bool) break; + + ConstExprValue body_val = {0}; + if (eval_expr(ef, body_node, &body_val)) return true; + + ef->root->branches_used += 1; + } + + ef->scope_stack.pop(); + + return false; +} + static bool eval_expr(EvalFn *ef, AstNode *node, ConstExprValue *out) { if (ef->root->branches_used > ef->root->branch_quota) { ef->root->exceeded_quota_node = node; return true; } + ConstExprValue *const_val = &get_resolved_expr(node)->const_val; + if (const_val->ok) { + *out = *const_val; + return false; + } switch (node->type) { case NodeTypeBlock: return eval_block(ef, node, out); @@ -952,23 +1029,16 @@ static bool eval_expr(EvalFn *ef, AstNode *node, ConstExprValue *out) { return eval_number_literal_expr(ef, node, out); case NodeTypeCharLiteral: return eval_char_literal_expr(ef, node, out); - case NodeTypeRoot: - case NodeTypeFnProto: - case NodeTypeFnDef: - case NodeTypeFnDecl: - case NodeTypeParamDecl: - case NodeTypeDirective: + case NodeTypeWhileExpr: + return eval_while_expr(ef, node, out); case NodeTypeDefer: - case NodeTypeTypeDecl: case NodeTypeErrorValueDecl: case NodeTypeUnwrapErrorExpr: case NodeTypeStringLiteral: case NodeTypeSliceExpr: - case NodeTypeUse: case NodeTypeNullLiteral: case NodeTypeUndefinedLiteral: case NodeTypeIfVarExpr: - case NodeTypeWhileExpr: case NodeTypeSwitchExpr: case NodeTypeSwitchProng: case NodeTypeSwitchRange: @@ -976,13 +1046,22 @@ static bool eval_expr(EvalFn *ef, AstNode *node, ConstExprValue *out) { case NodeTypeGoto: case NodeTypeBreak: case NodeTypeContinue: - case NodeTypeAsmExpr: case NodeTypeStructDecl: case NodeTypeStructField: case NodeTypeStructValueField: case NodeTypeArrayType: case NodeTypeErrorType: case NodeTypeTypeLiteral: + zig_panic("TODO"); + case NodeTypeRoot: + case NodeTypeFnProto: + case NodeTypeFnDef: + case NodeTypeFnDecl: + case NodeTypeUse: + case NodeTypeAsmExpr: + case NodeTypeParamDecl: + case NodeTypeDirective: + case NodeTypeTypeDecl: zig_unreachable(); } } @@ -1054,6 +1133,8 @@ bool eval_fn(CodeGen *g, AstNode *node, FnTableEntry *fn, ConstExprValue *out_va return true; } + assert(out_val->ok); + return efr.abort; } -- cgit v1.2.3