added #foreign blocks for quicker bulk definitions
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 5 Dec 2021 21:25:50 +0000 (15:25 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 5 Dec 2021 21:25:50 +0000 (15:25 -0600)
core/runtime/onyx_run.onyx
include/astnodes.h
src/astnodes.c
src/entities.c
src/parser.c
src/symres.c
src/wasm_runtime.c

index 07a0e3ae6862725269f32eddd6d473f721d1d2d3..166f2ffd6ad4d7f6c1ea27c55ff6b74a5ab6ac3a 100644 (file)
@@ -26,9 +26,11 @@ use package wasi
     InternalErr :: 0x03;
 }
 
-__process_spawn   :: (path: str, args: [] str, non_blocking_io: bool) -> os.Process.Handle #foreign "env" "process_spawn" ---
-__process_read    :: (handle: os.Process.Handle, buffer: [] u8) -> i32 #foreign "env" "process_read" ---
-__process_write   :: (handle: os.Process.Handle, buffer: [] u8) -> i32 #foreign "env" "process_write" ---
-__process_kill    :: (handle: os.Process.Handle) -> bool #foreign "env" "process_kill" ---
-__process_wait    :: (handle: os.Process.Handle) -> ProcessResult #foreign "env" "process_wait" ---
-__process_destroy :: (handle: os.Process.Handle) -> void #foreign "env" "process_destroy" ---
\ No newline at end of file
+#foreign "env" {
+    __process_spawn   :: (path: str, args: [] str, non_blocking_io: bool) -> os.Process.Handle ---
+    __process_read    :: (handle: os.Process.Handle, buffer: [] u8) -> i32 ---
+    __process_write   :: (handle: os.Process.Handle, buffer: [] u8) -> i32 ---
+    __process_kill    :: (handle: os.Process.Handle) -> bool ---
+    __process_wait    :: (handle: os.Process.Handle) -> ProcessResult ---
+    __process_destroy :: (handle: os.Process.Handle) -> void ---
+}
\ No newline at end of file
index 66deb9a877e2b0b24248ff033e7a292118d49ec3..921f8ea75f91a0cc681eba78bc467c29bf3015c6 100644 (file)
@@ -99,6 +99,8 @@
     NODE(DirectiveInsert)      \
     NODE(Macro)                \
                                \
+    NODE(ForeignBlock)         \
+                               \
     NODE(Package)          
 
 #define NODE(name) typedef struct Ast ## name Ast ## name;
