enum init uses container init syntax instead of fn call

See #5
master
Andrew Kelley 2016-04-19 18:52:09 -07:00
parent 7a7f83033c
commit 36c6acfc76
5 changed files with 69 additions and 50 deletions

View File

@ -392,7 +392,6 @@ struct AstNodeFnCallExpr {
Expr resolved_expr;
FnTableEntry *fn_entry;
CastOp cast_op;
TypeTableEntry *enum_type;
// if cast_op is CastOpArrayToString, this will be a pointer to
// the string struct on the stack
LLVMValueRef tmp_ptr;
@ -429,6 +428,7 @@ struct AstNodeFieldAccessExpr {
bool is_fn_call;
TypeTableEntry *bare_struct_type;
bool is_member_fn;
AstNode *container_init_expr_node;
};
struct AstNodeDirective {
@ -665,6 +665,7 @@ struct AstNodeContainerInitExpr {
// populated by semantic analyzer
StructValExprCodeGen resolved_struct_val_expr;
Expr resolved_expr;
TypeTableEntry *enum_type;
};
struct AstNodeNullLiteral {

View File

@ -2197,7 +2197,23 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry
ContainerInitKind kind = container_init_expr->kind;
TypeTableEntry *container_type = analyze_type_expr(g, import, context, container_init_expr->type);
if (container_init_expr->type->type == NodeTypeFieldAccessExpr) {
container_init_expr->type->data.field_access_expr.container_init_expr_node = node;
}
TypeTableEntry *container_meta_type = analyze_expression(g, import, context, nullptr,
container_init_expr->type);
if (container_meta_type->id == TypeTableEntryIdInvalid) {
return g->builtin_types.entry_invalid;
}
if (node->data.container_init_expr.enum_type) {
get_resolved_expr(node)->const_val = get_resolved_expr(container_init_expr->type)->const_val;
return node->data.container_init_expr.enum_type;
}
TypeTableEntry *container_type = resolve_type(g, container_init_expr->type);
if (container_type->id == TypeTableEntryIdInvalid) {
return container_type;
@ -2322,9 +2338,6 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry
} else if (container_type->id == TypeTableEntryIdArray) {
zig_panic("TODO array container init");
return container_type;
} else if (container_type->id == TypeTableEntryIdEnum) {
zig_panic("TODO enum container init");
return container_type;
} else if (container_type->id == TypeTableEntryIdVoid) {
if (container_init_expr->entries.length != 0) {
add_node_error(g, node, buf_sprintf("void expression expects no arguments"));
@ -2414,7 +2427,28 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
} else if (wrapped_in_fn_call) {
return resolve_expr_const_val_as_type(g, node, child_type);
} else if (child_type->id == TypeTableEntryIdEnum) {
return analyze_enum_value_expr(g, import, context, node, nullptr, child_type, field_name, node);
AstNode *container_init_node = node->data.field_access_expr.container_init_expr_node;
AstNode *value_node;
if (container_init_node) {
assert(container_init_node->type == NodeTypeContainerInitExpr);
int param_count = container_init_node->data.container_init_expr.entries.length;
if (param_count > 1) {
AstNode *first_invalid_node = container_init_node->data.container_init_expr.entries.at(1);
add_node_error(g, first_executing_node(first_invalid_node),
buf_sprintf("enum values accept only one parameter"));
return child_type;
} else {
if (param_count == 1) {
value_node = container_init_node->data.container_init_expr.entries.at(0);
} else {
value_node = nullptr;
}
container_init_node->data.container_init_expr.enum_type = child_type;
}
} else {
value_node = nullptr;
}
return analyze_enum_value_expr(g, import, context, node, value_node, child_type, field_name, node);
} else if (child_type->id == TypeTableEntryIdStruct) {
BlockContext *container_block_context = get_container_block_context(child_type);
auto entry = container_block_context->decl_table.maybe_get(field_name);
@ -4725,26 +4759,6 @@ static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import
if (child_type->id == TypeTableEntryIdInvalid) {
return g->builtin_types.entry_invalid;
} else if (child_type->id == TypeTableEntryIdEnum) {
Buf *field_name = &fn_ref_expr->data.field_access_expr.field_name;
int param_count = node->data.fn_call_expr.params.length;
if (param_count > 1) {
add_node_error(g, first_executing_node(node->data.fn_call_expr.params.at(1)),
buf_sprintf("enum values accept only one parameter"));
return child_type;
} else {
AstNode *value_node;
if (param_count == 1) {
value_node = node->data.fn_call_expr.params.at(0);
} else {
value_node = nullptr;
}
node->data.fn_call_expr.enum_type = child_type;
return analyze_enum_value_expr(g, import, context, fn_ref_expr, value_node,
child_type, field_name, node);
}
} else if (child_type->id == TypeTableEntryIdStruct) {
Buf *field_name = &fn_ref_expr->data.field_access_expr.field_name;
BlockContext *container_block_context = get_container_block_context(child_type);

View File

@ -764,23 +764,11 @@ static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) {
return gen_cast_expr(g, node);
}
AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
if (node->data.fn_call_expr.enum_type) {
int param_count = node->data.fn_call_expr.params.length;
AstNode *arg1_node;
if (param_count == 1) {
arg1_node = node->data.fn_call_expr.params.at(0);
} else {
assert(param_count == 0);
arg1_node = nullptr;
}
return gen_enum_value_expr(g, fn_ref_expr, node->data.fn_call_expr.enum_type, arg1_node);
}
FnTableEntry *fn_table_entry = node->data.fn_call_expr.fn_entry;
TypeTableEntry *struct_type = nullptr;
AstNode *first_param_expr = nullptr;
AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
if (fn_ref_expr->type == NodeTypeFieldAccessExpr &&
fn_ref_expr->data.field_access_expr.is_member_fn)
{
@ -2207,6 +2195,21 @@ static LLVMValueRef gen_container_init_expr(CodeGen *g, AstNode *node) {
TypeTableEntry *type_entry = get_expr_type(node);
if (node->data.container_init_expr.enum_type) {
int param_count = node->data.container_init_expr.entries.length;
AstNode *arg1_node;
if (param_count == 1) {
arg1_node = node->data.container_init_expr.entries.at(0);
} else {
assert(param_count == 0);
arg1_node = nullptr;
}
return gen_enum_value_expr(g, node->data.container_init_expr.type,
node->data.container_init_expr.enum_type, arg1_node);
}
if (type_entry->id == TypeTableEntryIdStruct) {
assert(node->data.container_init_expr.kind == ContainerInitKindStruct);

View File

@ -320,6 +320,11 @@ static bool eval_container_init_expr(EvalFn *ef, AstNode *node, ConstExprValue *
AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr;
ContainerInitKind kind = container_init_expr->kind;
if (container_init_expr->enum_type) {
zig_panic("TODO");
}
TypeTableEntry *container_type = resolve_expr_type(container_init_expr->type);
out_val->ok = true;
@ -723,10 +728,6 @@ static bool eval_fn_call_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val
return false;
}
if (node->data.fn_call_expr.enum_type) {
zig_panic("TODO");
}
FnTableEntry *fn_table_entry = node->data.fn_call_expr.fn_entry;
if (fn_ref_expr->type == NodeTypeFieldAccessExpr &&

View File

@ -353,8 +353,8 @@ fn maybe_type() {
#attribute("test")
fn enum_type() {
const foo1 = EnumTypeFoo.One(13);
const foo2 = EnumTypeFoo.Two(EnumType { .x = 1234, .y = 5678, });
const foo1 = EnumTypeFoo.One {13};
const foo2 = EnumTypeFoo.Two {EnumType { .x = 1234, .y = 5678, }};
const bar = EnumTypeBar.B;
assert(bar == EnumTypeBar.B);
@ -449,7 +449,7 @@ fn should_be_not_equal(a: error, b: error) {
#attribute("test")
fn constant_enum_with_payload() {
var empty = AnEnumWithPayload.Empty;
var full = AnEnumWithPayload.Full(13);
var full = AnEnumWithPayload.Full {13};
should_be_empty(empty);
should_be_not_empty(full);
}
@ -547,8 +547,8 @@ enum SwitchStatmentFoo {
#attribute("test")
fn switch_prong_with_var() {
switch_prong_with_var_fn(SwitchProngWithVarEnum.One(13));
switch_prong_with_var_fn(SwitchProngWithVarEnum.Two(13.0));
switch_prong_with_var_fn(SwitchProngWithVarEnum.One {13});
switch_prong_with_var_fn(SwitchProngWithVarEnum.Two {13.0});
switch_prong_with_var_fn(SwitchProngWithVarEnum.Meh);
}
enum SwitchProngWithVarEnum {
@ -1221,8 +1221,8 @@ struct Test3Point {
x: i32,
y: i32,
}
const test3_foo = Test3Foo.Three(Test3Point {.x = 3, .y = 4});
const test3_bar = Test3Foo.Two(13);
const test3_foo = Test3Foo.Three{Test3Point {.x = 3, .y = 4}};
const test3_bar = Test3Foo.Two{13};
#static_eval_enable(false)
fn test3_1(f: Test3Foo) {
switch (f) {