From 8041f0b511ffb63ba782b11dc9b9db6d8e7fe4c0 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Thu, 18 Jun 2020 22:09:00 -0500 Subject: [PATCH] Started work on importing external functions --- docs/plan | 1 + include/onyxparser.h | 13 ++++++++ onyx | Bin 149968 -> 151080 bytes progs/game.onyx | 16 ++++++++++ progs/minimal.onyx | 6 +++- src/onyxparser.c | 73 ++++++++++++++++++++++++++----------------- src/onyxutils.c | 19 ++++++++++- src/onyxwasm.c | 64 ++++++++++++++++++++----------------- 8 files changed, 133 insertions(+), 59 deletions(-) create mode 100644 progs/game.onyx diff --git a/docs/plan b/docs/plan index 66c9d3f8..21597ed3 100644 --- a/docs/plan +++ b/docs/plan @@ -55,6 +55,7 @@ HOW: [X] Curly braces are required for all bodies of blocks [X] Numeric literals are parsed [X] Numeric literals have the minimum type detected + [ ] Foreign imports (functions only) [ ] Comparison operators [ ] Proper boolean type [ ] Conditional branching works as expected diff --git a/include/onyxparser.h b/include/onyxparser.h index 80690f2f..b80e2cb9 100644 --- a/include/onyxparser.h +++ b/include/onyxparser.h @@ -13,6 +13,7 @@ typedef struct OnyxAstNodeScope OnyxAstNodeScope; typedef struct OnyxAstNodeBlock OnyxAstNodeBlock; typedef struct OnyxAstNodeParam OnyxAstNodeParam; typedef struct OnyxAstNodeFuncDef OnyxAstNodeFuncDef; +typedef struct OnyxAstNodeForeign OnyxAstNodeForeign; typedef struct OnyxAstNodeCall OnyxAstNodeCall; typedef struct OnyxParser { @@ -40,6 +41,7 @@ typedef enum OnyxAstNodeKind { ONYX_AST_NODE_KIND_PROGRAM, ONYX_AST_NODE_KIND_FUNCDEF, + ONYX_AST_NODE_KIND_FOREIGN, ONYX_AST_NODE_KIND_BLOCK, ONYX_AST_NODE_KIND_SCOPE, ONYX_AST_NODE_KIND_LOCAL, @@ -173,6 +175,16 @@ struct OnyxAstNodeFuncDef { OnyxAstNodeParam *params; }; +struct OnyxAstNodeForeign { + OnyxAstNodeKind kind; + u32 flags; + OnyxToken *mod_token; + OnyxTypeInfo *type; + OnyxAstNode *next; + OnyxToken *name_token; + OnyxAstNode *import; +}; + struct OnyxAstNodeCall { OnyxAstNodeKind kind; u32 flags; @@ -205,6 +217,7 @@ union OnyxAstNode { OnyxAstNodeScope as_scope; OnyxAstNodeCall as_call; OnyxAstNodeNumLit as_numlit; + OnyxAstNodeForeign as_foreign; }; const char* onyx_ast_node_kind_string(OnyxAstNodeKind kind); diff --git a/onyx b/onyx index 944178d4425bfbc47110af7efa3e051240acdc11..e09523b81a2d60ab26149a45a80840c4abdf1129 100755 GIT binary patch delta 51485 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 XYkT6Xw5Ik4!N$cDgg3GW)s+7L-9h6I delta 49030 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 diff --git a/progs/game.onyx b/progs/game.onyx new file mode 100644 index 00000000..85ac24da --- /dev/null +++ b/progs/game.onyx @@ -0,0 +1,16 @@ + +gfx_draw_rect :: foreign "gfx" "draw_rect" proc (x i32, y i32, w i32, h i32) --- + +update :: proc --- + +draw :: proc { + draw_rect(0, 0, 100, 100); +} + +export main :: proc { + + while true { + update(); + draw(); + } +} diff --git a/progs/minimal.onyx b/progs/minimal.onyx index 8b153fc7..83b863d6 100644 --- a/progs/minimal.onyx +++ b/progs/minimal.onyx @@ -1,4 +1,7 @@ -foo :: proc () -> i32 { + +print :: foreign "host" "print" proc (value i32) --- + +foo :: proc -> i32 { return 10 as i32; } @@ -17,6 +20,7 @@ diff_square :: proc (a i32, b i32) -> i32 { export do_stuff :: proc -> i32 { res := diff_square((4 + 5) as i32, (2 + 3) as i32); res = res + foo(); + // res should be 66 return res; } diff --git a/src/onyxparser.c b/src/onyxparser.c index 0c5d5dae..b0ad3861 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -7,6 +7,7 @@ static const char* ast_node_names[] = { "PROGRAM", "FUNCDEF", + "FOREIGN", "BLOCK", "SCOPE", "LOCAL", @@ -682,6 +683,32 @@ static OnyxAstNodeFuncDef* parse_function_definition(OnyxParser* parser) { return func_def; } +static OnyxAstNode* parse_top_level_symbol(OnyxParser* parser) { + if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_PROC) { + OnyxAstNodeFuncDef* func_def = parse_function_definition(parser); + return (OnyxAstNode *) func_def; + + } else if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_STRUCT) { + // Handle struct case + assert(0); + } else if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_FOREIGN) { + parser_next_token(parser); + + OnyxAstNodeForeign* foreign = (OnyxAstNodeForeign *) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_FOREIGN); + foreign->mod_token = expect(parser, TOKEN_TYPE_LITERAL_STRING); + foreign->name_token = expect(parser, TOKEN_TYPE_LITERAL_STRING); + foreign->import = parse_top_level_symbol(parser); + + return (OnyxAstNode *) foreign; + } else { + onyx_message_add(parser->msgs, + ONYX_MESSAGE_TYPE_UNEXPECTED_TOKEN, + parser->curr_token->pos, + onyx_get_token_type_name(parser->curr_token->type)); + return &error_node; + } +} + static OnyxAstNode* parse_top_level_statement(OnyxParser* parser) { switch (parser->curr_token->type) { case TOKEN_TYPE_KEYWORD_USE: @@ -713,38 +740,28 @@ static OnyxAstNode* parse_top_level_statement(OnyxParser* parser) { expect(parser, TOKEN_TYPE_SYM_COLON); expect(parser, TOKEN_TYPE_SYM_COLON); - if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_PROC) { - OnyxAstNodeFuncDef* func_def = parse_function_definition(parser); - func_def->token = symbol; + OnyxAstNode* node = parse_top_level_symbol(parser); + if (node->kind == ONYX_AST_NODE_KIND_FUNCDEF) { + node->token = symbol; - onyx_token_null_toggle(*symbol); + onyx_token_null_toggle(*symbol); - if (!bh_table_has(OnyxAstNode *, parser->identifiers, symbol->token)) { - bh_table_put(OnyxAstNode *, parser->identifiers, symbol->token, (OnyxAstNode *) func_def); - } else { - onyx_message_add(parser->msgs, - ONYX_MESSAGE_TYPE_FUNCTION_REDEFINITION, - symbol->pos, - symbol->token); + if (!bh_table_has(OnyxAstNode *, parser->identifiers, symbol->token)) { + bh_table_put(OnyxAstNode *, parser->identifiers, symbol->token, node); + } else { + onyx_message_add(parser->msgs, + ONYX_MESSAGE_TYPE_FUNCTION_REDEFINITION, + symbol->pos, + symbol->token); - // NOTE: I really wish C had defer... - onyx_token_null_toggle(*symbol); - return NULL; - } - - onyx_token_null_toggle(*symbol); - return (OnyxAstNode *) func_def; + // NOTE: I really wish C had defer... + onyx_token_null_toggle(*symbol); + return NULL; + } - } else if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_STRUCT) { - // Handle struct case - assert(0); - } else { - onyx_message_add(parser->msgs, - ONYX_MESSAGE_TYPE_UNEXPECTED_TOKEN, - parser->curr_token->pos, - onyx_get_token_type_name(parser->curr_token->type)); - break; - } + onyx_token_null_toggle(*symbol); + } + return node; } default: break; diff --git a/src/onyxutils.c b/src/onyxutils.c index 055932fd..5f0e97c9 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -19,7 +19,8 @@ void onyx_ast_print(OnyxAstNode* node, i32 indent) { } case ONYX_AST_NODE_KIND_FUNCDEF: { - bh_printf("(%b) ", node->token->token, node->token->length); + if (node->token) + bh_printf("(%b) ", node->token->token, node->token->length); OnyxAstNodeFuncDef* fd = &node->as_funcdef; print_indent; @@ -123,6 +124,22 @@ void onyx_ast_print(OnyxAstNode* node, i32 indent) { break; } + case ONYX_AST_NODE_KIND_FOREIGN: { + OnyxAstNodeForeign* foreign = &node->as_foreign; + bh_printf("%b:%b", + foreign->mod_token->token, foreign->mod_token->length, + foreign->name_token->token, foreign->name_token->length); + + if (foreign->import) { + onyx_ast_print(foreign->import, indent + 1); + } + + if (foreign->next) { + onyx_ast_print(foreign->next, indent); + } + break; + } + default: { onyx_ast_print(node->left, indent + 1); onyx_ast_print(node->right, indent + 1); diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 4d768fba..f4515a4a 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -506,33 +506,36 @@ static void process_function_definition(OnyxWasmModule* mod, OnyxAstNodeFuncDef* } // If there is no body then don't process the code - if (fd->body == NULL) return; - - // NOTE: Generate the local map - i32 localidx = 0; - forll (OnyxAstNodeParam, param, fd->params, next) { - bh_imap_put(&mod->local_map, (u64) param, localidx++); - } - - static const WasmType local_types[4] = { WASM_TYPE_INT32, WASM_TYPE_INT64, WASM_TYPE_FLOAT32, WASM_TYPE_FLOAT64 }; - - // HACK: This assumes that the order of the count members - // is the same as the order of the local_types above - u8* count = &wasm_func.locals.i32_count; - fori (ti, 0, 3) { - forll (OnyxAstNodeLocal, local, fd->body->scope->last_local, prev_local) { - if (onyx_type_to_wasm_type(local->type) == local_types[ti]) { - bh_imap_put(&mod->local_map, (u64) local, localidx++); - - (*count)++; - } - } + if (fd->body != NULL) { + // NOTE: Generate the local map + i32 localidx = 0; + forll (OnyxAstNodeParam, param, fd->params, next) { + bh_imap_put(&mod->local_map, (u64) param, localidx++); + } + + static const WasmType local_types[4] = { WASM_TYPE_INT32, WASM_TYPE_INT64, WASM_TYPE_FLOAT32, WASM_TYPE_FLOAT64 }; + + // HACK: This assumes that the order of the count members + // is the same as the order of the local_types above + u8* count = &wasm_func.locals.i32_count; + fori (ti, 0, 3) { + forll (OnyxAstNodeLocal, local, fd->body->scope->last_local, prev_local) { + if (onyx_type_to_wasm_type(local->type) == local_types[ti]) { + bh_imap_put(&mod->local_map, (u64) local, localidx++); + + (*count)++; + } + } - count++; - } + count++; + } - // Generate code - process_function_body(mod, &wasm_func, fd); + // Generate code + process_function_body(mod, &wasm_func, fd); + } else { + // NOTE: Empty bodies still need a block end instruction + bh_arr_push(wasm_func.code, ((WasmInstruction){ WI_BLOCK_END, 0x00 })); + } bh_arr_push(mod->funcs, wasm_func); @@ -540,6 +543,10 @@ static void process_function_definition(OnyxWasmModule* mod, OnyxAstNodeFuncDef* bh_imap_clear(&mod->local_map); } +void process_foreign(OnyxWasmModule* module, OnyxAstNodeForeign* foreign) { + +} + OnyxWasmModule onyx_wasm_generate_module(bh_allocator alloc, OnyxAstNode* program) { OnyxWasmModule module = { .allocator = alloc, @@ -570,6 +577,9 @@ OnyxWasmModule onyx_wasm_generate_module(bh_allocator alloc, OnyxAstNode* progra case ONYX_AST_NODE_KIND_FUNCDEF: process_function_definition(&module, &walker->as_funcdef); break; + case ONYX_AST_NODE_KIND_FOREIGN: + process_foreign(&module, &walker->as_foreign); + break; default: break; } @@ -804,10 +814,6 @@ static void output_instruction(WasmInstruction* instr, bh_buffer* buff) { case WI_LOCAL_GET: case WI_LOCAL_SET: case WI_CALL: - leb = uint_to_uleb128((u64) instr->data.i1, &leb_len); - bh_buffer_append(buff, leb, leb_len); - break; - case WI_BLOCK_START: leb = uint_to_uleb128((u64) instr->data.i1, &leb_len); bh_buffer_append(buff, leb, leb_len); -- 2.25.1