From: Brendan Hansen Date: Mon, 22 Feb 2021 21:57:04 +0000 (-0600) Subject: added anonymous struct literals X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=a0a9432f3a2ac85aac1550f120eaf4153b88baa8;p=onyx.git added anonymous struct literals --- diff --git a/.vimspector.json b/.vimspector.json index 7d57391f..d343fe44 100644 --- a/.vimspector.json +++ b/.vimspector.json @@ -5,10 +5,10 @@ "configuration": { "type": "cppdbg", "request": "launch", - "program": "/mnt/c/dev/onyx/bin/onyx", - "args": ["-VVV", "test/basic"], + "program": "${workspaceFolder}/bin/onyx", + "args": ["-VVV", "tmp/a"], "stopAtEntry": true, - "cwd": "/mnt/c/dev/onyx-imgui", + "cwd": "${workspaceFolder}", "environment": [], "externalConsole": false, "MIMode": "gdb", diff --git a/bin/onyx b/bin/onyx index 80399ea4..dce1879a 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/docs/bugs b/docs/bugs index dff0c9f4..44ea7228 100644 --- a/docs/bugs +++ b/docs/bugs @@ -6,7 +6,6 @@ List of known bugs: [ ] Aliasing in many cases does not work. For example: - arr.data[idx] = x; SomeNamespace :: struct { foo :: () { ... } bar :: ... @@ -17,3 +16,23 @@ List of known bugs: SN.foo() } + +List of things to change: +[ ] Currently, there is no way to use the initialized members of a structure without using a struct literal. + There should be a initialize intrinsic procedure that takes a pointer to anything and initializes it. + For example: + + initialize :: (x: ^$T) -> void #intrinsic --- + + Foo :: struct { + x := 1; + y : f32; + } + + x : Foo; + initialize(^x); + + // x.x = 1 + // x.y = + +[ ] Anonymous struct, enum and array literals. diff --git a/src/onyxastnodes.c b/src/onyxastnodes.c index 6f25c6be..98719b8d 100644 --- a/src/onyxastnodes.c +++ b/src/onyxastnodes.c @@ -426,6 +426,13 @@ b32 type_check_or_auto_cast(AstTyped** pnode, Type* type) { if (node_is_type((AstNode *) node)) return 0; + if (node->kind == Ast_Kind_Struct_Literal && node->type_node == NULL) { + node->type = type; + + add_entities_for_node(NULL, (AstNode *) node, NULL, NULL); + return 1; + } + if (node->kind == Ast_Kind_Polymorphic_Proc) { AstFunction* func = polymorphic_proc_lookup((AstPolyProc *) node, PPLM_By_Function_Type, type, node->token); if (func == NULL) return 0; diff --git a/src/onyxchecker.c b/src/onyxchecker.c index 9f3d7c0c..f2f1902d 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -654,14 +654,6 @@ CheckStatus check_binop_assignment(AstBinaryOp* binop, b32 assignment_is_ok) { return Check_Error; } - if (binop->right->type == NULL) { - // nocheckin - // onyx_report_error(binop->token->pos, - // "Unable to resolve type for symbol '%b'.", - // binop->right->token->text, binop->right->token->length); - return Check_Error; - } - if (binop->operation == Binary_Op_Assign) { // NOTE: Raw assignment @@ -671,6 +663,11 @@ CheckStatus check_binop_assignment(AstBinaryOp* binop, b32 assignment_is_ok) { if (binop->left->type == NULL) { resolve_expression_type(binop->right); + if (binop->right->type == NULL) { + onyx_report_error(binop->token->pos, "Could not resolve type of right hand side to infer."); + return Check_Error; + } + if (binop->right->type->kind == Type_Kind_Compound) { AstCompound* lhs = (AstCompound *) binop->left; assert(lhs->kind == Ast_Kind_Compound); @@ -719,6 +716,13 @@ CheckStatus check_binop_assignment(AstBinaryOp* binop, b32 assignment_is_ok) { return Check_Error; } + // CLEANUP: This seems like it should be here. But I don't know where + // or what the right place is for it. + // if (binop->right->type == NULL) { + // onyx_report_error(binop->right->token->pos, "Unable to resolve type for this expression."); + // return Check_Error; + // } + binop->type = &basic_types[Basic_Kind_Void]; return Check_Success; @@ -1028,13 +1032,17 @@ CheckStatus check_unaryop(AstUnaryOp** punop) { } CheckStatus check_struct_literal(AstStructLiteral* sl) { - if (!node_is_type((AstNode *) sl->stnode)) { - onyx_report_error(sl->token->pos, "Struct type is not a type."); - return Check_Error; - } + if (sl->type == NULL) { + if (sl->stnode == NULL) return Check_Success; - fill_in_type((AstTyped *) sl); - if (sl->type == NULL) return Check_Error; + if (!node_is_type((AstNode *) sl->stnode)) { + onyx_report_error(sl->token->pos, "Type used for struct literal is not a type."); + return Check_Error; + } + + fill_in_type((AstTyped *) sl); + if (sl->type == NULL) return Check_Error; + } if (!type_is_structlike_strict(sl->type)) { onyx_report_error(sl->token->pos, "Type is not a constructable using a struct literal."); diff --git a/src/onyxentities.c b/src/onyxentities.c index 0b32a17f..bf3e88c4 100644 --- a/src/onyxentities.c +++ b/src/onyxentities.c @@ -310,4 +310,4 @@ void add_entities_for_node(bh_arr(Entity *) *target_arr, AstNode* node, Scope* s break; } } -} \ No newline at end of file +} diff --git a/src/onyxparser.c b/src/onyxparser.c index da698741..66bdad6d 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -355,6 +355,12 @@ static AstTyped* parse_factor(OnyxParser* parser) { break; } + case '.': { + if (parse_possible_struct_literal(parser, NULL, &retval)) return retval; + if (parse_possible_array_literal(parser, NULL, &retval)) return retval; + goto no_match; + } + case Token_Type_Tilde_Tilde: { AstUnaryOp* ac_node = make_node(AstUnaryOp, Ast_Kind_Unary_Op); ac_node->operation = Unary_Op_Auto_Cast; @@ -566,12 +572,13 @@ static AstTyped* parse_factor(OnyxParser* parser) { break; } - onyx_report_error(parser->curr->pos, "invalid directive in expression."); + onyx_report_error(parser->curr->pos, "Invalid directive in expression."); return NULL; } default: - onyx_report_error(parser->curr->pos, "unexpected token '%s'.", token_name(parser->curr->type)); + no_match: + onyx_report_error(parser->curr->pos, "Unexpected token '%s'.", token_name(parser->curr->type)); return NULL; } diff --git a/src/onyxsymres.c b/src/onyxsymres.c index 5fc8e609..c25168ed 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -390,7 +390,7 @@ static SymresStatus symres_struct_literal(AstStructLiteral* sl) { SYMRES(type, (AstType **) &sl->stnode); sl->type_node = (AstType *) sl->stnode; - while (sl->type_node->kind == Ast_Kind_Type_Alias) + while (sl->type_node && sl->type_node->kind == Ast_Kind_Type_Alias) sl->type_node = ((AstTypeAlias *) sl->type_node)->to; SYMRES(arguments, &sl->args); diff --git a/src/onyxutils.c b/src/onyxutils.c index ec76f05a..a11a35f8 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -1159,7 +1159,7 @@ b32 fill_in_arguments(Arguments* args, AstNode* provider, char** err_msg) { assert(idx < bh_arr_length(args->values)); - if (args->values[idx] != NULL) { + if (args->values[idx] != NULL && args->values[idx] != named_value->value) { if (err_msg) *err_msg = bh_aprintf(global_scratch_allocator, "Multiple values given for parameter named '%s'.", named_value->token->text); token_toggle_end(named_value->token); return 0; @@ -1231,4 +1231,4 @@ i32 string_process_escape_seqs(char* dest, char* src, i32 len) { *dest = 0; return total_len; -} \ No newline at end of file +}