From: Brendan Hansen Date: Wed, 22 Jul 2020 13:33:25 +0000 (-0500) Subject: Added UFC syntax for function calls on structs X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=6b1a290541690d2ce018562913222869bd8e9f6e;p=onyx.git Added UFC syntax for function calls on structs --- diff --git a/docs/plan b/docs/plan index 1c0078d9..91f99cf7 100644 --- a/docs/plan +++ b/docs/plan @@ -88,20 +88,28 @@ HOW: - Adds '.onyx' to the end of the file name list - Only searches in current directory for now - [ ] Completely overhaul the type system + [X] Completely overhaul the type system - Keep the builtins - Add pointers - Add structs - [ ] Output 'drop' instruction for functions whose return value isn't used + [X] Output 'drop' instruction for functions whose return value isn't used [ ] Devise and implement a simple set of implicit type casting rules. - Numeric literals always type cast to whatever type is needed (very flexible). - [ ] Strings should work as pointers to data. + [X] Strings should work as pointers to data. - Literals should be placed in data section with pointers to the start. - Should strings be null-terminated or a length at the start of the string? + [ ] Struct splatting in arguments and parameters + + [X] UFC syntax for structs + + [ ] Enum types + + [ ] Procedures as arguments + [ ] Start work on evaluating compile time known values. - An expression marked COMPTIME will be reduced to its value in the parse tree. @@ -131,6 +139,5 @@ HOW: - diff --git a/onyx b/onyx index 6cb71073..982db0e1 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/structs.onyx b/progs/structs.onyx index 23bcce71..a0608d71 100644 --- a/progs/structs.onyx +++ b/progs/structs.onyx @@ -3,12 +3,6 @@ use "progs/intrinsics" N :: 5 -Vec3 :: struct { - x : f32; - y : f32; - z : f32; -} - Foo :: struct { v : Vec3; i : i32; @@ -37,55 +31,6 @@ foo_get :: proc (fooarr: []Foo, i: i32) -> ^Foo { return ^fooarr[i]; } -proc #export "main3" { - // foo := foo_make(); - // other_foo := foo_make(); - // other_foo.i = 1234; - - // foo.foo = other_foo; - // print(foo.foo.i); - foo1 := foo_make(); - foo1.v.y = 123.0f; - print(foo1.v.y); - - foo := alloc(sizeof [N]Foo) as [N]Foo; - - for i: 1, 6 { - foo[i - 1].v.x = (i + 3) as f32; - foo[i - 1].v.y = (i + 4) as f32; - - foo[i - 1].i = i; - foo[i - 1].l = (i * 10) as i64; - foo[i - 1].f = (i * 100) as f32; - foo[i - 1].d = (i * 1000) as f64; - - foo[i - 1].foo = foo as ^Foo; - } - - print(foo[3].v.x); // 7 - print(foo[4].i); // 5 - print(foo[2].d); // 3000.0 - print(foo[3].f); // 400.0 - print(foo[0].l); // 10 - - print(foo as i32); - print((^(foo[3].l)) as i32); // 84 - - print(foo[2].foo[4].foo[3].f); // 400.0 - - foo_get(foo, 2).f = 1234.5f; - print(foo[2].f); - - print(1000000000000); - link_test(); - - print(foo[3].v.x); // 7 - print(foo[4].i); // 5 - print(foo[2].d); // 3000.0 - print(foo[3].f); // 400.0 - print(foo[0].l); // 10 -} - Mut1 :: struct { bar : i32; other : Mut2; @@ -156,6 +101,45 @@ Vec2 :: struct { y : i32; } +Vec3 :: struct { + x : i32; + y : i32; + z : i32; +} + +v2magnitude :: proc (v: ^Vec2) -> f32 { + return sqrt_f32((v.x * v.x + v.y * v.y) as f32); +} + +v3magnitude :: proc (v: ^Vec3) -> f32 { + return sqrt_f32((v.x * v.x + v.y * v.y + v.z * v.z) as f32); +} + +magnitude :: proc #overloaded { v2magnitude, v3magnitude }; + +minus :: proc (n: i32, k: i32) -> i32 { + return n - k; +} + +foo :: proc (f: (i32, i32) -> i32) -> i32 { + return f(5, 6); +} + +proc #export "main" { + v2 := alloc(sizeof Vec2) as ^Vec2; + v2.x = 5; + v2.y = 12; + print(v2.magnitude()); + + v3 := alloc(sizeof Vec3) as ^Vec3; + v3.x = 1; + v3.y = 1; + v3.z = 1; + print(v3.magnitude()); + + print((1).minus(2)); +} + SOA :: struct { positions : [10] Vec2; velocities : [10] Vec2; @@ -167,7 +151,7 @@ vec2_set :: proc (v: ^Vec2) { v.y = 5678; } -soa_test :: proc #export "main" { +soa_test :: proc #export "main9" { // print(sizeof SOA); // 240 @@ -185,6 +169,8 @@ soa_test :: proc #export "main" { vec2_set(^(soa.positions[6])); vec2_set(soa.things[2]); + print((^(soa.positions[6])).v2magnitude()); + print(soa.positions[5].y); print(soa.velocities[2].x); print(soa.things[2].x); @@ -199,6 +185,6 @@ soa_test :: proc #export "main" { m_arr[y][x] = x + y * 5; } } - + for i: 0, 25 print((m_arr as [] i32)[i]); } \ No newline at end of file diff --git a/src/onyxmsgs.c b/src/onyxmsgs.c index afd76686..37f0fd97 100644 --- a/src/onyxmsgs.c +++ b/src/onyxmsgs.c @@ -61,21 +61,22 @@ void onyx_message_add(MsgType type, OnyxFilePos pos, ...) { } static void print_detailed_message(Message* msg, bh_file_contents* fc) { - bh_printf("(%s:%l:%l) %s\n", msg->pos.filename, msg->pos.line, msg->pos.column, msg->text); + bh_printf("(%s:%l,%l) %s\n", msg->pos.filename, msg->pos.line, msg->pos.column, msg->text); i32 linelength = 0; char* walker = msg->pos.line_start; while (*walker != '\n') linelength++, walker++; - bh_printf("| %b\n", msg->pos.line_start, linelength); + i32 numlen = bh_printf(" %d |", msg->pos.line); + bh_printf("%b\n", msg->pos.line_start, linelength); - char* pointer_str = bh_alloc_array(global_scratch_allocator, char, linelength); - memset(pointer_str, ' ', linelength); - memset(pointer_str + msg->pos.column, '~', msg->pos.length - 1); - pointer_str[msg->pos.column - 1] = '^'; - pointer_str[msg->pos.column + msg->pos.length - 1] = 0; + char* pointer_str = bh_alloc_array(global_scratch_allocator, char, linelength + numlen); + memset(pointer_str, ' ', linelength + numlen); + memset(pointer_str + msg->pos.column + numlen, '~', msg->pos.length - 1); + pointer_str[msg->pos.column + numlen - 1] = '^'; + pointer_str[msg->pos.column + numlen + msg->pos.length - 1] = 0; - bh_printf("| %s\n", pointer_str); + bh_printf("%s\n", pointer_str); } void onyx_message_print() { @@ -88,7 +89,7 @@ void onyx_message_print() { print_detailed_message(msg, fc); } else { - bh_printf("(%l:%l) %s\n", msg->pos.line, msg->pos.column, msg->text); + bh_printf("(%l,%l) %s\n", msg->pos.line, msg->pos.column, msg->text); } msg = msg->next; } diff --git a/src/onyxparser.c b/src/onyxparser.c index fc827d86..bdef91ea 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -192,47 +192,7 @@ static AstTyped* parse_factor(OnyxParser* parser) { AstTyped* sym_node = make_node(AstTyped, Ast_Kind_Symbol); sym_node->token = sym_token; - if (parser->curr->type != '(') { - retval = sym_node; - break; - } - - // NOTE: Function call - AstCall* call_node = make_node(AstCall, Ast_Kind_Call); - call_node->token = expect_token(parser, '('); - call_node->callee = (AstNode *) sym_node; - call_node->arg_count = 0; - - AstArgument** prev = &call_node->arguments; - AstArgument* curr = NULL; - while (parser->curr->type != ')') { - curr = make_node(AstArgument, Ast_Kind_Argument); - curr->token = parser->curr; - curr->value = parse_expression(parser); - - if (curr != NULL && curr->kind != Ast_Kind_Error) { - *prev = curr; - prev = (AstArgument **) &curr->next; - - call_node->arg_count++; - } - - if (parser->curr->type == ')') - break; - - if (parser->curr->type != ',') { - onyx_message_add(Msg_Type_Expected_Token, - parser->curr->pos, - token_name(','), - token_name(parser->curr->type)); - return (AstTyped *) &error_node; - } - - consume_token(parser); - } - consume_token(parser); - - retval = (AstTyped *) call_node; + retval = sym_node; break; } @@ -282,7 +242,7 @@ static AstTyped* parse_factor(OnyxParser* parser) { } while (parser->curr->type == '[' || parser->curr->type == Token_Type_Keyword_Cast - || parser->curr->type == '.') { + || parser->curr->type == '.' || parser->curr->type == '(') { switch ((u16) parser->curr->type) { case '[': { @@ -317,6 +277,45 @@ static AstTyped* parse_factor(OnyxParser* parser) { retval = (AstTyped *) cast_node; break; } + + case '(': { + AstCall* call_node = make_node(AstCall, Ast_Kind_Call); + call_node->token = expect_token(parser, '('); + call_node->callee = (AstNode *) retval; + call_node->arg_count = 0; + + AstArgument** prev = &call_node->arguments; + AstArgument* curr = NULL; + while (parser->curr->type != ')') { + curr = make_node(AstArgument, Ast_Kind_Argument); + curr->token = parser->curr; + curr->value = parse_expression(parser); + + if (curr != NULL && curr->kind != Ast_Kind_Error) { + *prev = curr; + prev = (AstArgument **) &curr->next; + + call_node->arg_count++; + } + + if (parser->curr->type == ')') + break; + + if (parser->curr->type != ',') { + onyx_message_add(Msg_Type_Expected_Token, + parser->curr->pos, + token_name(','), + token_name(parser->curr->type)); + return (AstTyped *) &error_node; + } + + consume_token(parser); + } + consume_token(parser); + + retval = (AstTyped *) call_node; + break; + } } } diff --git a/src/onyxsymres.c b/src/onyxsymres.c index f2a59202..d056573d 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -1,5 +1,6 @@ #define BH_DEBUG #include "onyxsempass.h" +#include "onyxparser.h" AstBasicType basic_type_void = { { Ast_Kind_Basic_Type, 0, NULL, "void" }, &basic_types[Basic_Kind_Void] }; AstBasicType basic_type_bool = { { Ast_Kind_Basic_Type, 0, NULL, "bool" }, &basic_types[Basic_Kind_Bool] }; @@ -46,7 +47,7 @@ static void scope_leave(); static AstType* symres_type(AstType* type); static void symres_local(AstLocal** local); -static void symres_call(AstCall* call); +static void symres_call(AstCall** pcall); static void symres_size_of(AstSizeOf* so); static void symres_expression(AstTyped** expr); static void symres_return(AstReturn* ret); @@ -185,7 +186,27 @@ static void symres_local(AstLocal** local) { symbol_introduce((*local)->token, (AstNode *) *local); } -static void symres_call(AstCall* call) { +static void symres_call(AstCall** pcall) { + AstCall* call = *pcall; + + if (call->callee->kind == Ast_Kind_Field_Access) { + AstFieldAccess* fa = (AstFieldAccess *) call->callee; + + AstTyped* symbol = onyx_ast_node_new(semstate.node_allocator, sizeof(AstTyped), Ast_Kind_Symbol); + symbol->token = fa->token; + + AstArgument* implicit_arg = onyx_ast_node_new(semstate.node_allocator, sizeof(AstArgument), Ast_Kind_Argument); + implicit_arg->value = fa->expr; + implicit_arg->token = fa->expr->token; + implicit_arg->next = (AstNode *) call->arguments; + + (*pcall)->callee = (AstNode *) symbol; + (*pcall)->arguments = implicit_arg; + (*pcall)->arg_count++; + + call = *pcall; + } + AstNode* callee = symbol_resolve(call->callee->token); if (callee) call->callee = callee; @@ -222,7 +243,7 @@ static void symres_expression(AstTyped** expr) { break; case Ast_Kind_Unary_Op: symres_unaryop((AstUnaryOp **) expr); break; - case Ast_Kind_Call: symres_call((AstCall *) *expr); break; + case Ast_Kind_Call: symres_call((AstCall **) expr); break; case Ast_Kind_Block: symres_block((AstBlock *) *expr); break; case Ast_Kind_Symbol: @@ -300,7 +321,7 @@ static b32 symres_statement(AstNode* stmt) { case Ast_Kind_If: symres_if((AstIf *) stmt); return 0; case Ast_Kind_While: symres_while((AstWhile *) stmt); return 0; case Ast_Kind_For: symres_for((AstFor *) stmt); return 0; - case Ast_Kind_Call: symres_call((AstCall *) stmt); return 0; + case Ast_Kind_Call: symres_call((AstCall **) &stmt); return 0; case Ast_Kind_Argument: symres_expression((AstTyped **) &((AstArgument *)stmt)->value); return 0; case Ast_Kind_Block: symres_block((AstBlock *) stmt); return 0;