Added ability to 'use' parameters
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 27 Jul 2020 14:48:04 +0000 (09:48 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 27 Jul 2020 14:48:04 +0000 (09:48 -0500)
docs/plan
include/onyxastnodes.h
onyx
progs/ez.onyx
progs/print_funcs.onyx
progs/ufc.onyx
src/onyxparser.c
src/onyxsymres.c

index 6c4426ba50c65398b7e675b3cd0ff1afdb8f45e7..b3b3a5b72ecd3e1f72d60ddac489c680aa351972 100644 (file)
--- a/docs/plan
+++ b/docs/plan
@@ -119,12 +119,17 @@ HOW:
 
         [X] Enum types
 
-        [ ] Static pointers to sized data
+        [X] Static pointers to sized data
 
-        [ ] 'using' parameters
+        [X] 'using' parameters
             - The following example will bring the members of the struct into the scope as field accesses
               and allow for a more OO style programming, without diving into the crap that is OO
 
+              foo :: proc (use data: ^Data, other_arg: i32) {
+                  member1_of_data = other_arg;
+                  bar(member2_of_data);
+              }
+
         [ ] Start work on evaluating compile time known values.
             - An expression marked COMPTIME will be reduced to its value in the parse tree.
 
index 078a9803d68888b9fa414974d422b00dd0020398..1238eed7f68c106a8b4b7b229a6ee7849c943b1a 100644 (file)
@@ -136,6 +136,7 @@ typedef enum AstFlags {
     // Expression flags
     Ast_Flag_Expr_Ignored     = BH_BIT(8),
     Ast_Flag_Param_Splatted   = BH_BIT(9),
+    Ast_Flag_Param_Use        = BH_BIT(10),
     
     // Type flags
     Ast_Flag_Type_Is_Resolved = BH_BIT(8),
diff --git a/onyx b/onyx
index 137784d6fac9b4ca65296c327bf433dc8fa87ee4..202b8c35bb77b4f271f2c38ebe6afd434b6ad058 100755 (executable)
Binary files a/onyx and b/onyx differ
index 58d61414bc9092d0d7b7fd4fa534714995dadca0..947baca2f2f0d51c751c7ffe0be394275719c17e 100644 (file)
@@ -1,9 +1,9 @@
 use "progs/print_funcs"
+use "progs/intrinsics"
 
 use package printing {
     print, PrintableArray,
-    print_f32 as pf32,
-    print_buf
+    print_f32 as pf32
 }
 
 Foo :: struct {
@@ -13,8 +13,8 @@ Foo :: struct {
     st : SomeType;
 }
 
-foo_sum :: proc (foo: ^Foo) -> i32 {
-    return foo.x + foo.y;
+foo_sum :: proc (use foo: ^Foo) -> i32 {
+    return x + y;
 }
 
 asdf :: proc (pa: PrintableArray) {
@@ -28,7 +28,7 @@ SomeType :: enum {
     Value4;
 }
 
-print_st :: proc (st: SomeType) {
+print_st :: proc (st: SomeType, other: i32) {
     print(st as i32);
 }
 
@@ -42,16 +42,14 @@ proc #export "main" {
 
     print(__heap_start as i32);
 
-    print(print_buf as i32);
-
     single_int = 10 as u8;
     print(single_int as i32);
 
     array[4].y = 1234;
     print(array[4].y);
 
-    st := SomeType.Value4;
-    print_st(st);
+    st: SomeType = SomeType.Value4;
+    print_st(st, 10);
 
     foo := __heap_start as ^Foo;
     foo.x = 123;
@@ -60,7 +58,7 @@ proc #export "main" {
     print(alignof Foo);
     print(sizeof Foo);
     print(foo.foo_sum());
-    print_st(foo.st);
+    print_st(foo.st, 20);
 
     pa := (__heap_start as i32 + sizeof Foo) as ^PrintableArray;
     pa.data = __heap_start as ^u8;
@@ -69,6 +67,6 @@ proc #export "main" {
 
     print(1234);
 
-    pf32(123.0f);
+    pf32(sqrt_f32(123.0f));
 }
 
index dd09204044f75b39197bd5d57983690948b24a22..3f48aab3d9c7008511d4405e5964d42f7d57db81 100644 (file)
@@ -1,9 +1,5 @@
 package printing
 
-use package main {
-    N as buf_size
-}
-
 print_bool :: proc #foreign "host" "print" (value: bool) ---
 print_i32  :: proc #foreign "host" "print" (value: i32) ---
 print_f32  :: proc #foreign "host" "print" (value: f32) ---
@@ -59,5 +55,3 @@ print :: proc #overloaded {
     print_str,
     print_str_len,
 }
-
-print_buf : [buf_size] u8
\ No newline at end of file
index cb3636778b0d8757bb7792f934b123316e5f4209..fb88f6ac43767bd19473fb0dd2cdbf1b72111d56 100644 (file)
@@ -41,8 +41,8 @@ Vec2 :: struct {
        y : f32;
 }
 
-vec2_magnitude :: proc (v: ^Vec2) -> i32 {
-       return sqrt_f32(v.x * v.x + v.y * v.y) as i32;
+vec2_magnitude :: proc (use v: ^Vec2) -> i32 {
+       return sqrt_f32(x * x + y * y) as i32;
 }
 
 Vec3 :: struct {
@@ -51,8 +51,8 @@ Vec3 :: struct {
        z : f32;
 }
 
-vec3_magnitude :: proc (v: ^Vec3) -> f32 {
-       return sqrt_f32(v.x * v.x + v.y * v.y + v.z * v.z);     
+vec3_magnitude :: proc (use v: ^Vec3) -> f32 {
+       return sqrt_f32(x * x + y * y + z * z); 
 }
 
 magnitude :: proc #overloaded {
index 865efd392f8e024cd5be12400ebdf70caa63f47b..79958c575e6eacd3c24f297dbba6ac968775de54 100644 (file)
@@ -889,9 +889,13 @@ static AstLocal* parse_function_params(OnyxParser* parser) {
     AstLocal* curr_param = NULL;
     AstLocal* trailer = NULL;
 
+    b32 param_use = 0;
     OnyxToken* symbol;
     while (parser->curr->type != ')') {
-        if (parser->curr->type == ',') consume_token(parser);
+        if (parser->curr->type == Token_Type_Keyword_Use) {
+            consume_token(parser);
+            param_use = 1;
+        }
 
         symbol = expect_token(parser, Token_Type_Symbol);
         expect_token(parser, ':');
@@ -901,12 +905,20 @@ static AstLocal* parse_function_params(OnyxParser* parser) {
         curr_param->flags |= Ast_Flag_Const;
         curr_param->type_node = parse_type(parser);
 
+        if (param_use) {
+            curr_param->flags |= Ast_Flag_Param_Use;
+            param_use = 0;
+        }
+
         if (first_param == NULL) first_param = curr_param;
 
         curr_param->next = NULL;
         if (trailer) trailer->next = (AstNode *) curr_param;
 
         trailer = curr_param;
+
+        if (parser->curr->type != ')')
+            expect_token(parser, ',');
     }
 
     consume_token(parser); // Skip the )
index 7c0bbccd77ed913d3e98a2377d1c7fd647d88b2b..ff8586f61acfdcd0b5c47d5a6549439b13c8313b 100644 (file)
@@ -349,6 +349,26 @@ static void symres_function(AstFunction* func) {
         param->type_node = symres_type(param->type_node);
 
         symbol_introduce(semstate.curr_scope, param->token, (AstNode *) param);
+
+        if (param->flags & Ast_Flag_Param_Use) {
+            if (param->type_node->kind != Ast_Kind_Pointer_Type
+                || ((AstPointerType *) param->type_node)->elem->kind != Ast_Kind_Struct_Type) {
+                onyx_message_add(Msg_Type_Literal,
+                        param->token->pos,
+                        "can only 'use' pointers to structures.");
+            } else {
+                AstStructType* st = (AstStructType *) ((AstPointerType *) param->type_node)->elem;
+
+                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;
+                    fa->expr = (AstTyped *) param;
+
+                    symbol_introduce(semstate.curr_scope, (*mem)->token, (AstNode *) fa);
+                }
+            }
+        }
     }
 
     if (func->type_node != NULL) {