From 7f5ee51f50b7e11629080fb18dc61abcb1e82596 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Sun, 5 Dec 2021 15:25:50 -0600 Subject: [PATCH] added #foreign blocks for quicker bulk definitions --- core/runtime/onyx_run.onyx | 14 ++++++++------ include/astnodes.h | 13 +++++++++++++ src/astnodes.c | 3 +++ src/entities.c | 8 ++++++++ src/parser.c | 17 +++++++++++++++++ src/symres.c | 30 ++++++++++++++++++++++++++++++ src/wasm_runtime.c | 12 ++++++------ 7 files changed, 85 insertions(+), 12 deletions(-) diff --git a/core/runtime/onyx_run.onyx b/core/runtime/onyx_run.onyx index 07a0e3ae..166f2ffd 100644 --- a/core/runtime/onyx_run.onyx +++ b/core/runtime/onyx_run.onyx @@ -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 diff --git a/include/astnodes.h b/include/astnodes.h index 66deb9a8..921f8ea7 100644 --- a/include/astnodes.h +++ b/include/astnodes.h @@ -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; diff --git a/src/astnodes.c b/src/astnodes.c index 77fe25f8..476124fe 100644 --- a/src/astnodes.c +++ b/src/astnodes.c @@ -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", diff --git a/src/entities.c b/src/entities.c index 3f707abe..b9940a1d 100644 --- a/src/entities.c +++ b/src/entities.c @@ -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; diff --git a/src/parser.c b/src/parser.c index 05832ab1..db6521c7 100644 --- a/src/parser.c +++ b/src/parser.c @@ -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; diff --git a/src/symres.c b/src/symres.c index 24b341bf..8786d70c 100644 --- a/src/symres.c +++ b/src/symres.c @@ -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; diff --git a/src/wasm_runtime.c b/src/wasm_runtime.c index 6a5d3dfb..f045b88f 100644 --- a/src/wasm_runtime.c +++ b/src/wasm_runtime.c @@ -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); -- 2.25.1