package core
+use package memory { null }
+
Buffer :: struct {
- length: u32;
- data: rawptr;
+ length : u32 = 0;
+ data : rawptr = null;
}
\ No newline at end of file
[X] local variable allocator
- [ ] Struct literals
-
+ [X] Struct literals
+ X All members specified means names not required
+ X Named member initialization
+ X Default values on structs so they don't have to be named
+
[ ] #union on structs
[ ] #align on structs
a := 2
b := 5
a, b = b, a;
-
+
[ ] All code paths return correct value
[ ] Type parameterized structs
typedef struct AstFunctionType AstFunctionType;
typedef struct AstArrayType AstArrayType;
typedef struct AstStructType AstStructType;
+typedef struct AstStructMember AstStructMember;
typedef struct AstEnumType AstEnumType;
typedef struct AstEnumValue AstEnumValue;
typedef struct AstTypeAlias AstTypeAlias;
struct AstSizeOf { AstTyped_base; AstType *so_type; u64 size; };
struct AstAlignOf { AstTyped_base; AstType *ao_type; u64 alignment; };
struct AstFileContents { AstTyped_base; OnyxToken *filename; };
-struct AstStructLiteral { AstTyped_base; AstTyped *stnode; bh_arr(AstTyped *) values; };
+struct AstStructLiteral {
+ AstTyped_base;
+
+ AstTyped *stnode;
+
+ bh_arr(AstStructMember *) named_values;
+ bh_arr(AstTyped *) values;
+};
// Intruction Node
struct AstReturn { AstNode_base; AstTyped* expr; };
struct AstStructType {
AstType_base;
- bh_arr(AstTyped *) members;
+ bh_arr(AstStructMember *) members;
// NOTE: Used to cache the actual type, since building
// a struct type is kind of complicated and should
// only happen once.
Type *stcache;
};
+struct AstStructMember {
+ AstTyped_base;
+ AstTyped* initial_value;
+};
struct AstEnumType {
AstType_base;
Scope *scope;
Msg_Type_Duplicate_Member,
Msg_Type_No_Field,
+ Msg_Type_Duplicate_Value,
+ Msg_Type_Field_No_Value,
Msg_Type_Unresolved_Type,
Msg_Type_Unresolved_Symbol,
mag_squared(varr[2]) |> print();
v1 := Vec3 .{ 1, 2, 4 };
- v2 := *vadd(Vec3.{4, 3, 2}, Vec3.{1, 1, 1});
+ v2 := *vadd(v1, Vec3.{ 1, 2, 4 });
print(v2.x);
print(v2.y);
print(v2.z);
- buf := core.Buffer.{ 16, null };
+ buf := core.Buffer.{
+ length = 16,
+ };
}
vadd :: proc (v1: Vec3, v2: Vec3) -> ^Vec3 {
return 1;
}
- bh_arr_each(AstTyped *, member, s_node->members) {
+ bh_arr_each(AstStructMember *, member, s_node->members) {
token_toggle_end((*member)->token);
if (bh_table_has(i32, mem_set, (*member)->token->text)) {
"duplicate declaration of struct member '%s'",
"field '%s' does not exist on '%s'",
+ "duplicate value for struct member '%b'",
+ "no value provided for field '%b'",
"unable to resolve type for symbol '%b'",
"unable to resolve symbol '%b'",
AstStructLiteral* sl = make_node(AstStructLiteral, Ast_Kind_Struct_Literal);
sl->token = parser->curr;
bh_arr_new(global_heap_allocator, sl->values, 4);
+ bh_arr_new(global_heap_allocator, sl->named_values, 4);
if (symbol2 != NULL) {
AstTyped *package = make_node(AstTyped, Ast_Kind_Symbol);
}
expect_token(parser, '{');
+ b32 is_named = ((parser->curr + 1)->type == '=');
+
+ OnyxToken* name = NULL;
while (parser->curr->type != '}') {
if (parser->hit_unexpected_token) break;
+ if (is_named) {
+ name = expect_token(parser, Token_Type_Symbol);
+ expect_token(parser, '=');
+ } else {
+ name = NULL;
+ }
+
AstTyped *expr = parse_expression(parser);
- bh_arr_push(sl->values, expr);
+
+ if (is_named) {
+ AstStructMember* sm = make_node(AstStructMember, Ast_Kind_Struct_Member);
+ sm->token = name;
+ sm->initial_value = expr;
+
+ bh_arr_push(sl->named_values, sm);
+
+ } else {
+ bh_arr_push(sl->values, expr);
+ }
if (parser->curr->type != '}')
expect_token(parser, ',');
while (parser->curr->type != '}') {
if (parser->hit_unexpected_token) return s_node;
- AstTyped* mem = make_node(AstTyped, Ast_Kind_Struct_Member);
+ AstStructMember* mem = make_node(AstStructMember, Ast_Kind_Struct_Member);
mem->token = expect_token(parser, Token_Type_Symbol);
expect_token(parser, ':');
mem->type_node = parse_type(parser);
+
+ if (parser->curr->type == '=') {
+ consume_token(parser);
+ mem->initial_value = parse_expression(parser);
+ }
+
expect_token(parser, ';');
bh_arr_push(s_node->members, mem);
s_node->flags |= Ast_Flag_Type_Is_Resolved;
- bh_arr_each(AstTyped *, member, s_node->members) {
+ bh_arr_each(AstStructMember *, member, s_node->members) {
(*member)->type_node = symres_type((*member)->type_node);
+ if ((*member)->initial_value != NULL) {
+ symres_expression(&(*member)->initial_value);
+ }
}
return type;
}
sl->type_node = (AstType *) sl->stnode;
+ sl->type = type_build_from_ast(semstate.allocator, sl->type_node);
+
+ if (bh_arr_length(sl->named_values) > 0) {
+ bh_arr_set_length(sl->values, sl->type->Struct.mem_count);
+
+ StructMember s;
+ bh_arr_each(AstStructMember *, smem, sl->named_values) {
+ token_toggle_end((*smem)->token);
+ if (!type_struct_lookup_member(sl->type, (*smem)->token->text, &s)) {
+ onyx_message_add(Msg_Type_No_Field,
+ (*smem)->token->pos,
+ (*smem)->token->text, type_get_name(sl->type));
+ return;
+ }
+ token_toggle_end((*smem)->token);
+
+ if (sl->values[s.idx] != NULL) {
+ onyx_message_add(Msg_Type_Duplicate_Value,
+ (*smem)->token->pos,
+ (*smem)->token->text, (*smem)->token->length);
+ return;
+ }
+
+ sl->values[s.idx] = (*smem)->initial_value;
+ }
+
+ AstStructType* st = (AstStructType *) sl->type_node;
+ bh_arr_each(StructMember*, smem, sl->type->Struct.memarr) {
+ u32 idx = (*smem)->idx;
+
+ if (sl->values[idx] == NULL) {
+ if (st->members[idx]->initial_value == NULL) {
+ onyx_message_add(Msg_Type_Field_No_Value,
+ sl->token->pos,
+ st->members[idx]->token->text,
+ st->members[idx]->token->length);
+ return;
+ }
+
+ sl->values[idx] = st->members[idx]->initial_value;
+ }
+ }
+ }
bh_arr_each(AstTyped *, expr, sl->values) symres_expression(expr);
}
st = (AstStructType *) ((AstPointerType *) param->type_node)->elem;
}
- bh_arr_each(AstTyped *, mem, st->members) {
+ bh_arr_each(AstStructMember *, mem, st->members) {
AstFieldAccess* fa = onyx_ast_node_new(semstate.node_allocator, sizeof(AstFieldAccess), Ast_Kind_Field_Access);
fa->token = (*mem)->token;
fa->type_node = (*mem)->type_node;
u32 offset = 0;
u32 alignment = 1, mem_alignment;
u32 idx = 0;
- bh_arr_each(AstTyped *, member, s_node->members) {
+ bh_arr_each(AstStructMember *, member, s_node->members) {
(*member)->type = type_build_from_ast(alloc, (*member)->type_node);
// TODO: Add alignment checking here
// NOTE: Need to do a second pass because the references to the
// elements of the table may change if the internal arrays of the
// table need to be resized.
- bh_arr_each(AstTyped *, member, s_node->members) {
+ bh_arr_each(AstStructMember *, member, s_node->members) {
token_toggle_end((*member)->token);
bh_arr_push(s_type->Struct.memarr, &bh_table_get(StructMember, s_type->Struct.members, (*member)->token->text));
token_toggle_end((*member)->token);