aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2016-01-04 23:37:17 -0700
committerAndrew Kelley <superjoe30@gmail.com>2016-01-04 23:37:17 -0700
commita11d0aaf62e3ebf2f46307d1546b8105792c8dd0 (patch)
tree3dc29343eb5eefa115047b49bf1be23f484aa12c /src
parent3c551628268e88c6d6dcbe729e1bc756a689dbda (diff)
downloadzig-a11d0aaf62e3ebf2f46307d1546b8105792c8dd0.tar.gz
zig-a11d0aaf62e3ebf2f46307d1546b8105792c8dd0.zip
progress toward compile time constant expression evaluation
Diffstat (limited to 'src')
-rw-r--r--src/analyze.cpp49
-rw-r--r--src/codegen.cpp4
-rw-r--r--src/parser.cpp20
-rw-r--r--src/parser.hpp5
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;
};