Added basic type aliasing
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 28 Jul 2020 16:38:07 +0000 (11:38 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 28 Jul 2020 16:38:07 +0000 (11:38 -0500)
include/onyxastnodes.h
onyx
progs/fcf.onyx
src/onyx.c
src/onyxchecker.c
src/onyxparser.c
src/onyxsymres.c
src/onyxtypes.c
src/onyxutils.c

index 72fb15eb02c774a84c96b291a3bc7c62e29ae75e..bde66fe2124654a3a4f1d44887759f0da8be3d24 100644 (file)
@@ -41,6 +41,7 @@ typedef struct AstStructType AstStructType;
 typedef struct AstStructMember AstStructMember;
 typedef struct AstEnumType AstEnumType;
 typedef struct AstEnumValue AstEnumValue;
+typedef struct AstTypeAlias AstTypeAlias;
 
 typedef struct AstBinding AstBinding;
 typedef struct AstMemRes AstMemRes;
@@ -91,6 +92,7 @@ typedef enum AstKind {
     Ast_Kind_Array_Type,
     Ast_Kind_Struct_Type,
     Ast_Kind_Enum_Type,
+    Ast_Kind_Type_Alias,
     Ast_Kind_Type_End,
 
     Ast_Kind_Struct_Member,
@@ -331,6 +333,7 @@ struct AstEnumType {
     Type *etcache;
 };
 struct AstEnumValue { AstTyped_base; AstNumLit* value; };
+struct AstTypeAlias { AstType_base; AstType* to; };
 
 // Top level nodes
 struct AstBinding       { AstTyped_base; AstNode* node; };
@@ -399,7 +402,7 @@ typedef enum EntityType {
     Entity_Type_Use_Package,
     Entity_Type_String_Literal,
     Entity_Type_Enum,
-    Entity_Type_Struct,
+    Entity_Type_Type_Alias,
     Entity_Type_Memory_Reservation,
     Entity_Type_Function_Header,
     Entity_Type_Global_Header,
@@ -420,7 +423,7 @@ typedef struct Entity {
         AstGlobal             *global;
         AstTyped              *expr;
         AstStrLit             *strlit;
-        AstStructType         *struct_type;
+        AstType               *type_alias;
         AstEnumType           *enum_type;
         AstMemRes             *mem_res;
     };
diff --git a/onyx b/onyx
index 4865923646d7e8f1f9a5ddd670b6a63fb449c24b..1174de4dbc1e2531fa922417313c7b2ce972e4cf 100755 (executable)
Binary files a/onyx and b/onyx differ
index 9258518839d8dccdd405208b758a413a7fb7dbc8..3fceb30ecc789911a68f7205c7994c0df5e0af72 100644 (file)
@@ -4,7 +4,7 @@ use "progs/intrinsics"
 use package printing
 
 call_me :: proc (f: proc (i32) -> i32, val: i32) {
-       f(val);
+    f(val);
 }
 
 funcs : [5] proc (i32, i32) -> i32
@@ -15,8 +15,11 @@ mul :: proc (a: i32, b: i32) -> i32 { return a * b; }
 div :: proc (a: i32, b: i32) -> i32 { return a / b; }
 mod :: proc (a: i32, b: i32) -> i32 { return a % b; }
 
+deferred_proc :: #type proc (i32, i32) -> i32
+my_int :: #type i32;
+
 DeferredCall :: struct {
-    func  : proc (i32, i32) -> i32;
+    func  : deferred_proc;
     left  : i32;
     right : i32;
 }
@@ -43,9 +46,9 @@ minus_one :: proc (n: i32) -> i32 { return n - 1; }
 double :: proc (n: i32) -> i32 { return n << 1; }
 
 proc #export "main" {
-       call_me(echo, 10);
+    call_me(echo, 10);
 
-    print(add as i32);
+    print(add as my_int);
 
     funcs[0] = add;
     funcs[1] = sub;
@@ -56,7 +59,7 @@ proc #export "main" {
     for i: 0, 5 print(funcs[i](10, 3));
 
     dc := __heap_start as ^DeferredCall;
-    dc.func = mod;
+    dc.func = add;
     dc.left = 40;
     dc.right = 19;
 
@@ -71,4 +74,35 @@ proc #export "main" {
 
     array_map(len, data, add_one);
     print(data as [] i32, len);
+
+    cheese := Cheeses.Cheddar;
+
+    // Closest thing to a switch statement at the moment
+    {
+        if cheese == Cheeses.Cheddar {
+            print(1);
+            break;
+        }
+
+        print(2);
+
+        if cheese == Cheeses.Muenster {
+            print(10);
+            break;
+        }
+
+        print(2);
+
+        if cheese == Cheeses.Mozerella {
+            print(100);
+            break;
+        }
+    }
+
 }
+
+Cheeses :: enum {
+    Cheddar;
+    Muenster;
+    Mozerella;
+}
\ No newline at end of file
index 4da00e579170cb1a7678ade5136c23795a49473e..6c12f62bfac79fd31aa82f48460ef5fc7b5d203f 100644 (file)
@@ -223,9 +223,10 @@ static void merge_parse_results(CompilerState* compiler_state, ParseResults* res
                 break;
             }
 
+            case Ast_Kind_Type_Alias:
             case Ast_Kind_Struct_Type: {
-                ent.type = Entity_Type_Struct;
-                ent.struct_type = (AstStructType *) node;
+                ent.type = Entity_Type_Type_Alias;
+                ent.type_alias = (AstType *) node;
                 bh_arr_push(compiler_state->prog_info.entities, ent);
                 break;
             }
index d73db301bc2be0c5fc07c05460d669199f0e3686..4f2281234fdcbf094a08d6f4cf12094372679892 100644 (file)
@@ -952,8 +952,9 @@ void onyx_type_check() {
                 if (check_expression(&entity->expr)) return;
                 break;
 
-            case Entity_Type_Struct:
-                if (check_struct(entity->struct_type)) return;
+            case Entity_Type_Type_Alias:
+                if (entity->type_alias->kind == Ast_Kind_Struct_Type)
+                    if (check_struct((AstStructType *) entity->type_alias)) return;
                 break;
 
             case Entity_Type_Enum: break;
index 6ea6d391c629dd07bb0dbbe60b949135541c5973..ea134310565195c2828a2baf1a8347d744a12c89 100644 (file)
@@ -1201,6 +1201,11 @@ static AstTyped* parse_top_level_expression(OnyxParser* parser) {
     else if (parser->curr->type == Token_Type_Keyword_Struct) {
         return (AstTyped *) parse_struct(parser);
     }
+    else if (parse_possible_directive(parser, "type")) {
+        AstTypeAlias* alias = make_node(AstTypeAlias, Ast_Kind_Type_Alias);
+        alias->to = parse_type(parser);
+        return (AstTyped *) alias;
+    }
     else if (parser->curr->type == Token_Type_Keyword_Enum) {
         return (AstTyped *) parse_enum_declaration(parser);
     }
index 1d286f98f5a31326f973a56d05014232d5d47533..a2bb30973793e194ba7ddd663428e1a52e096c00 100644 (file)
@@ -78,6 +78,11 @@ static void scope_leave() {
 static AstType* symres_type(AstType* type) {
     if (type == NULL) return NULL;
 
+    if (type->kind == Ast_Kind_Type_Alias) {
+        ((AstTypeAlias *) type)->to = symres_type(((AstTypeAlias *) type)->to);
+        return type;
+    }
+
     if (type->kind == Ast_Kind_Symbol) {
         return (AstType *) symbol_resolve(semstate.curr_scope, ((AstNode *) type)->token);
     }
@@ -524,7 +529,7 @@ void onyx_resolve_symbols() {
             case Entity_Type_Overloaded_Function: symres_overloaded_function(entity->overloaded_function); break;
             case Entity_Type_Global:              symres_global(entity->global); break;
             case Entity_Type_Expression:          symres_expression(&entity->expr); break;
-            case Entity_Type_Struct:              symres_type((AstType *) entity->struct_type); break;
+            case Entity_Type_Type_Alias:          entity->type_alias = symres_type(entity->type_alias); break;
             case Entity_Type_Enum:                symres_enum(entity->enum_type); break;
             case Entity_Type_Memory_Reservation:  symres_memres(&entity->mem_res); break;
 
index 45b18079f37007d9c51e757b2977fa779c41b433..1c94e1be9b25162b3d1839b6afcb9ec914d1fdf9 100644 (file)
@@ -321,6 +321,9 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) {
         case Ast_Kind_Basic_Type:
             return ((AstBasicType *) type_node)->type;
 
+        case Ast_Kind_Type_Alias:
+            return type_build_from_ast(alloc, ((AstTypeAlias *) type_node)->to);
+
         case Ast_Kind_Symbol:
             assert(("symbol node in type expression", 0));
             return NULL;
index ed3bd9da4e3172d6d81d3668f6e5751c856b8850..a8da138bf164e7e7a7190e9a3df5c86feb1d5ffc 100644 (file)
@@ -34,7 +34,8 @@ static const char* ast_node_names[] = {
     "FUNCTION_TYPE",
     "ARRAY TYPE",
     "STRUCT TYPE",
-    "ENUM TYPE"
+    "ENUM TYPE",
+    "TYPE_ALIAS",
     "TYPE_END (BAD)",
 
     "STRUCT MEMBER",