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
NODE(DirectiveInsert) \
NODE(Macro) \
\
+ NODE(ForeignBlock) \
+ \
NODE(Package)
#define NODE(name) typedef struct Ast ## name Ast ## name;
Ast_Kind_Macro,
Ast_Kind_Do_Block,
+ Ast_Kind_Foreign_Block,
+
Ast_Kind_Note,
Ast_Kind_Count
AstTyped* body;
};
+struct AstForeignBlock {
+ AstNode_base;
+
+ OnyxToken *module_name;
+ bh_arr(struct Entity *) captured_entities;
+};
+
typedef enum EntityState {
Entity_State_Error,
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,
AstMemRes *mem_res;
AstPolyProc *poly_proc;
AstPolyQuery *poly_query;
+ AstForeignBlock *foreign_block;
AstMacro *macro;
AstUse *use;
AstInterface *interface;
"MACRO",
"DO BLOCK",
+ "FOREIGN BLOCK",
+
"NOTE",
"AST_NODE_KIND_COUNT",
"Constraint Check",
"Polymorphic Proc",
"Polymorph Query",
+ "Foreign Block",
"Macro",
"Foreign_Function Header",
"Temporary Function Header",
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;
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;
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);
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;
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(),
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());
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());
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);
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);
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);