Commit a55555c99e

Andrew Kelley <superjoe30@gmail.com>
2016-11-17 06:44:14
remove superseded eval code
1 parent 8d1c613
Changed files (2)
src/eval.cpp
@@ -2,36 +2,6 @@
 #include "analyze.hpp"
 #include "error.hpp"
 
-struct EvalVar {
-    Buf *name;
-    ConstExprValue value;
-};
-
-struct EvalScope {
-    BlockContext *block_context;
-    ZigList<EvalVar> vars;
-};
-
-struct EvalFnRoot {
-    CodeGen *codegen;
-    FnTableEntry *fn;
-    AstNode *call_node;
-    size_t branch_quota;
-    size_t branches_used;
-    AstNode *exceeded_quota_node;
-    bool abort;
-};
-
-struct EvalFn {
-    EvalFnRoot *root;
-    FnTableEntry *fn;
-    ConstExprValue *return_expr;
-    ZigList<EvalScope*> scope_stack;
-};
-
-
-static bool eval_fn_args(EvalFnRoot *efr, FnTableEntry *fn, ConstExprValue *args, ConstExprValue *out_val);
-
 bool const_values_equal(ConstExprValue *a, ConstExprValue *b, TypeTableEntry *type_entry) {
     switch (type_entry->id) {
         case TypeTableEntryIdEnum:
@@ -95,33 +65,6 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b, TypeTableEntry *ty
 }
 
 
-static bool eval_expr(EvalFn *ef, AstNode *node, ConstExprValue *out);
-
-static bool eval_block(EvalFn *ef, AstNode *node, ConstExprValue *out) {
-    assert(node->type == NodeTypeBlock);
-
-    EvalScope *my_scope = allocate<EvalScope>(1);
-    my_scope->block_context = node->block_context;
-    ef->scope_stack.append(my_scope);
-
-    for (size_t 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;
-    }
-
-    ef->scope_stack.pop();
-
-    return false;
-}
-
-static bool eval_return(EvalFn *ef, AstNode *node, ConstExprValue *out) {
-    assert(node->type == NodeTypeReturnExpr);
-
-    eval_expr(ef, node->data.return_expr.expr, ef->return_expr);
-    return true;
-}
-
 static bool eval_bool_bin_op_bool(bool a, BinOpType bin_op, bool b) {
     if (bin_op == BinOpTypeBoolOr || bin_op == BinOpTypeAssignBoolOr) {
         return a || b;
@@ -209,31 +152,6 @@ static int eval_const_expr_bin_op_bignum(ConstExprValue *op1_val, ConstExprValue
     return 0;
 }
 
-bool eval_const_expr_bin_op_handle_errors(EvalFn *ef, AstNode *node,
-        ConstExprValue *op1_val, TypeTableEntry *op1_type,
-        BinOpType bin_op, ConstExprValue *op2_val, TypeTableEntry *op2_type, ConstExprValue *out_val)
-{
-    int err;
-    if ((err = eval_const_expr_bin_op(op1_val, op1_type, bin_op, op2_val, op2_type, out_val))) {
-        ef->root->abort = true;
-        if (err == ErrorDivByZero) {
-            ErrorMsg *msg = add_node_error(ef->root->codegen, ef->root->fn->fn_def_node,
-                    buf_sprintf("function evaluation caused division by zero"));
-            add_error_note(ef->root->codegen, msg, ef->root->call_node, buf_sprintf("called from here"));
-            add_error_note(ef->root->codegen, msg, node, buf_sprintf("division by zero here"));
-        } else if (err == ErrorOverflow) {
-            ErrorMsg *msg = add_node_error(ef->root->codegen, ef->root->fn->fn_def_node,
-                    buf_sprintf("function evaluation caused overflow"));
-            add_error_note(ef->root->codegen, msg, ef->root->call_node, buf_sprintf("called from here"));
-            add_error_note(ef->root->codegen, msg, node, buf_sprintf("overflow occurred here"));
-        } else {
-            zig_unreachable();
-        }
-        return true;
-    }
-    return false;
-}
-
 int eval_const_expr_bin_op(ConstExprValue *op1_val, TypeTableEntry *op1_type,
         BinOpType bin_op, ConstExprValue *op2_val, TypeTableEntry *op2_type, ConstExprValue *out_val)
 {
@@ -375,249 +293,6 @@ int eval_const_expr_bin_op(ConstExprValue *op1_val, TypeTableEntry *op1_type,
     zig_unreachable();
 }
 
-static EvalVar *find_var(EvalFn *ef, Buf *name) {
-    size_t scope_index = ef->scope_stack.length - 1;
-    while (scope_index != SIZE_MAX) {
-        EvalScope *scope = ef->scope_stack.at(scope_index);
-        for (size_t var_i = 0; var_i < scope->vars.length; var_i += 1) {
-            EvalVar *var = &scope->vars.at(var_i);
-            if (buf_eql_buf(var->name, name)) {
-                return var;
-            }
-        }
-        scope_index -= 1;
-    }
-
-    return nullptr;
-}
-
-static bool eval_get_lvalue(EvalFn *ef, AstNode *node, ConstExprValue **lvalue) {
-    if (node->type == NodeTypeSymbol) {
-        Buf *name = node->data.symbol_expr.symbol;
-        EvalVar *var = find_var(ef, name);
-        assert(var);
-        *lvalue = &var->value;
-    } else {
-        zig_panic("TODO eval other lvalue types");
-    }
-    return false;
-}
-
-static bool eval_bin_op_assign(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {
-    AstNode *op1 = node->data.bin_op_expr.op1;
-    AstNode *op2 = node->data.bin_op_expr.op2;
-    BinOpType bin_op = node->data.bin_op_expr.bin_op;
-
-    TypeTableEntry *op2_type = get_resolved_expr(op2)->type_entry;
-    assert(op2_type);
-
-    ConstExprValue *assign_result_val;
-    if (eval_get_lvalue(ef, op1, &assign_result_val)) return true;
-
-    ConstExprValue op1_val = *assign_result_val;
-
-    ConstExprValue op2_val = {0};
-    if (eval_expr(ef, op2, &op2_val)) return true;
-
-    if (eval_const_expr_bin_op_handle_errors(ef, node, &op1_val, op2_type, bin_op, &op2_val, op2_type,
-        assign_result_val))
-    {
-        return true;
-    }
-
-    out_val->ok = true;
-    out_val->depends_on_compile_var = false;
-    return false;
-}
-
-static bool eval_bin_op_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {
-    assert(node->type == NodeTypeBinOpExpr);
-
-    BinOpType bin_op = node->data.bin_op_expr.bin_op;
-
-    switch (bin_op) {
-        case BinOpTypeAssign:
-        case BinOpTypeAssignTimes:
-        case BinOpTypeAssignTimesWrap:
-        case BinOpTypeAssignDiv:
-        case BinOpTypeAssignMod:
-        case BinOpTypeAssignPlus:
-        case BinOpTypeAssignPlusWrap:
-        case BinOpTypeAssignMinus:
-        case BinOpTypeAssignMinusWrap:
-        case BinOpTypeAssignBitShiftLeft:
-        case BinOpTypeAssignBitShiftLeftWrap:
-        case BinOpTypeAssignBitShiftRight:
-        case BinOpTypeAssignBitAnd:
-        case BinOpTypeAssignBitXor:
-        case BinOpTypeAssignBitOr:
-        case BinOpTypeAssignBoolAnd:
-        case BinOpTypeAssignBoolOr:
-            return eval_bin_op_assign(ef, node, out_val);
-        case BinOpTypeBoolOr:
-        case BinOpTypeBoolAnd:
-        case BinOpTypeCmpEq:
-        case BinOpTypeCmpNotEq:
-        case BinOpTypeCmpLessThan:
-        case BinOpTypeCmpGreaterThan:
-        case BinOpTypeCmpLessOrEq:
-        case BinOpTypeCmpGreaterOrEq:
-        case BinOpTypeBinOr:
-        case BinOpTypeBinXor:
-        case BinOpTypeBinAnd:
-        case BinOpTypeBitShiftLeft:
-        case BinOpTypeBitShiftLeftWrap:
-        case BinOpTypeBitShiftRight:
-        case BinOpTypeAdd:
-        case BinOpTypeAddWrap:
-        case BinOpTypeSub:
-        case BinOpTypeSubWrap:
-        case BinOpTypeMult:
-        case BinOpTypeMultWrap:
-        case BinOpTypeDiv:
-        case BinOpTypeMod:
-        case BinOpTypeUnwrapMaybe:
-        case BinOpTypeArrayCat:
-        case BinOpTypeArrayMult:
-            break;
-        case BinOpTypeInvalid:
-            zig_unreachable();
-    }
-
-    AstNode *op1 = node->data.bin_op_expr.op1;
-    AstNode *op2 = node->data.bin_op_expr.op2;
-
-
-    TypeTableEntry *op1_type = get_resolved_expr(op1)->type_entry;
-    TypeTableEntry *op2_type = get_resolved_expr(op2)->type_entry;
-
-    assert(op1_type);
-    assert(op2_type);
-
-    ConstExprValue op1_val = {0};
-    if (eval_expr(ef, op1, &op1_val)) return true;
-
-    ConstExprValue op2_val = {0};
-    if (eval_expr(ef, op2, &op2_val)) return true;
-
-    if (eval_const_expr_bin_op_handle_errors(ef, node, &op1_val, op1_type, bin_op, &op2_val, op2_type, out_val)) {
-        return true;
-    }
-
-    assert(out_val->ok);
-
-    return false;
-}
-
-static bool eval_symbol_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {
-    assert(node->type == NodeTypeSymbol);
-
-    Buf *name = node->data.symbol_expr.symbol;
-    EvalVar *var = find_var(ef, name);
-    assert(var);
-
-    *out_val = var->value;
-
-    return false;
-}
-
-static TypeTableEntry *resolve_expr_type(AstNode *node) {
-    Expr *expr = get_resolved_expr(node);
-    TypeTableEntry *type_entry = expr->type_entry;
-    assert(type_entry->id == TypeTableEntryIdMetaType);
-    ConstExprValue *const_val = &expr->const_val;
-    assert(const_val->ok);
-    return const_val->data.x_type;
-}
-
-static bool eval_container_init_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {
-    assert(node->type == NodeTypeContainerInitExpr);
-
-    AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr;
-    ContainerInitKind kind = container_init_expr->kind;
-
-    if (container_init_expr->enum_type) {
-        zig_panic("TODO eval enum init");
-    }
-
-    TypeTableEntry *container_type = resolve_expr_type(container_init_expr->type);
-    out_val->ok = true;
-
-    if (container_type->id == TypeTableEntryIdStruct &&
-        !container_type->data.structure.is_slice &&
-        kind == ContainerInitKindStruct)
-    {
-        size_t expr_field_count = container_init_expr->entries.length;
-        size_t actual_field_count = container_type->data.structure.src_field_count;
-        assert(expr_field_count == actual_field_count);
-
-        out_val->data.x_struct.fields = allocate<ConstExprValue*>(actual_field_count);
-
-        for (size_t i = 0; i < expr_field_count; i += 1) {
-            AstNode *val_field_node = container_init_expr->entries.at(i);
-            assert(val_field_node->type == NodeTypeStructValueField);
-
-            TypeStructField *type_field = val_field_node->data.struct_val_field.type_struct_field;
-            size_t field_index = type_field->src_index;
-
-            ConstExprValue src_field_val = {0};
-            if (eval_expr(ef, val_field_node->data.struct_val_field.expr, &src_field_val)) return true;
-
-            ConstExprValue *dest_field_val = allocate<ConstExprValue>(1);
-            *dest_field_val = src_field_val;
-
-            out_val->data.x_struct.fields[field_index] = dest_field_val;
-            out_val->depends_on_compile_var = out_val->depends_on_compile_var ||
-                src_field_val.depends_on_compile_var;
-        }
-    } else if (container_type->id == TypeTableEntryIdVoid) {
-        return false;
-    } else if (container_type->id == TypeTableEntryIdStruct &&
-               container_type->data.structure.is_slice &&
-               kind == ContainerInitKindArray)
-    {
-
-        size_t elem_count = container_init_expr->entries.length;
-
-        out_val->ok = true;
-        out_val->data.x_array.fields = allocate<ConstExprValue*>(elem_count);
-
-        for (size_t i = 0; i < elem_count; i += 1) {
-            AstNode *elem_node = container_init_expr->entries.at(i);
-
-            ConstExprValue *elem_val = allocate<ConstExprValue>(1);
-            if (eval_expr(ef, elem_node, elem_val)) return true;
-
-            assert(elem_val->ok);
-
-            out_val->data.x_array.fields[i] = elem_val;
-            out_val->depends_on_compile_var = out_val->depends_on_compile_var ||
-                elem_val->depends_on_compile_var;
-        }
-    } else {
-        zig_panic("TODO init more container kinds");
-    }
-
-
-    return false;
-}
-
-static bool eval_if_bool_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {
-    assert(node->type == NodeTypeIfBoolExpr);
-
-    ConstExprValue cond_val = {0};
-    if (eval_expr(ef, node->data.if_bool_expr.condition, &cond_val)) return true;
-
-    AstNode *exec_node = cond_val.data.x_bool ?
-        node->data.if_bool_expr.then_block : node->data.if_bool_expr.else_node;
-
-    if (exec_node) {
-        if (eval_expr(ef, exec_node, out_val)) return true;
-    }
-    out_val->ok = true;
-    return false;
-}
-
 void eval_const_expr_implicit_cast(CastOp cast_op,
         ConstExprValue *other_val, TypeTableEntry *other_type,
         ConstExprValue *const_val, TypeTableEntry *new_type)
@@ -817,685 +492,3 @@ void eval_min_max_value(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *
         zig_unreachable();
     }
 }
-
-static bool eval_min_max(EvalFn *ef, AstNode *node, ConstExprValue *out_val, bool is_max) {
-    assert(node->type == NodeTypeFnCallExpr);
-    AstNode *type_node = node->data.fn_call_expr.params.at(0);
-    TypeTableEntry *type_entry = resolve_expr_type(type_node);
-    eval_min_max_value(ef->root->codegen, type_entry, out_val, is_max);
-    return false;
-}
-
-static bool eval_div_exact(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {
-    assert(node->type == NodeTypeFnCallExpr);
-    AstNode *op1_node = node->data.fn_call_expr.params.at(0);
-    AstNode *op2_node = node->data.fn_call_expr.params.at(1);
-
-    TypeTableEntry *type_entry = get_resolved_expr(op1_node)->type_entry;
-    assert(type_entry->id == TypeTableEntryIdInt);
-
-    ConstExprValue op1_val = {0};
-    if (eval_expr(ef, op1_node, &op1_val)) return true;
-
-    ConstExprValue op2_val = {0};
-    if (eval_expr(ef, op2_node, &op2_val)) return true;
-
-    if (op2_val.data.x_bignum.data.x_uint == 0) {
-        ErrorMsg *msg = add_node_error(ef->root->codegen, ef->root->fn->fn_def_node,
-                buf_sprintf("function evaluation caused division by zero"));
-        add_error_note(ef->root->codegen, msg, ef->root->call_node, buf_sprintf("called from here"));
-        add_error_note(ef->root->codegen, msg, node, buf_sprintf("division by zero here"));
-        return true;
-    }
-
-    bignum_div(&out_val->data.x_bignum, &op1_val.data.x_bignum, &op2_val.data.x_bignum);
-
-    BigNum orig_bn;
-    bignum_mul(&orig_bn, &out_val->data.x_bignum, &op2_val.data.x_bignum);
-
-    if (bignum_cmp_neq(&orig_bn, &op1_val.data.x_bignum)) {
-        ErrorMsg *msg = add_node_error(ef->root->codegen, ef->root->fn->fn_def_node,
-                buf_sprintf("function evaluation violated exact division"));
-        add_error_note(ef->root->codegen, msg, ef->root->call_node, buf_sprintf("called from here"));
-        add_error_note(ef->root->codegen, msg, node, buf_sprintf("exact division violation here"));
-        return true;
-    }
-
-    out_val->ok = true;
-    out_val->depends_on_compile_var = op1_val.depends_on_compile_var || op2_val.depends_on_compile_var;
-    return false;
-}
-
-static bool eval_unreachable(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {
-    ef->root->abort = true;
-    ErrorMsg *msg = add_node_error(ef->root->codegen, ef->root->fn->fn_def_node,
-            buf_sprintf("function evaluation reached unreachable expression"));
-    add_error_note(ef->root->codegen, msg, ef->root->call_node, buf_sprintf("called from here"));
-    add_error_note(ef->root->codegen, msg, node, buf_sprintf("unreachable expression here"));
-    return true;
-}
-
-static bool eval_fn_with_overflow(EvalFn *ef, AstNode *node, ConstExprValue *out_val,
-    bool (*bignum_fn)(BigNum *dest, BigNum *op1, BigNum *op2))
-{
-    assert(node->type == NodeTypeFnCallExpr);
-
-    AstNode *type_node = node->data.fn_call_expr.params.at(0);
-    TypeTableEntry *int_type = resolve_expr_type(type_node);
-    assert(int_type->id == TypeTableEntryIdInt);
-
-    AstNode *op1_node = node->data.fn_call_expr.params.at(1);
-    AstNode *op2_node = node->data.fn_call_expr.params.at(2);
-    AstNode *result_node = node->data.fn_call_expr.params.at(3);
-
-    ConstExprValue op1_val = {0};
-    if (eval_expr(ef, op1_node, &op1_val)) return true;
-
-    ConstExprValue op2_val = {0};
-    if (eval_expr(ef, op2_node, &op2_val)) return true;
-
-    ConstExprValue result_ptr_val = {0};
-    if (eval_expr(ef, result_node, &result_ptr_val)) return true;
-
-    ConstExprValue *result_val = result_ptr_val.data.x_ptr.ptr[0];
-
-    out_val->ok = true;
-    bool overflow = bignum_fn(&result_val->data.x_bignum, &op1_val.data.x_bignum, &op2_val.data.x_bignum);
-
-    overflow = overflow || !bignum_fits_in_bits(&result_val->data.x_bignum,
-            int_type->data.integral.bit_count, int_type->data.integral.is_signed);
-
-    out_val->data.x_bool = overflow;
-
-    if (overflow) {
-        bignum_truncate(&result_val->data.x_bignum, int_type->data.integral.bit_count);
-    }
-
-    return false;
-}
-
-static bool eval_fn_call_builtin(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {
-    assert(node->type == NodeTypeFnCallExpr);
-
-    BuiltinFnEntry *builtin_fn = node->data.fn_call_expr.builtin_fn;
-    switch (builtin_fn->id) {
-        case BuiltinFnIdMaxValue:
-            return eval_min_max(ef, node, out_val, true);
-        case BuiltinFnIdMinValue:
-            return eval_min_max(ef, node, out_val, false);
-        case BuiltinFnIdMulWithOverflow:
-            return eval_fn_with_overflow(ef, node, out_val, bignum_mul);
-        case BuiltinFnIdAddWithOverflow:
-            return eval_fn_with_overflow(ef, node, out_val, bignum_add);
-        case BuiltinFnIdSubWithOverflow:
-            return eval_fn_with_overflow(ef, node, out_val, bignum_sub);
-        case BuiltinFnIdShlWithOverflow:
-            return eval_fn_with_overflow(ef, node, out_val, bignum_shl);
-        case BuiltinFnIdFence:
-            return false;
-        case BuiltinFnIdDivExact:
-            return eval_div_exact(ef, node, out_val);
-        case BuiltinFnIdUnreachable:
-            return eval_unreachable(ef, node, out_val);
-        case BuiltinFnIdMemcpy:
-        case BuiltinFnIdMemset:
-        case BuiltinFnIdSizeof:
-        case BuiltinFnIdAlignof:
-        case BuiltinFnIdMemberCount:
-        case BuiltinFnIdTypeof:
-        case BuiltinFnIdCInclude:
-        case BuiltinFnIdCDefine:
-        case BuiltinFnIdCUndef:
-        case BuiltinFnIdCompileVar:
-        case BuiltinFnIdConstEval:
-        case BuiltinFnIdCtz:
-        case BuiltinFnIdClz:
-        case BuiltinFnIdImport:
-        case BuiltinFnIdCImport:
-        case BuiltinFnIdErrName:
-        case BuiltinFnIdEmbedFile:
-        case BuiltinFnIdCmpExchange:
-        case BuiltinFnIdTruncate:
-            zig_panic("TODO builtin function");
-        case BuiltinFnIdBreakpoint:
-        case BuiltinFnIdInvalid:
-        case BuiltinFnIdFrameAddress:
-        case BuiltinFnIdReturnAddress:
-        case BuiltinFnIdCompileErr:
-        case BuiltinFnIdIntType:
-            zig_unreachable();
-        case BuiltinFnIdSetFnTest:
-        case BuiltinFnIdSetFnVisible:
-        case BuiltinFnIdSetFnStaticEval:
-        case BuiltinFnIdSetFnNoInline:
-        case BuiltinFnIdSetDebugSafety:
-            return false;
-    }
-
-    return false;
-}
-
-static bool eval_fn_call_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {
-    assert(node->type == NodeTypeFnCallExpr);
-
-    AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
-    CastOp cast_op = node->data.fn_call_expr.cast_op;
-    if (node->data.fn_call_expr.is_builtin) {
-        return eval_fn_call_builtin(ef, node, out_val);
-    } else if (cast_op != CastOpNoCast) {
-        TypeTableEntry *new_type = resolve_expr_type(fn_ref_expr);
-        AstNode *param_node = node->data.fn_call_expr.params.at(0);
-        TypeTableEntry *old_type = get_resolved_expr(param_node)->type_entry;
-        ConstExprValue param_val = {0};
-        if (eval_expr(ef, param_node, &param_val)) return true;
-        eval_const_expr_implicit_cast(cast_op, &param_val, old_type, out_val, new_type);
-        return false;
-    }
-
-    FnTableEntry *fn_table_entry = node->data.fn_call_expr.fn_entry;
-
-    if (fn_ref_expr->type == NodeTypeFieldAccessExpr &&
-        fn_ref_expr->data.field_access_expr.is_member_fn)
-    {
-        zig_panic("TODO field access member fn");
-    }
-
-    if (!fn_table_entry) {
-        ConstExprValue fn_val = {0};
-        if (eval_expr(ef, fn_ref_expr, &fn_val)) return true;
-        fn_table_entry = fn_val.data.x_fn;
-    }
-
-    size_t param_count = node->data.fn_call_expr.params.length;
-    ConstExprValue *args = allocate<ConstExprValue>(param_count);
-    for (size_t call_i = 0; call_i < param_count; call_i += 1) {
-        AstNode *param_expr_node = node->data.fn_call_expr.params.at(call_i);
-        ConstExprValue *param_val = &args[call_i];
-        if (eval_expr(ef, param_expr_node, param_val)) return true;
-    }
-
-    ef->root->branches_used += 1;
-
-    eval_fn_args(ef->root, fn_table_entry, args, out_val);
-    return false;
-}
-
-static bool eval_field_access_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {
-    assert(node->type == NodeTypeFieldAccessExpr);
-
-    AstNode *struct_expr = node->data.field_access_expr.struct_expr;
-    TypeTableEntry *struct_type = get_resolved_expr(struct_expr)->type_entry;
-
-    if (struct_type->id == TypeTableEntryIdArray) {
-        Buf *name = node->data.field_access_expr.field_name;
-        assert(buf_eql_str(name, "len"));
-        zig_panic("TODO field access array");
-    } else if (struct_type->id == TypeTableEntryIdStruct || (struct_type->id == TypeTableEntryIdPointer &&
-               struct_type->data.pointer.child_type->id == TypeTableEntryIdStruct))
-    {
-        TypeStructField *tsf = node->data.field_access_expr.type_struct_field;
-        assert(tsf);
-        if (struct_type->id == TypeTableEntryIdStruct) {
-            ConstExprValue struct_val = {0};
-            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 field access struct");
-        }
-    } else if (struct_type->id == TypeTableEntryIdMetaType) {
-        TypeTableEntry *child_type = resolve_expr_type(struct_expr);
-        if (child_type->id == TypeTableEntryIdPureError) {
-            *out_val = get_resolved_expr(node)->const_val;
-        } else {
-            zig_panic("TODO field access meta type");
-        }
-    } else if (struct_type->id == TypeTableEntryIdNamespace) {
-        zig_panic("TODO field access namespace");
-    } else {
-        zig_unreachable();
-    }
-
-    return false;
-}
-
-static bool eval_for_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {
-    assert(node->type == NodeTypeForExpr);
-
-    AstNode *array_node = node->data.for_expr.array_expr;
-    AstNode *elem_node = node->data.for_expr.elem_node;
-    AstNode *index_node = node->data.for_expr.index_node;
-    AstNode *body_node = node->data.for_expr.body;
-
-    TypeTableEntry *array_type = get_resolved_expr(array_node)->type_entry;
-
-    ConstExprValue array_val = {0};
-    if (eval_expr(ef, array_node, &array_val)) return true;
-
-    assert(elem_node->type == NodeTypeSymbol);
-    Buf *elem_var_name = elem_node->data.symbol_expr.symbol;
-
-    if (node->data.for_expr.elem_is_ptr) {
-        zig_panic("TODO for elem is ptr");
-    }
-
-    Buf *index_var_name = nullptr;
-    if (index_node) {
-        assert(index_node->type == NodeTypeSymbol);
-        index_var_name = index_node->data.symbol_expr.symbol;
-    }
-
-    uint64_t it_index = 0;
-    uint64_t array_len;
-    ConstExprValue **array_ptr_val;
-    if (array_type->id == TypeTableEntryIdArray) {
-        array_len = array_type->data.array.len;
-        array_ptr_val = array_val.data.x_array.fields;
-    } else if (array_type->id == TypeTableEntryIdStruct) {
-        ConstExprValue *len_field_val = array_val.data.x_struct.fields[1];
-        array_len = len_field_val->data.x_bignum.data.x_uint;
-        array_ptr_val = array_val.data.x_struct.fields[0]->data.x_ptr.ptr;
-    } else {
-        zig_unreachable();
-    }
-
-    EvalScope *my_scope = allocate<EvalScope>(1);
-    my_scope->block_context = body_node->block_context;
-    ef->scope_stack.append(my_scope);
-
-    for (; it_index < array_len; it_index += 1) {
-        my_scope->vars.resize(0);
-
-        if (index_var_name) {
-            my_scope->vars.add_one();
-            EvalVar *index_var = &my_scope->vars.last();
-            index_var->name = index_var_name;
-            memset(&index_var->value, 0, sizeof(ConstExprValue));
-            index_var->value.ok = true;
-            bignum_init_unsigned(&index_var->value.data.x_bignum, it_index);
-        }
-        {
-            my_scope->vars.add_one();
-            EvalVar *elem_var = &my_scope->vars.last();
-            elem_var->name = elem_var_name;
-            elem_var->value = *array_ptr_val[it_index];
-        }
-
-        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_array_access_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {
-    assert(node->type == NodeTypeArrayAccessExpr);
-
-    AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr;
-    AstNode *index_node = node->data.array_access_expr.subscript;
-
-    TypeTableEntry *array_type = get_resolved_expr(array_ref_node)->type_entry;
-
-    ConstExprValue array_val = {0};
-    if (eval_expr(ef, array_ref_node, &array_val)) return true;
-
-    ConstExprValue index_val = {0};
-    if (eval_expr(ef, index_node, &index_val)) return true;
-    uint64_t index_int = index_val.data.x_bignum.data.x_uint;
-
-    if (array_type->id == TypeTableEntryIdPointer) {
-        if (index_int >= array_val.data.x_ptr.len) {
-            zig_panic("TODO array access pointer");
-        }
-        *out_val = *array_val.data.x_ptr.ptr[index_int];
-    } else if (array_type->id == TypeTableEntryIdStruct) {
-        assert(array_type->data.structure.is_slice);
-
-        ConstExprValue *len_value = array_val.data.x_struct.fields[1];
-        uint64_t len_int = len_value->data.x_bignum.data.x_uint;
-        if (index_int >= len_int) {
-            zig_panic("TODO array access slice");
-        }
-
-        ConstExprValue *ptr_value = array_val.data.x_struct.fields[0];
-        *out_val = *ptr_value->data.x_ptr.ptr[index_int];
-    } else if (array_type->id == TypeTableEntryIdArray) {
-        uint64_t array_len = array_type->data.array.len;
-        if (index_int >= array_len) {
-            zig_panic("TODO array access array");
-        }
-        *out_val = *array_val.data.x_array.fields[index_int];
-    } else {
-        zig_unreachable();
-    }
-
-    return false;
-}
-
-static bool eval_bool_literal_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {
-    assert(node->type == NodeTypeBoolLiteral);
-
-    out_val->ok = true;
-    out_val->data.x_bool = node->data.bool_literal.value;
-
-    return false;
-}
-
-static bool eval_prefix_op_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {
-    assert(node->type == NodeTypePrefixOpExpr);
-
-    PrefixOp prefix_op = node->data.prefix_op_expr.prefix_op;
-    AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
-
-    ConstExprValue expr_val = {0};
-    if (eval_expr(ef, expr_node, &expr_val)) return true;
-
-    TypeTableEntry *expr_type = get_resolved_expr(expr_node)->type_entry;
-
-    switch (prefix_op) {
-        case PrefixOpBoolNot:
-            *out_val = expr_val;
-            out_val->data.x_bool = !out_val->data.x_bool;
-            break;
-        case PrefixOpDereference:
-            assert(expr_type->id == TypeTableEntryIdPointer);
-            *out_val = *expr_val.data.x_ptr.ptr[0];
-            break;
-        case PrefixOpAddressOf:
-        case PrefixOpConstAddressOf:
-            {
-                ConstExprValue *child_val = allocate<ConstExprValue>(1);
-                *child_val = expr_val;
-
-                ConstExprValue **ptr_val = allocate<ConstExprValue*>(1);
-                *ptr_val = child_val;
-
-                out_val->data.x_ptr.ptr = ptr_val;
-                out_val->data.x_ptr.len = 1;
-                out_val->ok = true;
-                break;
-            }
-        case PrefixOpNegation:
-        case PrefixOpNegationWrap:
-            if (expr_type->id == TypeTableEntryIdInt) {
-                assert(expr_type->data.integral.is_signed);
-                bignum_negate(&out_val->data.x_bignum, &expr_val.data.x_bignum);
-                out_val->ok = true;
-                bool overflow = !bignum_fits_in_bits(&out_val->data.x_bignum,
-                        expr_type->data.integral.bit_count, expr_type->data.integral.is_signed);
-                if (prefix_op == PrefixOpNegationWrap) {
-                    if (overflow) {
-                        out_val->data.x_bignum.is_negative = true;
-                    }
-                } else if (overflow) {
-                    ErrorMsg *msg = add_node_error(ef->root->codegen, ef->root->fn->fn_def_node,
-                            buf_sprintf("function evaluation caused overflow"));
-                    add_error_note(ef->root->codegen, msg, ef->root->call_node, buf_sprintf("called from here"));
-                    add_error_note(ef->root->codegen, msg, node, buf_sprintf("overflow occurred here"));
-                    return true;
-                }
-            } else if (expr_type->id == TypeTableEntryIdFloat) {
-                zig_panic("TODO prefix op on floats");
-            } else {
-                zig_unreachable();
-            }
-            break;
-        case PrefixOpBinNot:
-        case PrefixOpMaybe:
-        case PrefixOpError:
-        case PrefixOpUnwrapError:
-        case PrefixOpUnwrapMaybe:
-            zig_panic("TODO more prefix operations");
-        case PrefixOpInvalid:
-            zig_unreachable();
-    }
-
-    return false;
-}
-
-static bool eval_var_decl_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {
-    assert(node->type == NodeTypeVariableDeclaration);
-
-    assert(node->data.variable_declaration.expr);
-
-    EvalScope *my_scope = ef->scope_stack.at(ef->scope_stack.length - 1);
-
-    my_scope->vars.add_one();
-    EvalVar *var = &my_scope->vars.last();
-    var->name = node->data.variable_declaration.symbol;
-
-    if (eval_expr(ef, node->data.variable_declaration.expr, &var->value)) return true;
-
-    out_val->ok = true;
-
-    return false;
-}
-
-static bool eval_number_literal_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {
-    assert(node->type == NodeTypeNumberLiteral);
-    assert(!node->data.number_literal.overflow);
-
-    out_val->ok = true;
-    bignum_init_bignum(&out_val->data.x_bignum, node->data.number_literal.bignum);
-
-    return false;
-}
-
-static bool eval_char_literal_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {
-    assert(node->type == NodeTypeCharLiteral);
-
-    out_val->ok = true;
-    bignum_init_unsigned(&out_val->data.x_bignum, node->data.char_literal.value);
-
-    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;
-    AstNode *continue_expr_node = node->data.while_expr.continue_expr;
-
-    EvalScope *my_scope = allocate<EvalScope>(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;
-
-        if (continue_expr_node) {
-            ConstExprValue continue_expr_val = {0};
-            if (eval_expr(ef, continue_expr_node, &continue_expr_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);
-        case NodeTypeReturnExpr:
-            return eval_return(ef, node, out);
-        case NodeTypeBinOpExpr:
-            return eval_bin_op_expr(ef, node, out);
-        case NodeTypeSymbol:
-            return eval_symbol_expr(ef, node, out);
-        case NodeTypeContainerInitExpr:
-            return eval_container_init_expr(ef, node, out);
-        case NodeTypeIfBoolExpr:
-            return eval_if_bool_expr(ef, node, out);
-        case NodeTypeFnCallExpr:
-            return eval_fn_call_expr(ef, node, out);
-        case NodeTypeFieldAccessExpr:
-            return eval_field_access_expr(ef, node, out);
-        case NodeTypeForExpr:
-            return eval_for_expr(ef, node, out);
-        case NodeTypeArrayAccessExpr:
-            return eval_array_access_expr(ef, node, out);
-        case NodeTypeBoolLiteral:
-            return eval_bool_literal_expr(ef, node, out);
-        case NodeTypePrefixOpExpr:
-            return eval_prefix_op_expr(ef, node, out);
-        case NodeTypeVariableDeclaration:
-            return eval_var_decl_expr(ef, node, out);
-        case NodeTypeNumberLiteral:
-            return eval_number_literal_expr(ef, node, out);
-        case NodeTypeCharLiteral:
-            return eval_char_literal_expr(ef, node, out);
-        case NodeTypeWhileExpr:
-            return eval_while_expr(ef, node, out);
-        case NodeTypeDefer:
-        case NodeTypeErrorValueDecl:
-        case NodeTypeUnwrapErrorExpr:
-        case NodeTypeStringLiteral:
-        case NodeTypeSliceExpr:
-        case NodeTypeNullLiteral:
-        case NodeTypeUndefinedLiteral:
-        case NodeTypeZeroesLiteral:
-        case NodeTypeThisLiteral:
-        case NodeTypeIfVarExpr:
-        case NodeTypeSwitchExpr:
-        case NodeTypeSwitchProng:
-        case NodeTypeSwitchRange:
-        case NodeTypeLabel:
-        case NodeTypeGoto:
-        case NodeTypeBreak:
-        case NodeTypeContinue:
-        case NodeTypeContainerDecl:
-        case NodeTypeStructField:
-        case NodeTypeStructValueField:
-        case NodeTypeArrayType:
-        case NodeTypeErrorType:
-        case NodeTypeTypeLiteral:
-        case NodeTypeVarLiteral:
-            zig_panic("TODO expr node");
-        case NodeTypeRoot:
-        case NodeTypeFnProto:
-        case NodeTypeFnDef:
-        case NodeTypeFnDecl:
-        case NodeTypeUse:
-        case NodeTypeAsmExpr:
-        case NodeTypeParamDecl:
-        case NodeTypeTypeDecl:
-            zig_unreachable();
-    }
-    zig_unreachable();
-}
-
-static bool eval_fn_args(EvalFnRoot *efr, FnTableEntry *fn, ConstExprValue *args, ConstExprValue *out_val) {
-    AstNode *acting_proto_node;
-    if (fn->proto_node->data.fn_proto.generic_proto_node) {
-        acting_proto_node = fn->proto_node->data.fn_proto.generic_proto_node;
-    } else {
-        acting_proto_node = fn->proto_node;
-    }
-
-    EvalFn ef = {0};
-    ef.root = efr;
-    ef.fn = fn;
-    ef.return_expr = out_val;
-
-    EvalScope *root_scope = allocate<EvalScope>(1);
-    root_scope->block_context = fn->fn_def_node->data.fn_def.body->block_context;
-    ef.scope_stack.append(root_scope);
-
-    size_t param_count = acting_proto_node->data.fn_proto.params.length;
-    for (size_t proto_i = 0; proto_i < param_count; proto_i += 1) {
-        AstNode *decl_param_node = acting_proto_node->data.fn_proto.params.at(proto_i);
-        assert(decl_param_node->type == NodeTypeParamDecl);
-
-        ConstExprValue *src_const_val = &args[proto_i];
-        assert(src_const_val->ok);
-
-        root_scope->vars.add_one();
-        EvalVar *eval_var = &root_scope->vars.last();
-        eval_var->name = decl_param_node->data.param_decl.name;
-        eval_var->value = *src_const_val;
-    }
-
-    return eval_expr(&ef, fn->fn_def_node->data.fn_def.body, out_val);
-}
-
-bool eval_fn(CodeGen *g, AstNode *node, FnTableEntry *fn, ConstExprValue *out_val,
-        size_t branch_quota, AstNode *struct_node)
-{
-    assert(node->type == NodeTypeFnCallExpr);
-
-    EvalFnRoot efr = {0};
-    efr.codegen = g;
-    efr.fn = fn;
-    efr.call_node = node;
-    efr.branch_quota = branch_quota;
-
-    AstNode *acting_proto_node;
-    if (fn->proto_node->data.fn_proto.generic_proto_node) {
-        acting_proto_node = fn->proto_node->data.fn_proto.generic_proto_node;
-    } else {
-        acting_proto_node = fn->proto_node;
-    }
-
-    size_t call_param_count = node->data.fn_call_expr.params.length;
-    size_t proto_param_count = acting_proto_node->data.fn_proto.params.length;
-    ConstExprValue *args = allocate<ConstExprValue>(proto_param_count);
-    size_t next_arg_index = 0;
-    if (struct_node) {
-        ConstExprValue *struct_val = &get_resolved_expr(struct_node)->const_val;
-        assert(struct_val->ok);
-        args[next_arg_index] = *struct_val;
-        next_arg_index += 1;
-    }
-    for (size_t call_index = 0; call_index < call_param_count; call_index += 1) {
-        AstNode *call_param_node = node->data.fn_call_expr.params.at(call_index);
-        ConstExprValue *src_const_val = &get_resolved_expr(call_param_node)->const_val;
-        assert(src_const_val->ok);
-        args[next_arg_index] = *src_const_val;
-        next_arg_index += 1;
-    }
-    eval_fn_args(&efr, fn, args, out_val);
-
-    if (efr.exceeded_quota_node) {
-        ErrorMsg *msg = add_node_error(g, fn->fn_def_node,
-                buf_sprintf("function evaluation exceeded %zu branches", efr.branch_quota));
-
-        add_error_note(g, msg, efr.call_node, buf_sprintf("called from here"));
-        add_error_note(g, msg, efr.exceeded_quota_node, buf_sprintf("quota exceeded here"));
-        return true;
-    }
-
-    if (efr.abort) {
-        return true;
-    }
-
-    assert(out_val->ok);
-    return false;
-}
-
src/eval.hpp
@@ -10,9 +10,6 @@
 
 #include "all_types.hpp"
 
-bool eval_fn(CodeGen *g, AstNode *node, FnTableEntry *fn, ConstExprValue *out_val, size_t branch_quota,
-        AstNode *struct_node);
-
 bool const_values_equal(ConstExprValue *a, ConstExprValue *b, TypeTableEntry *type_entry);
 int eval_const_expr_bin_op(ConstExprValue *op1_val, TypeTableEntry *op1_type,
         BinOpType bin_op, ConstExprValue *op2_val, TypeTableEntry *op2_type, ConstExprValue *out_val);