@@ -214,6 +216,8 @@ typedef enum AstKind {
     Ast_Kind_Macro,
     Ast_Kind_Do_Block,
 
+    Ast_Kind_Foreign_Block,
+
     Ast_Kind_Note,
 
     Ast_Kind_Count
@@ -1268,6 +1272,13 @@ struct AstMacro {
     AstTyped* body;
 };
 
+struct AstForeignBlock {
+    AstNode_base;
+
+    OnyxToken *module_name;
+    bh_arr(struct Entity *) captured_entities;
+};
+
 typedef enum EntityState {
     Entity_State_Error,
     
@@ -1309,6 +1320,7 @@ typedef enum EntityType {
     Entity_Type_Polymorphic_Proc,
     Entity_Type_Polymorph_Query,
     Entity_Type_Macro,
+    Entity_Type_Foreign_Block,
     Entity_Type_Foreign_Function_Header,
     Entity_Type_Temp_Function_Header,    // Same as a Function_Header, except it disappears after it checks completely.
     Entity_Type_Function_Header,
@@ -1361,6 +1373,7 @@ typedef struct Entity {
         AstMemRes             *mem_res;
         AstPolyProc           *poly_proc;
         AstPolyQuery          *poly_query;
+        AstForeignBlock       *foreign_block;
         AstMacro              *macro;
         AstUse                *use;
         AstInterface          *interface;
index 77fe25f81ab43ce865f50d629bf7eece3780e408..476124fee8b89b13b22d7296ac54ea566ae8ee3f 100644 (file)
@@ -100,6 +100,8 @@ static const char* ast_node_names[] = {
     "MACRO",
     "DO BLOCK",
 
+    "FOREIGN BLOCK",
+
     "NOTE",
 
     "AST_NODE_KIND_COUNT",
@@ -157,6 +159,7 @@ const char* entity_type_strings[Entity_Type_Count] = {
     "Constraint Check",
     "Polymorphic Proc",
     "Polymorph Query",
+    "Foreign Block",
     "Macro",
     "Foreign_Function Header",
     "Temporary Function Header",
index 3f707abe51a6dc1df84ac9c9c00e6046220ce5b9..b9940a1d458122048dcfadaf6eb38f30be4848ec 100644 (file)
@@ -375,6 +375,14 @@ void add_entities_for_node(bh_arr(Entity *) *target_arr, AstNode* node, Scope* s
             break;
         }
 
+        case Ast_Kind_Foreign_Block: {
+            ent.type = Entity_Type_Foreign_Block;
+            ent.foreign_block = (AstForeignBlock *) node;
+            ent.state = Entity_State_Resolve_Symbols;
+            ENTITY_INSERT(ent);
+            break;
+        }
+
         default: {
             ent.type = Entity_Type_Expression;
             ent.expr = (AstTyped *) node;
index 05832ab1755b5f055ea7177bb334e461df3de6ba..db6521c7e487a82049b80adde0bcbfc92ae338ca 100644 (file)
@@ -2974,6 +2974,23 @@ static void parse_top_level_statement(OnyxParser* parser) {
                 ENTITY_SUBMIT(error);
                 return;
             }
+            else if (parse_possible_directive(parser, "foreign")) {
+                // :LinearTokenDependent
+                AstForeignBlock *fb = make_node(AstForeignBlock, Ast_Kind_Foreign_Block);
+                fb->token = parser->curr - 2;
+                fb->module_name = expect_token(parser, Token_Type_Literal_String);
+
+                bh_arr_new(global_heap_allocator, fb->captured_entities, 4);
+                bh_arr_push(parser->alternate_entity_placement_stack, &fb->captured_entities);
+
+                expect_token(parser, '{');
+                parse_top_level_statements_until(parser, '}');
+                expect_token(parser, '}');
+
+                bh_arr_pop(parser->alternate_entity_placement_stack);
+                ENTITY_SUBMIT(fb);
+                return;
+            }
             else if (parse_possible_directive(parser, "operator")) {
                 AstDirectiveOperator *operator = make_node(AstDirectiveOperator, Ast_Kind_Directive_Operator);
                 operator->token = dir_token;
index 24b341bf82be462913c1979d20aedd066b434354..8786d70ceaa428acb83694cf748cdf9b52af3a4a 100644 (file)
@@ -1348,6 +1348,34 @@ static SymresStatus symres_polyquery(AstPolyQuery *query) {
     return Symres_Success;
 }
 
+static SymresStatus symres_foreign_block(AstForeignBlock *fb) {
+    bh_arr_each(Entity *, pent, fb->captured_entities) {
+        Entity *ent = *pent;
+        if (ent->type == Entity_Type_Function_Header) {
+            if (ent->function->body->next != NULL) {
+                onyx_report_error(ent->function->token->pos, "Procedures declared in a #foreign block should not have bodies.");
+                return Symres_Error;
+            }
+
+            ent->function->foreign_name = ent->function->intrinsic_name; // Hmm... This might not be right?
+            ent->function->foreign_module = fb->module_name;
+            ent->function->is_foreign = 1;
+            ent->function->entity = NULL;
+            ent->function->entity_header = NULL;
+            ent->function->entity_body = NULL;
+
+            add_entities_for_node(NULL, (AstNode *) ent->function, ent->scope, ent->package);
+            continue;
+        }
+
+        if (ent->type != Entity_Type_Function) {
+            entity_heap_insert_existing(&context.entities, ent);
+        }
+    }
+
+    return Symres_Complete;
+}
+
 void symres_entity(Entity* ent) {
     if (ent->scope) scope_enter(ent->scope);
 
@@ -1394,12 +1422,14 @@ void symres_entity(Entity* ent) {
         case Entity_Type_Macro:                   ss = symres_macro(ent->macro); break;
         case Entity_Type_Constraint_Check:        ss = symres_constraint(ent->constraint); break;
         case Entity_Type_Polymorph_Query:         ss = symres_polyquery(ent->poly_query); break;
+        case Entity_Type_Foreign_Block:           ss = symres_foreign_block(ent->foreign_block); break;
 
         default: break;
     }
 
     if (ss == Symres_Yield_Macro) ent->macro_attempts++;
     if (ss == Symres_Yield_Micro) ent->micro_attempts++;
+    if (ss == Symres_Complete)    ent->state = Entity_State_Finalized;
     if (ss == Symres_Success) {
         ent->macro_attempts = 0;
         ent->micro_attempts = 0;
index 6a5d3dfb52e82a893f26a9b63d68d11368a894fc..f045b88f6eb1c245850992cc44e4d93dd1630b28 100644 (file)
@@ -600,7 +600,7 @@ b32 onyx_run_wasm(bh_buffer wasm_bytes) {
                 goto import_found;
             }
 
-            if (wasm_name_equals_string(import_name, "process_spawn")) {
+            if (wasm_name_equals_string(import_name, "__process_spawn")) {
                 wasm_valtype_t* ps[5] = {
                     wasm_valtype_new_i32(), wasm_valtype_new_i32(),
                     wasm_valtype_new_i32(), wasm_valtype_new_i32(),
@@ -617,7 +617,7 @@ b32 onyx_run_wasm(bh_buffer wasm_bytes) {
                 goto import_found;
             }
 
-            if (wasm_name_equals_string(import_name, "process_read")) {
+            if (wasm_name_equals_string(import_name, "__process_read")) {
                 wasm_functype_t* func_type = wasm_functype_new_3_1(
                     wasm_valtype_new_i64(), wasm_valtype_new_i32(), wasm_valtype_new_i32(),
                     wasm_valtype_new_i32());
@@ -627,7 +627,7 @@ b32 onyx_run_wasm(bh_buffer wasm_bytes) {
                 goto import_found;
             }
 
-            if (wasm_name_equals_string(import_name, "process_write")) {
+            if (wasm_name_equals_string(import_name, "__process_write")) {
                 wasm_functype_t* func_type = wasm_functype_new_3_1(
                     wasm_valtype_new_i64(), wasm_valtype_new_i32(), wasm_valtype_new_i32(),
                     wasm_valtype_new_i32());
@@ -637,7 +637,7 @@ b32 onyx_run_wasm(bh_buffer wasm_bytes) {
                 goto import_found;
             }
 
-            if (wasm_name_equals_string(import_name, "process_kill")) {
+            if (wasm_name_equals_string(import_name, "__process_kill")) {
                 wasm_functype_t* func_type = wasm_functype_new_1_1(wasm_valtype_new_i64(), wasm_valtype_new_i32());
 
                 wasm_func_t* wasm_func = wasm_func_new(wasm_store, func_type, onyx_process_kill_impl);
@@ -645,7 +645,7 @@ b32 onyx_run_wasm(bh_buffer wasm_bytes) {
                 goto import_found;
             }
 
-            if (wasm_name_equals_string(import_name, "process_wait")) {
+            if (wasm_name_equals_string(import_name, "__process_wait")) {
                 wasm_functype_t* func_type = wasm_functype_new_1_1(wasm_valtype_new_i64(), wasm_valtype_new_i32());
 
                 wasm_func_t* wasm_func = wasm_func_new(wasm_store, func_type, onyx_process_wait_impl);
@@ -653,7 +653,7 @@ b32 onyx_run_wasm(bh_buffer wasm_bytes) {
                 goto import_found;
             }
 
-            if (wasm_name_equals_string(import_name, "process_destroy")) {
+            if (wasm_name_equals_string(import_name, "__process_destroy")) {
                 wasm_functype_t* func_type = wasm_functype_new_1_0(wasm_valtype_new_i64());
 
                 wasm_func_t* wasm_func = wasm_func_new(wasm_store, func_type, onyx_process_destroy_impl);