aboutsummaryrefslogtreecommitdiff
path: root/src/eval.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/eval.cpp')
-rw-r--r--src/eval.cpp429
1 files changed, 0 insertions, 429 deletions
diff --git a/src/eval.cpp b/src/eval.cpp
deleted file mode 100644
index c1a8bc604b..0000000000
--- a/src/eval.cpp
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
- * Copyright (c) 2016 Andrew Kelley
- *
- * This file is part of zig, which is MIT licensed.
- * See http://opensource.org/licenses/MIT
- */
-
-#include "eval.hpp"
-#include "analyze.hpp"
-#include "error.hpp"
-
-bool const_values_equal(ConstExprValue *a, ConstExprValue *b, TypeTableEntry *type_entry) {
- switch (type_entry->id) {
- case TypeTableEntryIdEnum:
- {
- ConstEnumValue *enum1 = &a->data.x_enum;
- ConstEnumValue *enum2 = &b->data.x_enum;
- if (enum1->tag == enum2->tag) {
- TypeEnumField *enum_field = &type_entry->data.enumeration.fields[enum1->tag];
- if (type_has_bits(enum_field->type_entry)) {
- zig_panic("TODO const expr analyze enum special value for equality");
- } else {
- return true;
- }
- }
- return false;
- }
- case TypeTableEntryIdMetaType:
- return a->data.x_type == b->data.x_type;
- case TypeTableEntryIdVoid:
- return true;
- case TypeTableEntryIdPureError:
- return a->data.x_pure_err == b->data.x_pure_err;
- case TypeTableEntryIdFn:
- return a->data.x_fn == b->data.x_fn;
- case TypeTableEntryIdBool:
- return a->data.x_bool == b->data.x_bool;
- case TypeTableEntryIdInt:
- case TypeTableEntryIdFloat:
- case TypeTableEntryIdNumLitFloat:
- case TypeTableEntryIdNumLitInt:
- return bignum_cmp_eq(&a->data.x_bignum, &b->data.x_bignum);
- case TypeTableEntryIdPointer:
- zig_panic("TODO");
- case TypeTableEntryIdArray:
- zig_panic("TODO");
- case TypeTableEntryIdStruct:
- zig_panic("TODO");
- case TypeTableEntryIdUnion:
- zig_panic("TODO");
- case TypeTableEntryIdUndefLit:
- zig_panic("TODO");
- case TypeTableEntryIdNullLit:
- zig_panic("TODO");
- case TypeTableEntryIdMaybe:
- zig_panic("TODO");
- case TypeTableEntryIdErrorUnion:
- zig_panic("TODO");
- case TypeTableEntryIdTypeDecl:
- zig_panic("TODO");
- case TypeTableEntryIdNamespace:
- zig_panic("TODO");
- case TypeTableEntryIdBlock:
- zig_panic("TODO");
- case TypeTableEntryIdBoundFn:
- case TypeTableEntryIdInvalid:
- case TypeTableEntryIdUnreachable:
- case TypeTableEntryIdVar:
- zig_unreachable();
- }
- zig_unreachable();
-}
-
-
-static bool eval_bool_bin_op_bool(bool a, BinOpType bin_op, bool b) {
- if (bin_op == BinOpTypeBoolOr || bin_op == BinOpTypeAssignBoolOr) {
- return a || b;
- } else if (bin_op == BinOpTypeBoolAnd || bin_op == BinOpTypeAssignBoolAnd) {
- return a && b;
- } else {
- zig_unreachable();
- }
-}
-
-static uint64_t max_unsigned_val(TypeTableEntry *type_entry) {
- assert(type_entry->id == TypeTableEntryIdInt);
- if (type_entry->data.integral.bit_count == 64) {
- return UINT64_MAX;
- } else if (type_entry->data.integral.bit_count == 32) {
- return UINT32_MAX;
- } else if (type_entry->data.integral.bit_count == 16) {
- return UINT16_MAX;
- } else if (type_entry->data.integral.bit_count == 8) {
- return UINT8_MAX;
- } else {
- zig_unreachable();
- }
-}
-
-static int64_t max_signed_val(TypeTableEntry *type_entry) {
- assert(type_entry->id == TypeTableEntryIdInt);
- if (type_entry->data.integral.bit_count == 64) {
- return INT64_MAX;
- } else if (type_entry->data.integral.bit_count == 32) {
- return INT32_MAX;
- } else if (type_entry->data.integral.bit_count == 16) {
- return INT16_MAX;
- } else if (type_entry->data.integral.bit_count == 8) {
- return INT8_MAX;
- } else {
- zig_unreachable();
- }
-}
-
-static int64_t min_signed_val(TypeTableEntry *type_entry) {
- assert(type_entry->id == TypeTableEntryIdInt);
- if (type_entry->data.integral.bit_count == 64) {
- return INT64_MIN;
- } else if (type_entry->data.integral.bit_count == 32) {
- return INT32_MIN;
- } else if (type_entry->data.integral.bit_count == 16) {
- return INT16_MIN;
- } else if (type_entry->data.integral.bit_count == 8) {
- return INT8_MIN;
- } else {
- zig_unreachable();
- }
-}
-
-static int eval_const_expr_bin_op_bignum(ConstExprValue *op1_val, ConstExprValue *op2_val,
- ConstExprValue *out_val, bool (*bignum_fn)(BigNum *, BigNum *, BigNum *),
- TypeTableEntry *type, bool wrapping_op)
-{
- bool overflow = bignum_fn(&out_val->data.x_bignum, &op1_val->data.x_bignum, &op2_val->data.x_bignum);
- if (overflow) {
- return ErrorOverflow;
- }
-
- if (type->id == TypeTableEntryIdInt && !bignum_fits_in_bits(&out_val->data.x_bignum,
- type->data.integral.bit_count, type->data.integral.is_signed))
- {
- if (wrapping_op) {
- if (type->data.integral.is_signed) {
- out_val->data.x_bignum.data.x_uint = max_unsigned_val(type) - out_val->data.x_bignum.data.x_uint + 1;
- out_val->data.x_bignum.is_negative = !out_val->data.x_bignum.is_negative;
- } else if (out_val->data.x_bignum.is_negative) {
- out_val->data.x_bignum.data.x_uint = max_unsigned_val(type) - out_val->data.x_bignum.data.x_uint + 1;
- out_val->data.x_bignum.is_negative = false;
- } else {
- bignum_truncate(&out_val->data.x_bignum, type->data.integral.bit_count);
- }
- } else {
- return ErrorOverflow;
- }
- }
-
- out_val->special = ConstValSpecialStatic;
- out_val->depends_on_compile_var = op1_val->depends_on_compile_var || op2_val->depends_on_compile_var;
- return 0;
-}
-
-int eval_const_expr_bin_op(ConstExprValue *op1_val, TypeTableEntry *op1_type,
- BinOpType bin_op, ConstExprValue *op2_val, TypeTableEntry *op2_type, ConstExprValue *out_val)
-{
- assert(op1_val->special != ConstValSpecialRuntime);
- assert(op2_val->special != ConstValSpecialRuntime);
- assert(op1_type->id != TypeTableEntryIdInvalid);
- assert(op2_type->id != TypeTableEntryIdInvalid);
-
- switch (bin_op) {
- case BinOpTypeAssign:
- *out_val = *op2_val;
- return 0;
- case BinOpTypeBoolOr:
- case BinOpTypeBoolAnd:
- case BinOpTypeAssignBoolAnd:
- case BinOpTypeAssignBoolOr:
- assert(op1_type->id == TypeTableEntryIdBool);
- assert(op2_type->id == TypeTableEntryIdBool);
- out_val->data.x_bool = eval_bool_bin_op_bool(op1_val->data.x_bool, bin_op, op2_val->data.x_bool);
- out_val->special = ConstValSpecialStatic;
- out_val->depends_on_compile_var = op1_val->depends_on_compile_var || op2_val->depends_on_compile_var;
- return 0;
- case BinOpTypeCmpEq:
- case BinOpTypeCmpNotEq:
- case BinOpTypeCmpLessThan:
- case BinOpTypeCmpGreaterThan:
- case BinOpTypeCmpLessOrEq:
- case BinOpTypeCmpGreaterOrEq:
- {
- bool type_can_gt_lt_cmp = (op1_type->id == TypeTableEntryIdNumLitFloat ||
- op1_type->id == TypeTableEntryIdNumLitInt ||
- op1_type->id == TypeTableEntryIdFloat ||
- op1_type->id == TypeTableEntryIdInt);
- bool answer;
- if (type_can_gt_lt_cmp) {
- bool (*bignum_cmp)(BigNum *, BigNum *);
- if (bin_op == BinOpTypeCmpEq) {
- bignum_cmp = bignum_cmp_eq;
- } else if (bin_op == BinOpTypeCmpNotEq) {
- bignum_cmp = bignum_cmp_neq;
- } else if (bin_op == BinOpTypeCmpLessThan) {
- bignum_cmp = bignum_cmp_lt;
- } else if (bin_op == BinOpTypeCmpGreaterThan) {
- bignum_cmp = bignum_cmp_gt;
- } else if (bin_op == BinOpTypeCmpLessOrEq) {
- bignum_cmp = bignum_cmp_lte;
- } else if (bin_op == BinOpTypeCmpGreaterOrEq) {
- bignum_cmp = bignum_cmp_gte;
- } else {
- zig_unreachable();
- }
-
- answer = bignum_cmp(&op1_val->data.x_bignum, &op2_val->data.x_bignum);
- } else {
- bool are_equal = const_values_equal(op1_val, op2_val, op1_type);
- if (bin_op == BinOpTypeCmpEq) {
- answer = are_equal;
- } else if (bin_op == BinOpTypeCmpNotEq) {
- answer = !are_equal;
- } else {
- zig_unreachable();
- }
- }
-
- out_val->depends_on_compile_var =
- op1_val->depends_on_compile_var || op2_val->depends_on_compile_var;
- out_val->data.x_bool = answer;
- out_val->special = ConstValSpecialStatic;
- return 0;
- }
- case BinOpTypeAdd:
- case BinOpTypeAssignPlus:
- return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_add, op1_type, false);
- case BinOpTypeAddWrap:
- case BinOpTypeAssignPlusWrap:
- return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_add, op1_type, true);
- case BinOpTypeBinOr:
- case BinOpTypeAssignBitOr:
- return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_or, op1_type, false);
- case BinOpTypeBinXor:
- case BinOpTypeAssignBitXor:
- return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_xor, op1_type, false);
- case BinOpTypeBinAnd:
- case BinOpTypeAssignBitAnd:
- return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_and, op1_type, false);
- case BinOpTypeBitShiftLeft:
- case BinOpTypeAssignBitShiftLeft:
- return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_shl, op1_type, false);
- case BinOpTypeBitShiftLeftWrap:
- case BinOpTypeAssignBitShiftLeftWrap:
- return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_shl, op1_type, true);
- case BinOpTypeBitShiftRight:
- case BinOpTypeAssignBitShiftRight:
- return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_shr, op1_type, false);
- case BinOpTypeSub:
- case BinOpTypeAssignMinus:
- return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_sub, op1_type, false);
- case BinOpTypeSubWrap:
- case BinOpTypeAssignMinusWrap:
- return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_sub, op1_type, true);
- case BinOpTypeMult:
- case BinOpTypeAssignTimes:
- return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_mul, op1_type, false);
- case BinOpTypeMultWrap:
- case BinOpTypeAssignTimesWrap:
- return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_mul, op1_type, true);
- case BinOpTypeDiv:
- case BinOpTypeAssignDiv:
- {
- bool is_int = false;
- bool is_float = false;
- if (op1_type->id == TypeTableEntryIdInt ||
- op1_type->id == TypeTableEntryIdNumLitInt)
- {
- is_int = true;
- } else if (op1_type->id == TypeTableEntryIdFloat ||
- op1_type->id == TypeTableEntryIdNumLitFloat)
- {
- is_float = true;
- }
- if ((is_int && op2_val->data.x_bignum.data.x_uint == 0) ||
- (is_float && op2_val->data.x_bignum.data.x_float == 0.0))
- {
- return ErrorDivByZero;
- } else {
- return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_div, op1_type, false);
- }
- }
- case BinOpTypeMod:
- case BinOpTypeAssignMod:
- return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_mod, op1_type, false);
- case BinOpTypeUnwrapMaybe:
- zig_panic("TODO");
- case BinOpTypeArrayCat:
- case BinOpTypeArrayMult:
- case BinOpTypeInvalid:
- zig_unreachable();
- }
- zig_unreachable();
-}
-
-void eval_const_expr_implicit_cast(CastOp cast_op,
- ConstExprValue *other_val, TypeTableEntry *other_type,
- ConstExprValue *const_val, TypeTableEntry *new_type)
-{
- const_val->depends_on_compile_var = other_val->depends_on_compile_var;
- const_val->special = other_val->special;
-
- assert(other_val != const_val);
- switch (cast_op) {
- case CastOpNoCast:
- zig_unreachable();
- case CastOpNoop:
- case CastOpWidenOrShorten:
- *const_val = *other_val;
- break;
- case CastOpPointerReinterpret:
- zig_panic("TODO compile time pointer reinterpret");
- break;
- case CastOpPtrToInt:
- case CastOpIntToPtr:
- case CastOpResizeSlice:
- case CastOpBytesToSlice:
- // can't do it
- break;
- case CastOpToUnknownSizeArray:
- {
- assert(other_type->id == TypeTableEntryIdArray);
- assert(other_val->data.x_array.size == other_type->data.array.len);
-
- const_val->data.x_struct.fields = allocate<ConstExprValue>(2);
- ConstExprValue *ptr_field = &const_val->data.x_struct.fields[slice_ptr_index];
- ConstExprValue *len_field = &const_val->data.x_struct.fields[slice_len_index];
-
- ptr_field->special = ConstValSpecialStatic;
- ptr_field->data.x_ptr.base_ptr = other_val;
-
- len_field->special = ConstValSpecialStatic;
- bignum_init_unsigned(&len_field->data.x_bignum, other_type->data.array.len);
-
- const_val->special = ConstValSpecialStatic;
- break;
- }
- case CastOpErrToInt:
- {
- uint64_t value;
- if (other_type->id == TypeTableEntryIdErrorUnion) {
- value = other_val->data.x_err_union.err ? other_val->data.x_err_union.err->value : 0;
- } else if (other_type->id == TypeTableEntryIdPureError) {
- value = other_val->data.x_pure_err->value;
- } else {
- zig_unreachable();
- }
- bignum_init_unsigned(&const_val->data.x_bignum, value);
- const_val->special = ConstValSpecialStatic;
- break;
- }
- case CastOpIntToFloat:
- bignum_cast_to_float(&const_val->data.x_bignum, &other_val->data.x_bignum);
- const_val->special = ConstValSpecialStatic;
- break;
- case CastOpFloatToInt:
- bignum_cast_to_int(&const_val->data.x_bignum, &other_val->data.x_bignum);
- const_val->special = ConstValSpecialStatic;
- break;
- case CastOpBoolToInt:
- bignum_init_unsigned(&const_val->data.x_bignum, other_val->data.x_bool ? 1 : 0);
- const_val->special = ConstValSpecialStatic;
- break;
- case CastOpIntToEnum:
- {
- uint64_t value = other_val->data.x_bignum.data.x_uint;
- assert(new_type->id == TypeTableEntryIdEnum);
- assert(value < new_type->data.enumeration.src_field_count);
- const_val->data.x_enum.tag = value;
- const_val->data.x_enum.payload = NULL;
- const_val->special = ConstValSpecialStatic;
- break;
- }
- case CastOpEnumToInt:
- bignum_init_unsigned(&const_val->data.x_bignum, other_val->data.x_enum.tag);
- const_val->special = ConstValSpecialStatic;
- break;
- }
-}
-
-static bool int_type_depends_on_compile_var(CodeGen *g, TypeTableEntry *int_type) {
- assert(int_type->id == TypeTableEntryIdInt);
-
- for (size_t i = 0; i < CIntTypeCount; i += 1) {
- if (int_type == g->builtin_types.entry_c_int[i]) {
- return true;
- }
- }
- return false;
-}
-
-void eval_min_max_value(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val, bool is_max) {
- if (type_entry->id == TypeTableEntryIdInt) {
- const_val->special = ConstValSpecialStatic;
- const_val->depends_on_compile_var = int_type_depends_on_compile_var(g, type_entry);
- if (is_max) {
- if (type_entry->data.integral.is_signed) {
- int64_t val = max_signed_val(type_entry);
- bignum_init_signed(&const_val->data.x_bignum, val);
- } else {
- uint64_t val = max_unsigned_val(type_entry);
- bignum_init_unsigned(&const_val->data.x_bignum, val);
- }
- } else {
- if (type_entry->data.integral.is_signed) {
- int64_t val = min_signed_val(type_entry);
- bignum_init_signed(&const_val->data.x_bignum, val);
- } else {
- bignum_init_unsigned(&const_val->data.x_bignum, 0);
- }
- }
- } else if (type_entry->id == TypeTableEntryIdFloat) {
- zig_panic("TODO analyze_min_max_value float");
- } else if (type_entry->id == TypeTableEntryIdBool) {
- const_val->special = ConstValSpecialStatic;
- const_val->data.x_bool = is_max;
- } else if (type_entry->id == TypeTableEntryIdVoid) {
- // nothing to do
- } else {
- zig_unreachable();
- }
-}