parent
7a7f83033c
commit
36c6acfc76
@ -392,7 +392,6 @@ struct AstNodeFnCallExpr {
|
|||||||
Expr resolved_expr;
|
Expr resolved_expr;
|
||||||
FnTableEntry *fn_entry;
|
FnTableEntry *fn_entry;
|
||||||
CastOp cast_op;
|
CastOp cast_op;
|
||||||
TypeTableEntry *enum_type;
|
|
||||||
// if cast_op is CastOpArrayToString, this will be a pointer to
|
// if cast_op is CastOpArrayToString, this will be a pointer to
|
||||||
// the string struct on the stack
|
// the string struct on the stack
|
||||||
LLVMValueRef tmp_ptr;
|
LLVMValueRef tmp_ptr;
|
||||||
@ -429,6 +428,7 @@ struct AstNodeFieldAccessExpr {
|
|||||||
bool is_fn_call;
|
bool is_fn_call;
|
||||||
TypeTableEntry *bare_struct_type;
|
TypeTableEntry *bare_struct_type;
|
||||||
bool is_member_fn;
|
bool is_member_fn;
|
||||||
|
AstNode *container_init_expr_node;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstNodeDirective {
|
struct AstNodeDirective {
|
||||||
@ -665,6 +665,7 @@ struct AstNodeContainerInitExpr {
|
|||||||
// populated by semantic analyzer
|
// populated by semantic analyzer
|
||||||
StructValExprCodeGen resolved_struct_val_expr;
|
StructValExprCodeGen resolved_struct_val_expr;
|
||||||
Expr resolved_expr;
|
Expr resolved_expr;
|
||||||
|
TypeTableEntry *enum_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstNodeNullLiteral {
|
struct AstNodeNullLiteral {
|
||||||
|
@ -2197,7 +2197,23 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry
|
|||||||
|
|
||||||
ContainerInitKind kind = container_init_expr->kind;
|
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) {
|
if (container_type->id == TypeTableEntryIdInvalid) {
|
||||||
return container_type;
|
return container_type;
|
||||||
@ -2322,9 +2338,6 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry
|
|||||||
} else if (container_type->id == TypeTableEntryIdArray) {
|
} else if (container_type->id == TypeTableEntryIdArray) {
|
||||||
zig_panic("TODO array container init");
|
zig_panic("TODO array container init");
|
||||||
return container_type;
|
return container_type;
|
||||||
} else if (container_type->id == TypeTableEntryIdEnum) {
|
|
||||||
zig_panic("TODO enum container init");
|
|
||||||
return container_type;
|
|
||||||
} else if (container_type->id == TypeTableEntryIdVoid) {
|
} else if (container_type->id == TypeTableEntryIdVoid) {
|
||||||
if (container_init_expr->entries.length != 0) {
|
if (container_init_expr->entries.length != 0) {
|
||||||
add_node_error(g, node, buf_sprintf("void expression expects no arguments"));
|
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) {
|
} else if (wrapped_in_fn_call) {
|
||||||
return resolve_expr_const_val_as_type(g, node, child_type);
|
return resolve_expr_const_val_as_type(g, node, child_type);
|
||||||
} else if (child_type->id == TypeTableEntryIdEnum) {
|
} 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) {
|
} else if (child_type->id == TypeTableEntryIdStruct) {
|
||||||
BlockContext *container_block_context = get_container_block_context(child_type);
|
BlockContext *container_block_context = get_container_block_context(child_type);
|
||||||
auto entry = container_block_context->decl_table.maybe_get(field_name);
|
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) {
|
if (child_type->id == TypeTableEntryIdInvalid) {
|
||||||
return g->builtin_types.entry_invalid;
|
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) {
|
} else if (child_type->id == TypeTableEntryIdStruct) {
|
||||||
Buf *field_name = &fn_ref_expr->data.field_access_expr.field_name;
|
Buf *field_name = &fn_ref_expr->data.field_access_expr.field_name;
|
||||||
BlockContext *container_block_context = get_container_block_context(child_type);
|
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);
|
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;
|
FnTableEntry *fn_table_entry = node->data.fn_call_expr.fn_entry;
|
||||||
TypeTableEntry *struct_type = nullptr;
|
TypeTableEntry *struct_type = nullptr;
|
||||||
AstNode *first_param_expr = nullptr;
|
AstNode *first_param_expr = nullptr;
|
||||||
|
|
||||||
|
AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
|
||||||
if (fn_ref_expr->type == NodeTypeFieldAccessExpr &&
|
if (fn_ref_expr->type == NodeTypeFieldAccessExpr &&
|
||||||
fn_ref_expr->data.field_access_expr.is_member_fn)
|
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);
|
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) {
|
if (type_entry->id == TypeTableEntryIdStruct) {
|
||||||
assert(node->data.container_init_expr.kind == ContainerInitKindStruct);
|
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;
|
AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr;
|
||||||
ContainerInitKind kind = container_init_expr->kind;
|
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);
|
TypeTableEntry *container_type = resolve_expr_type(container_init_expr->type);
|
||||||
out_val->ok = true;
|
out_val->ok = true;
|
||||||
|
|
||||||
@ -723,10 +728,6 @@ static bool eval_fn_call_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->data.fn_call_expr.enum_type) {
|
|
||||||
zig_panic("TODO");
|
|
||||||
}
|
|
||||||
|
|
||||||
FnTableEntry *fn_table_entry = node->data.fn_call_expr.fn_entry;
|
FnTableEntry *fn_table_entry = node->data.fn_call_expr.fn_entry;
|
||||||
|
|
||||||
if (fn_ref_expr->type == NodeTypeFieldAccessExpr &&
|
if (fn_ref_expr->type == NodeTypeFieldAccessExpr &&
|
||||||
|
@ -353,8 +353,8 @@ fn maybe_type() {
|
|||||||
|
|
||||||
#attribute("test")
|
#attribute("test")
|
||||||
fn enum_type() {
|
fn enum_type() {
|
||||||
const foo1 = EnumTypeFoo.One(13);
|
const foo1 = EnumTypeFoo.One {13};
|
||||||
const foo2 = EnumTypeFoo.Two(EnumType { .x = 1234, .y = 5678, });
|
const foo2 = EnumTypeFoo.Two {EnumType { .x = 1234, .y = 5678, }};
|
||||||
const bar = EnumTypeBar.B;
|
const bar = EnumTypeBar.B;
|
||||||
|
|
||||||
assert(bar == EnumTypeBar.B);
|
assert(bar == EnumTypeBar.B);
|
||||||
@ -449,7 +449,7 @@ fn should_be_not_equal(a: error, b: error) {
|
|||||||
#attribute("test")
|
#attribute("test")
|
||||||
fn constant_enum_with_payload() {
|
fn constant_enum_with_payload() {
|
||||||
var empty = AnEnumWithPayload.Empty;
|
var empty = AnEnumWithPayload.Empty;
|
||||||
var full = AnEnumWithPayload.Full(13);
|
var full = AnEnumWithPayload.Full {13};
|
||||||
should_be_empty(empty);
|
should_be_empty(empty);
|
||||||
should_be_not_empty(full);
|
should_be_not_empty(full);
|
||||||
}
|
}
|
||||||
@ -547,8 +547,8 @@ enum SwitchStatmentFoo {
|
|||||||
|
|
||||||
#attribute("test")
|
#attribute("test")
|
||||||
fn switch_prong_with_var() {
|
fn switch_prong_with_var() {
|
||||||
switch_prong_with_var_fn(SwitchProngWithVarEnum.One(13));
|
switch_prong_with_var_fn(SwitchProngWithVarEnum.One {13});
|
||||||
switch_prong_with_var_fn(SwitchProngWithVarEnum.Two(13.0));
|
switch_prong_with_var_fn(SwitchProngWithVarEnum.Two {13.0});
|
||||||
switch_prong_with_var_fn(SwitchProngWithVarEnum.Meh);
|
switch_prong_with_var_fn(SwitchProngWithVarEnum.Meh);
|
||||||
}
|
}
|
||||||
enum SwitchProngWithVarEnum {
|
enum SwitchProngWithVarEnum {
|
||||||
@ -1221,8 +1221,8 @@ struct Test3Point {
|
|||||||
x: i32,
|
x: i32,
|
||||||
y: i32,
|
y: i32,
|
||||||
}
|
}
|
||||||
const test3_foo = Test3Foo.Three(Test3Point {.x = 3, .y = 4});
|
const test3_foo = Test3Foo.Three{Test3Point {.x = 3, .y = 4}};
|
||||||
const test3_bar = Test3Foo.Two(13);
|
const test3_bar = Test3Foo.Two{13};
|
||||||
#static_eval_enable(false)
|
#static_eval_enable(false)
|
||||||
fn test3_1(f: Test3Foo) {
|
fn test3_1(f: Test3Foo) {
|
||||||
switch (f) {
|
switch (f) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user