diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2016-01-04 23:37:17 -0700 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2016-01-04 23:37:17 -0700 |
| commit | a11d0aaf62e3ebf2f46307d1546b8105792c8dd0 (patch) | |
| tree | 3dc29343eb5eefa115047b49bf1be23f484aa12c /src | |
| parent | 3c551628268e88c6d6dcbe729e1bc756a689dbda (diff) | |
| download | zig-a11d0aaf62e3ebf2f46307d1546b8105792c8dd0.tar.gz zig-a11d0aaf62e3ebf2f46307d1546b8105792c8dd0.zip | |
progress toward compile time constant expression evaluation
Diffstat (limited to 'src')
| -rw-r--r-- | src/analyze.cpp | 49 | ||||
| -rw-r--r-- | src/codegen.cpp | 4 | ||||
| -rw-r--r-- | src/parser.cpp | 20 | ||||
| -rw-r--r-- | src/parser.hpp | 5 |
4 files changed, 72 insertions, 6 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp index c62fb9cec6..27772f6ef1 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -233,6 +233,30 @@ static TypeTableEntry *get_array_type(CodeGen *g, ImportTableEntry *import, } } +static TypeTableEntry *eval_const_expr(CodeGen *g, BlockContext *context, + AstNode *node, AstNodeNumberLiteral *out_number_literal) +{ + switch (node->type) { + case NodeTypeNumberLiteral: + *out_number_literal = node->data.number_literal; + return node->codegen_node->expr_node.type_entry; + case NodeTypeBinOpExpr: + zig_panic("TODO eval_const_expr bin op expr"); + break; + case NodeTypeSymbol: + { + VariableTableEntry *var = find_variable(context, &node->data.symbol); + assert(var); + AstNode *decl_node = var->decl_node; + AstNode *expr_node = decl_node->data.variable_declaration.expr; + BlockContext *next_context = expr_node->codegen_node->expr_node.block_context; + return eval_const_expr(g, next_context, expr_node, out_number_literal); + } + default: + return g->builtin_types.entry_invalid; + } +} + static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node, ImportTableEntry *import, BlockContext *context) { assert(node->type == NodeTypeType); alloc_codegen_node(node); @@ -275,14 +299,27 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node, ImportTableEntry } AstNode *size_node = node->data.type.array_size; - if (size_node->type == NodeTypeNumberLiteral && - is_num_lit_unsigned(size_node->data.number_literal.kind)) - { - type_node->entry = get_array_type(g, import, child_type, - size_node->data.number_literal.data.x_uint); + TypeTableEntry *size_type = analyze_expression(g, import, context, + g->builtin_types.entry_usize, size_node); + if (size_type->id == TypeTableEntryIdInvalid) { + type_node->entry = g->builtin_types.entry_invalid; + return type_node->entry; + } + + AstNodeNumberLiteral number_literal; + TypeTableEntry *resolved_type = eval_const_expr(g, context, size_node, &number_literal); + + if (resolved_type->id == TypeTableEntryIdInt) { + if (resolved_type->data.integral.is_signed) { + add_node_error(g, size_node, + buf_create_from_str("array size must be unsigned integer")); + type_node->entry = g->builtin_types.entry_invalid; + } else { + type_node->entry = get_array_type(g, import, child_type, number_literal.data.x_uint); + } } else { add_node_error(g, size_node, - buf_create_from_str("array size must be literal unsigned integer")); + buf_create_from_str("unable to resolve constant expression")); type_node->entry = g->builtin_types.entry_invalid; } return type_node->entry; diff --git a/src/codegen.cpp b/src/codegen.cpp index 32c34e6323..bc9462ae99 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1696,6 +1696,10 @@ static const NumLit num_lit_kinds[] = { NumLitU16, NumLitU32, NumLitU64, + NumLitI8, + NumLitI16, + NumLitI32, + NumLitI64, }; static void define_builtin_types(CodeGen *g) { diff --git a/src/parser.cpp b/src/parser.cpp index 5c9d34a3c4..60de2fbab7 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -2750,6 +2750,14 @@ const char *num_lit_str(NumLit num_lit) { return "u32"; case NumLitU64: return "u64"; + case NumLitI8: + return "i8"; + case NumLitI16: + return "i16"; + case NumLitI32: + return "i32"; + case NumLitI64: + return "i64"; case NumLitCount: zig_unreachable(); } @@ -2761,6 +2769,10 @@ bool is_num_lit_unsigned(NumLit num_lit) { case NumLitF32: case NumLitF64: case NumLitF128: + case NumLitI8: + case NumLitI16: + case NumLitI32: + case NumLitI64: return false; case NumLitU8: case NumLitU16: @@ -2783,6 +2795,10 @@ bool is_num_lit_float(NumLit num_lit) { case NumLitU16: case NumLitU32: case NumLitU64: + case NumLitI8: + case NumLitI16: + case NumLitI32: + case NumLitI64: return false; case NumLitCount: zig_unreachable(); @@ -2793,13 +2809,17 @@ bool is_num_lit_float(NumLit num_lit) { uint64_t num_lit_bit_count(NumLit num_lit) { switch (num_lit) { case NumLitU8: + case NumLitI8: return 8; case NumLitU16: + case NumLitI16: return 16; case NumLitU32: + case NumLitI32: case NumLitF32: return 32; case NumLitU64: + case NumLitI64: case NumLitF64: return 64; case NumLitF128: diff --git a/src/parser.hpp b/src/parser.hpp index 5585a94495..52cbf3e37d 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -309,6 +309,10 @@ enum NumLit { NumLitU16, NumLitU32, NumLitU64, + NumLitI8, + NumLitI16, + NumLitI32, + NumLitI64, NumLitCount }; @@ -322,6 +326,7 @@ struct AstNodeNumberLiteral { union { uint64_t x_uint; + int64_t x_int; double x_float; } data; }; |
