parent
7a7f83033c
commit
36c6acfc76
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue