Added UFC syntax for function calls on structs
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 22 Jul 2020 13:33:25 +0000 (08:33 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 22 Jul 2020 13:33:25 +0000 (08:33 -0500)
docs/plan
onyx
progs/structs.onyx
src/onyxmsgs.c
src/onyxparser.c
src/onyxsymres.c

index 1c0078d9239ef5150ff5bb513dda618ef6a3b225..91f99cf7afe5e3dba38d9a8eca242b180450629b 100644 (file)
--- 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 6cb71073c234edd54da55f98b507d8b0cd4ce380..982db0e14864bb625e5b685461b7541bed3589c3 100755 (executable)
Binary files a/onyx and b/onyx differ
index 23bcce71de08491116fd126e44240a490e38a6c3..a0608d710ce1e3dabc455255c44d75a787f1f537 100644 (file)
@@ -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
index afd766860806e25a2312a668d84011fe7d040c62..37f0fd97c7d76acf9b06d2fd85ee69ef06c1537e 100644 (file)
@@ -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;
     }
index fc827d86a338a5cf0e1c3bf624d7937dcdb70829..bdef91ea861b364339f7c190e508c232dd80933f 100644 (file)
@@ -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;
+            }
         }
     }
 
index f2a592029ccbf8c2c567cd77cbfdde804cc9840a..d056573d85b4285eae06c16e9301eb399da5c8d9 100644 (file)
@@ -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;