added 'use' statement for enums and variables of struct type
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 23 Sep 2020 14:26:53 +0000 (09:26 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 23 Sep 2020 14:26:53 +0000 (09:26 -0500)
Makefile
onyx
src/onyxchecker.c
src/onyxparser.c
src/onyxsymres.c
src/onyxutils.c

index 72e048278ea42b97ae1d7c4832eff6420b11df38..302e4efacfafe4c04903efe4c488a7423fce42e1 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -17,9 +17,13 @@ OBJ_FILES=\
 
 ifeq (, $(shell which tcc))
        CC=gcc
+else
+ifeq ($(RELEASE), 0)
+       CC=gcc
 else
        CC=tcc
 endif
+endif
 
 INCLUDES=-I./include
 LIBS=
diff --git a/onyx b/onyx
index bba7794e52e705e0c38c00ea8f08db022a93f1f8..cf023545d27a197208ecbb6be087a55cd56e6ede 100755 (executable)
Binary files a/onyx and b/onyx differ
index b12c866fa0fd26321de0322da9792a2ff2a53c76..5f9940ae97c771de5737c588c6eb7a99fe97148c 100644 (file)
@@ -978,14 +978,19 @@ b32 check_field_access(AstFieldAccess** pfield) {
         return 1;
     }
 
-    token_toggle_end(field->token);
     StructMember smem;
-    if (!type_lookup_member(field->expr->type, field->token->text, &smem)) {
+    if (field->token != NULL) {
+        token_toggle_end(field->token);
+        field->field = field->token->text;
+    }
+
+    if (!type_lookup_member(field->expr->type, field->field, &smem)) {
         onyx_report_error(field->token->pos,
             "Field '%s' does not exists on '%s'.",
-            field->token->text,
+            field->field,
             type_get_name(field->expr->type));
-        token_toggle_end(field->token);
+
+        if (field->token != NULL) token_toggle_end(field->token);
         return 1;
     }
 
@@ -993,7 +998,7 @@ b32 check_field_access(AstFieldAccess** pfield) {
     field->idx = smem.idx;
     field->type = smem.type;
 
-    token_toggle_end(field->token);
+    if (field->token != NULL) token_toggle_end(field->token);
     return 0;
 }
 
index 1d8b2a270827dc5191e5b930cae92199f04d0b04..be50983d8c83514fa1608fab8a5080a7cacae570 100644 (file)
@@ -1145,6 +1145,15 @@ static AstNode* parse_statement(OnyxParser* parser) {
             break;
         }
 
+        case Token_Type_Keyword_Use: {
+            AstUse* use_node = make_node(AstUse, Ast_Kind_Use);
+            use_node->token = expect_token(parser, Token_Type_Keyword_Use);
+            use_node->expr = parse_expression(parser);
+
+            retval = (AstNode *) use_node;
+            break;
+        }
+
         default:
             break;
     }
index 146494fe9b384e27592834700bf99fe43956b5ab..7abad05695b8a6af463bf489d1e383201ed909b8 100644 (file)
@@ -20,6 +20,7 @@ static void symres_if(AstIfWhile* ifnode);
 static void symres_while(AstIfWhile* whilenode);
 static void symres_for(AstFor* fornode);
 static void symres_switch(AstSwitch* switchnode);
+static void symres_use(AstUse* use);
 static void symres_statement_chain(AstNode** walker);
 static b32  symres_statement(AstNode** stmt);
 static void symres_block(AstBlock* block);
@@ -30,6 +31,14 @@ static void symres_use_package(AstUsePackage* package);
 static void symres_enum(AstEnumType* enum_node);
 static void symres_memres(AstMemRes** memres);
 
+static AstFieldAccess* make_field_access(AstTyped* node, char* field) {
+    AstFieldAccess* fa = onyx_ast_node_new(semstate.node_allocator, sizeof(AstFieldAccess), Ast_Kind_Field_Access);
+    fa->field = field;
+    fa->expr = node;
+
+    return fa;
+}
+
 static void scope_enter(Scope* new_scope) {
     // if (new_scope->parent == NULL)
     //     new_scope->parent = semstate.curr_scope;
@@ -457,6 +466,41 @@ static void symres_switch(AstSwitch* switchnode) {
     if (switchnode->assignment != NULL) scope_leave();
 }
 
+static void symres_use(AstUse* use) {
+    symres_expression(&use->expr);
+    if (use->expr == NULL) return;
+
+    if (use->expr->kind == Ast_Kind_Enum_Type) {
+        AstEnumType* et = (AstEnumType *) use->expr;
+
+        bh_arr_each(AstEnumValue *, ev, et->values)
+            symbol_introduce(semstate.curr_scope, (*ev)->token, (AstNode *) *ev);
+
+        return;
+    }
+
+    if (use->expr->type_node == NULL) goto cannot_use;
+
+    if (use->expr->type_node->kind == Ast_Kind_Struct_Type ||
+            use->expr->type_node->kind == Ast_Kind_Poly_Call_Type) {
+
+        if (use->expr->type == NULL)
+            use->expr->type = type_build_from_ast(semstate.node_allocator, use->expr->type_node);
+        if (use->expr->type == NULL) goto cannot_use;
+
+        Type* st = use->expr->type;
+        bh_arr_each(StructMember *, smem, st->Struct.memarr) {
+            AstFieldAccess* fa = make_field_access(use->expr, (*smem)->name);
+            symbol_raw_introduce(semstate.curr_scope, (*smem)->name, use->token->pos, (AstNode *) fa);
+        }
+
+        return;
+    }
+
+cannot_use:
+    onyx_report_error(use->token->pos, "Cannot use this.");
+}
+
 // NOTE: Returns 1 if the statment should be removed
 static b32 symres_statement(AstNode** stmt) {
     switch ((*stmt)->kind) {
@@ -470,6 +514,7 @@ static b32 symres_statement(AstNode** stmt) {
         case Ast_Kind_Argument:   symres_expression((AstTyped **) &((AstArgument *) *stmt)->value); return 0;
         case Ast_Kind_Block:      symres_block((AstBlock *) *stmt);                  return 0;
         case Ast_Kind_Defer:      symres_statement(&((AstDefer *) *stmt)->stmt);     return 0;
+        case Ast_Kind_Use:        symres_use((AstUse *) *stmt);                       return 1;
 
         case Ast_Kind_Jump:      return 0;
 
index 05eeb47803136c4026c03ceb80dfc5fa5f994444..0b66aaabd204ca1b9c0149305204e1f208b881b8 100644 (file)
@@ -82,6 +82,7 @@ static const char* ast_node_names[] = {
     "FOR",
     "WHILE",
     "JUMP",
+    "USE",
     "DEFER",
     "SWITCH",
     "SWITCH CASE",