#define ONYX_MSG_BUFFER_SIZE 256
-typedef enum OnyxMessageType {
- ONYX_MESSAGE_TYPE_LITERAL,
- ONYX_MESSAGE_TYPE_EXPECTED_TOKEN,
- ONYX_MESSAGE_TYPE_UNEXPECTED_TOKEN,
- ONYX_MESSAGE_TYPE_UNKNOWN_TYPE,
- ONYX_MESSAGE_TYPE_NOT_LVAL,
- ONYX_MESSAGE_TYPE_ASSIGN_CONST,
- ONYX_MESSAGE_TYPE_UNKNOWN_SYMBOL,
- ONYX_MESSAGE_TYPE_UNKNOWN_DIRECTIVE,
-
- ONYX_MESSAGE_TYPE_REDECLARE_SYMBOL,
- ONYX_MESSAGE_TYPE_BINOP_MISMATCH_TYPE,
- ONYX_MESSAGE_TYPE_ASSIGNMENT_TYPE_MISMATCH,
- ONYX_MESSAGE_TYPE_GLOBAL_TYPE_MISMATCH,
- ONYX_MESSAGE_TYPE_EXPECTED_EXPRESSION,
- ONYX_MESSAGE_TYPE_CALL_NON_FUNCTION,
-
- ONYX_MESSAGE_TYPE_FUNCTION_RETURN_MISMATCH,
- ONYX_MESSAGE_TYPE_FUNCTION_PARAM_TYPE_MISMATCH,
-
- ONYX_MESSAGE_TYPE_UNRESOLVED_TYPE,
- ONYX_MESSAGE_TYPE_UNRESOLVED_SYMBOL,
-
- ONYX_MESSAGE_TYPE_COUNT,
-} OnyxMessageType;
-
-typedef struct OnyxMessage {
- OnyxMessageType type;
+typedef enum MsgType {
+ Msg_Type_Literal,
+ Msg_Type_Expected_Token,
+ Msg_Type_Unexpected_Token,
+ Msg_Type_Unknown_Type,
+ Msg_Type_Not_Lval,
+ Msg_Type_Assign_Const,
+ Msg_Type_Unknown_Symbol,
+ Msg_Type_Unknown_Directive,
+
+ Msg_Type_Redeclare_Symbol,
+ Msg_Type_Binop_Mismatch,
+ Msg_Type_Assignment_Mismatch,
+ Msg_Type_Global_Type_Mismatch,
+ Msg_Type_Expected_Expression,
+ Msg_Type_Call_Non_Function,
+
+ Msg_Type_Function_Return_Mismatch,
+ Msg_Type_Function_Param_Mismatch,
+
+ Msg_Type_Unresolved_Type,
+ Msg_Type_Unresolved_Symbol,
+
+ Msg_Type_Count,
+} MsgType;
+
+typedef struct Message {
+ MsgType type;
OnyxFilePos pos;
- struct OnyxMessage* next;
+ struct Message* next;
char text[ONYX_MSG_BUFFER_SIZE];
-} OnyxMessage;
+} Message;
typedef struct OnyxMessages {
bh_allocator allocator;
// their file contents. Used for better error messages
bh_table(bh_file_contents)* file_contents;
- OnyxMessage* first;
+ Message* first;
} OnyxMessages;
-void onyx_message_add(OnyxMessages* msgs, OnyxMessageType type, OnyxFilePos pos, ...);
-void onyx_message_print(OnyxMessages* msgs);
-b32 onyx_message_has_errors(OnyxMessages* msgs);
-void onyx_message_create(bh_allocator allocator, OnyxMessages* msgs, bh_table(bh_file_contents)* files);
+extern OnyxMessages msgs;
+
+void onyx_message_init(bh_allocator allocator, bh_table(bh_file_contents)* files);
+void onyx_message_add(MsgType type, OnyxFilePos pos, ...);
+void onyx_message_print();
+b32 onyx_message_has_errors();
#endif
OnyxToken *prev;
OnyxToken *curr;
- OnyxMessages *msgs;
-
ParseResults results;
} OnyxParser;
const char* onyx_ast_node_kind_string(AstKind kind);
void* onyx_ast_node_new(bh_allocator alloc, i32 size, AstKind kind);
-OnyxParser onyx_parser_create(bh_allocator alloc, OnyxTokenizer *tokenizer, OnyxMessages* msgs);
+OnyxParser onyx_parser_create(bh_allocator alloc, OnyxTokenizer *tokenizer);
void onyx_parser_free(OnyxParser* parser);
ParseResults onyx_parse(OnyxParser *parser);
// NOTE: Adding node_allocator in case we need
// to make any more node in the tree
bh_allocator allocator, node_allocator;
- OnyxMessages *msgs;
// NOTE: Used in symbol resolution phase
Scope* global_scope;
Type* expected_return_type;
} SemState;
+extern SemState semstate;
+
// NOTE: Resolving all symbols in the tree
-void onyx_resolve_symbols(SemState* state, ProgramInfo* program);
+void onyx_resolve_symbols(ProgramInfo* program);
// NOTE: Inferring and checking types in the tree
-void onyx_type_check(SemState* state, ProgramInfo* program);
+void onyx_type_check(ProgramInfo* program);
// NOTE: Full semantic pass
-SemState onyx_sempass_create(bh_allocator alloc, bh_allocator node_alloc, OnyxMessages* msgs);
-void onyx_sempass(SemState* state, ProgramInfo* program);
+void onyx_sempass_init(bh_allocator alloc, bh_allocator node_alloc);
+void onyx_sempass(ProgramInfo* program);
#endif
typedef struct OnyxWasmModule {
bh_allocator allocator;
- OnyxMessages* msgs;
// NOTE: Mapping ptrs to function / global indicies
bh_imap index_map;
u32 next_datum_offset;
} OnyxWasmModule;
-OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc, OnyxMessages* msgs);
+OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc);
void onyx_wasm_module_compile(OnyxWasmModule* module, ProgramInfo* program);
void onyx_wasm_module_free(OnyxWasmModule* module);
void onyx_wasm_module_write_to_file(OnyxWasmModule* module, bh_file file);
other_str :: "I can't believe this \n actually fricken worked!";
-str_test :: proc #export "main" {
+str_test :: proc {
hello_str :: "Hello World!";
walker := other_str;
walker = (walker as i32 + 1) as ^u8;
}
+
+ print("This is a test"[10] as i32);
}
// Don't need to bind this function to a symbol
-proc #export "main2" {
+proc #export "main" {
print(min(10.0, 12.0));
- global_arr = 0 as ^i32;
+ global_arr = 128 as ^i32;
len :: 10;
i := 0;
print(1234567);
print(global_arr, len);
+
+ str_test();
}
bh_table(bh_file_contents) loaded_files;
bh_arr(const char *) queued_files;
- OnyxMessages msgs;
ProgramInfo prog_info;
OnyxWasmModule wasm_mod;
} CompilerState;
bh_table_init(opts->allocator, compiler_state->loaded_files, 15);
- onyx_message_create(compiler_state->msg_alloc, &compiler_state->msgs, &compiler_state->loaded_files);
+ onyx_message_init(compiler_state->msg_alloc, &compiler_state->loaded_files);
compiler_state->token_alloc = opts->allocator;
if (compiler_state->options->verbose_output)
bh_printf("[Parsing] %s\n", file_contents->filename);
- OnyxParser parser = onyx_parser_create(compiler_state->ast_alloc, &tokenizer, &compiler_state->msgs);
+ OnyxParser parser = onyx_parser_create(compiler_state->ast_alloc, &tokenizer);
return onyx_parse(&parser);
}
ParseResults results = parse_source_file(compiler_state, &fc);
merge_parse_results(compiler_state, &results);
- if (onyx_message_has_errors(&compiler_state->msgs)) {
+ if (onyx_message_has_errors()) {
return ONYX_COMPILER_PROGRESS_FAILED_PARSE;
} else {
return ONYX_COMPILER_PROGRESS_SUCCESS;
if (compiler_state->options->verbose_output)
bh_printf("[Checking semantics]\n");
- SemState sp_state = onyx_sempass_create(compiler_state->sp_alloc, compiler_state->ast_alloc, &compiler_state->msgs);
- onyx_sempass(&sp_state, &compiler_state->prog_info);
+ onyx_sempass_init(compiler_state->sp_alloc, compiler_state->ast_alloc);
+ onyx_sempass(&compiler_state->prog_info);
- if (onyx_message_has_errors(&compiler_state->msgs)) {
+ if (onyx_message_has_errors()) {
return ONYX_COMPILER_PROGRESS_FAILED_SEMPASS;
}
if (compiler_state->options->verbose_output)
bh_printf("[Generating WASM]\n");
- compiler_state->wasm_mod = onyx_wasm_module_create(compiler_state->options->allocator, &compiler_state->msgs);
+ compiler_state->wasm_mod = onyx_wasm_module_create(compiler_state->options->allocator);
onyx_wasm_module_compile(&compiler_state->wasm_mod, &compiler_state->prog_info);
- if (onyx_message_has_errors(&compiler_state->msgs)) {
+ if (onyx_message_has_errors()) {
return ONYX_COMPILER_PROGRESS_FAILED_BINARY_GEN;
}
case ONYX_COMPILER_PROGRESS_FAILED_PARSE:
case ONYX_COMPILER_PROGRESS_FAILED_SEMPASS:
case ONYX_COMPILER_PROGRESS_FAILED_BINARY_GEN:
- onyx_message_print(&compile_state.msgs);
+ onyx_message_print();
break;
case ONYX_COMPILER_PROGRESS_FAILED_OUTPUT:
#include "onyxsempass.h"
#include "onyxparser.h"
-#define CHECK(kind, ...) static b32 check_ ## kind (SemState* state, __VA_ARGS__)
+#define CHECK(kind, ...) static b32 check_ ## kind (__VA_ARGS__)
CHECK(block, AstBlock* block);
CHECK(statement_chain, AstNode* start);
CHECK(function, AstFunction* func);
CHECK(overloaded_function, AstOverloadedFunction* func);
-static inline void fill_in_type(SemState* state, AstTyped* node) {
+static inline void fill_in_type(AstTyped* node) {
if (node->type == NULL)
- node->type = type_build_from_ast(state->allocator, node->type_node);
+ node->type = type_build_from_ast(semstate.allocator, node->type_node);
}
CHECK(return, AstReturn* retnode) {
if (retnode->expr) {
- if (check_expression(state, retnode->expr)) return 1;
+ if (check_expression(retnode->expr)) return 1;
- if (!types_are_compatible(retnode->expr->type, state->expected_return_type)) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_FUNCTION_RETURN_MISMATCH,
+ if (!types_are_compatible(retnode->expr->type, semstate.expected_return_type)) {
+ onyx_message_add(Msg_Type_Function_Return_Mismatch,
retnode->expr->token->pos,
type_get_name(retnode->expr->type),
- type_get_name(state->expected_return_type));
+ type_get_name(semstate.expected_return_type));
return 1;
}
} else {
- if (state->expected_return_type->Basic.size > 0) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_LITERAL,
+ if (semstate.expected_return_type->Basic.size > 0) {
+ onyx_message_add(Msg_Type_Literal,
retnode->token->pos,
"returning from non-void function without value");
return 1;
}
CHECK(if, AstIf* ifnode) {
- if (check_expression(state, ifnode->cond)) return 1;
+ if (check_expression(ifnode->cond)) return 1;
if (!type_is_bool(ifnode->cond->type)) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_LITERAL,
+ onyx_message_add(Msg_Type_Literal,
ifnode->cond->token->pos,
"expected boolean type for condition");
return 1;
}
- if (ifnode->true_stmt) if (check_statement(state, ifnode->true_stmt)) return 1;
- if (ifnode->false_stmt) if (check_statement(state, ifnode->false_stmt)) return 1;
+ if (ifnode->true_stmt) if (check_statement(ifnode->true_stmt)) return 1;
+ if (ifnode->false_stmt) if (check_statement(ifnode->false_stmt)) return 1;
return 0;
}
CHECK(while, AstWhile* whilenode) {
- if (check_expression(state, whilenode->cond)) return 1;
+ if (check_expression(whilenode->cond)) return 1;
if (!type_is_bool(whilenode->cond->type)) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_LITERAL,
+ onyx_message_add(Msg_Type_Literal,
whilenode->cond->token->pos,
"expected boolean type for condition");
return 1;
}
- return check_statement(state, whilenode->stmt);
+ return check_statement(whilenode->stmt);
}
-static AstTyped* match_overloaded_function(SemState* state, AstCall* call, AstOverloadedFunction* ofunc) {
+static AstTyped* match_overloaded_function(AstCall* call, AstOverloadedFunction* ofunc) {
bh_arr_each(AstTyped *, node, ofunc->overloads) {
AstFunction* overload = (AstFunction *) *node;
- fill_in_type(state, (AstTyped *) overload);
+ fill_in_type((AstTyped *) overload);
TypeFunction* ol_type = &overload->type->Function;
AstArgument* arg = call->arguments;
Type** param_type = ol_type->params;
while (arg != NULL) {
- fill_in_type(state, (AstTyped *) arg);
+ fill_in_type((AstTyped *) arg);
if (!types_are_compatible(*param_type, arg->type)) goto no_match;
continue;
}
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_LITERAL,
+ onyx_message_add(Msg_Type_Literal,
call->token->pos,
"unable to match overloaded function");
AstFunction* callee = (AstFunction *) call->callee;
if (callee->kind == Ast_Kind_Symbol) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_UNRESOLVED_SYMBOL,
+ onyx_message_add(Msg_Type_Unresolved_Symbol,
callee->token->pos,
callee->token->text, callee->token->length);
return 1;
// NOTE: Check arguments
AstArgument* actual_param = call->arguments;
while (actual_param != NULL) {
- if (check_expression(state, (AstTyped *) actual_param)) return 1;
+ if (check_expression((AstTyped *) actual_param)) return 1;
actual_param = (AstArgument *) actual_param->next;
}
if (callee->kind == Ast_Kind_Overloaded_Function) {
- call->callee = (AstNode *) match_overloaded_function(state, call, (AstOverloadedFunction *) callee);
+ call->callee = (AstNode *) match_overloaded_function(call, (AstOverloadedFunction *) callee);
callee = (AstFunction *) call->callee;
if (callee == NULL) return 1;
}
// NOTE: Build callee's type
- fill_in_type(state, (AstTyped *) callee);
+ fill_in_type((AstTyped *) callee);
if (callee->type->kind != Type_Kind_Function) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_CALL_NON_FUNCTION,
+ onyx_message_add(Msg_Type_Call_Non_Function,
call->token->pos,
callee->token->text, callee->token->length);
return 1;
i32 arg_pos = 0;
while (formal_param != NULL && actual_param != NULL) {
- fill_in_type(state, (AstTyped *) formal_param);
+ fill_in_type((AstTyped *) formal_param);
if (!types_are_compatible(formal_param->type, actual_param->type)) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_FUNCTION_PARAM_TYPE_MISMATCH,
+ onyx_message_add(Msg_Type_Function_Param_Mismatch,
actual_param->token->pos,
callee->token->text, callee->token->length,
type_get_name(formal_param->type),
}
if (formal_param != NULL && actual_param == NULL) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_LITERAL,
+ onyx_message_add(Msg_Type_Literal,
call->token->pos,
"too few arguments to function call");
return 1;
}
if (formal_param == NULL && actual_param != NULL) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_LITERAL,
+ onyx_message_add(Msg_Type_Literal,
call->token->pos,
"too many arguments to function call");
return 1;
}
CHECK(binaryop, AstBinaryOp* binop) {
- if (check_expression(state, binop->left)) return 1;
- if (check_expression(state, binop->right)) return 1;
+ if (check_expression(binop->left)) return 1;
+ if (check_expression(binop->right)) return 1;
if (binop_is_assignment(binop)) {
if (!is_lval((AstNode *) binop->left)) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_NOT_LVAL,
+ onyx_message_add(Msg_Type_Not_Lval,
binop->left->token->pos,
binop->left->token->text, binop->left->token->length);
return 1;
}
if ((binop->left->flags & Ast_Flag_Const) != 0 && binop->left->type != NULL) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_ASSIGN_CONST,
+ onyx_message_add(Msg_Type_Assign_Const,
binop->token->pos,
binop->left->token->text, binop->left->token->length);
return 1;
// NOTE: +=, -=, ...
AstBinaryOp* binop_node = onyx_ast_node_new(
- state->node_allocator,
+ semstate.node_allocator,
sizeof(AstBinaryOp),
Ast_Kind_Binary_Op);
} else {
if (type_is_pointer(binop->left->type)
|| type_is_pointer(binop->right->type)) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_LITERAL,
+ onyx_message_add(Msg_Type_Literal,
binop->token->pos,
"binary operations are not supported for pointers (yet).");
return 1;
}
if (binop->left->type == NULL) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_UNRESOLVED_TYPE,
+ onyx_message_add(Msg_Type_Unresolved_Type,
binop->token->pos,
binop->left->token->text, binop->left->token->length);
return 1;
}
if (binop->right->type == NULL) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_UNRESOLVED_TYPE,
+ onyx_message_add(Msg_Type_Unresolved_Type,
binop->token->pos,
binop->right->token->text, binop->right->token->length);
return 1;
if (!types_are_compatible(binop->left->type, binop->right->type)) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_BINOP_MISMATCH_TYPE,
+ onyx_message_add(Msg_Type_Binop_Mismatch,
binop->token->pos,
type_get_name(binop->left->type),
type_get_name(binop->right->type));
}
CHECK(array_access, AstArrayAccess* aa) {
- check_expression(state, aa->addr);
- check_expression(state, aa->expr);
+ check_expression(aa->addr);
+ check_expression(aa->expr);
if (!type_is_pointer(aa->addr->type)) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_LITERAL,
+ onyx_message_add(Msg_Type_Literal,
aa->token->pos,
"expected pointer type for left of array access");
return 1;
if (aa->expr->type->kind != Type_Kind_Basic
|| (aa->expr->type->Basic.flags & Basic_Flag_Integer) == 0) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_LITERAL,
+ onyx_message_add(Msg_Type_Literal,
aa->token->pos,
"expected integer type for index");
return 1;
CHECK(expression, AstTyped* expr) {
if (expr->kind > Ast_Kind_Type_Start && expr->kind < Ast_Kind_Type_End) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_LITERAL,
+ onyx_message_add(Msg_Type_Literal,
(OnyxFilePos) { 0 },
"type used as part of an expression");
return 1;
}
- fill_in_type(state, expr);
+ fill_in_type(expr);
i32 retval = 0;
switch (expr->kind) {
- case Ast_Kind_Binary_Op: retval = check_binaryop(state, (AstBinaryOp *) expr); break;
+ case Ast_Kind_Binary_Op: retval = check_binaryop((AstBinaryOp *) expr); break;
case Ast_Kind_Unary_Op:
- retval = check_expression(state, ((AstUnaryOp *) expr)->expr);
+ retval = check_expression(((AstUnaryOp *) expr)->expr);
if (((AstUnaryOp *) expr)->operation != Unary_Op_Cast) {
expr->type = ((AstUnaryOp *) expr)->expr->type;
}
break;
- case Ast_Kind_Call: retval = check_call(state, (AstCall *) expr); break;
- case Ast_Kind_Block: retval = check_block(state, (AstBlock *) expr); break;
+ case Ast_Kind_Call: retval = check_call((AstCall *) expr); break;
+ case Ast_Kind_Block: retval = check_block((AstBlock *) expr); break;
case Ast_Kind_Symbol:
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_UNRESOLVED_SYMBOL,
+ onyx_message_add(Msg_Type_Unresolved_Symbol,
expr->token->pos,
expr->token->text, expr->token->length);
retval = 1;
case Ast_Kind_Param:
if (expr->type == NULL) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_LITERAL,
+ onyx_message_add(Msg_Type_Literal,
expr->token->pos,
"local variable with unknown type");
retval = 1;
case Ast_Kind_Local: break;
case Ast_Kind_Array_Access:
- retval = check_array_access(state, (AstArrayAccess *) expr);
+ retval = check_array_access((AstArrayAccess *) expr);
break;
case Ast_Kind_Global:
if (expr->type == NULL) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_LITERAL,
+ onyx_message_add(Msg_Type_Literal,
expr->token->pos,
"global with unknown type");
retval = 1;
break;
case Ast_Kind_Argument:
- retval = check_expression(state, ((AstArgument *) expr)->value);
+ retval = check_expression(((AstArgument *) expr)->value);
expr->type = ((AstArgument *) expr)->value->type;
break;
}
CHECK(global, AstGlobal* global) {
- fill_in_type(state, (AstTyped *) global);
+ fill_in_type((AstTyped *) global);
if (global->type == NULL) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_UNRESOLVED_TYPE,
+ onyx_message_add(Msg_Type_Unresolved_Type,
global->token->pos,
global->exported_name->text,
global->exported_name->length);
CHECK(statement, AstNode* stmt) {
switch (stmt->kind) {
- case Ast_Kind_Return: return check_return(state, (AstReturn *) stmt);
- case Ast_Kind_If: return check_if(state, (AstIf *) stmt);
- case Ast_Kind_While: return check_while(state, (AstWhile *) stmt);
- case Ast_Kind_Call: return check_call(state, (AstCall *) stmt);
- case Ast_Kind_Block: return check_block(state, (AstBlock *) stmt);
+ case Ast_Kind_Return: return check_return((AstReturn *) stmt);
+ case Ast_Kind_If: return check_if((AstIf *) stmt);
+ case Ast_Kind_While: return check_while((AstWhile *) stmt);
+ case Ast_Kind_Call: return check_call((AstCall *) stmt);
+ case Ast_Kind_Block: return check_block((AstBlock *) stmt);
case Ast_Kind_Break: return 0;
case Ast_Kind_Continue: return 0;
default:
stmt->flags |= Ast_Flag_Expr_Ignored;
- return check_expression(state, (AstTyped *) stmt);
+ return check_expression((AstTyped *) stmt);
}
}
CHECK(statement_chain, AstNode* start) {
while (start) {
- if (check_statement(state, start)) return 1;
+ if (check_statement(start)) return 1;
start = start->next;
}
}
CHECK(block, AstBlock* block) {
- if (check_statement_chain(state, block->body)) return 1;
+ if (check_statement_chain(block->body)) return 1;
bh_table_each_start(AstTyped *, block->scope->symbols);
if (value->type == NULL) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_UNRESOLVED_TYPE,
+ onyx_message_add(Msg_Type_Unresolved_Type,
value->token->pos,
value->token->text, value->token->length);
return 1;
CHECK(function, AstFunction* func) {
for (AstLocal *param = func->params; param != NULL; param = (AstLocal *) param->next) {
- fill_in_type(state, (AstTyped *) param);
+ fill_in_type((AstTyped *) param);
if (param->type == NULL) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_LITERAL,
+ onyx_message_add(Msg_Type_Literal,
param->token->pos,
"function parameter types must be known");
return 1;
}
if (param->type->Basic.size == 0) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_LITERAL,
+ onyx_message_add(Msg_Type_Literal,
param->token->pos,
"function parameters must have non-void types");
return 1;
}
}
- fill_in_type(state, (AstTyped *) func);
+ fill_in_type((AstTyped *) func);
if ((func->flags & Ast_Flag_Exported) != 0) {
if ((func->flags & Ast_Flag_Foreign) != 0) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_LITERAL,
+ onyx_message_add(Msg_Type_Literal,
func->token->pos,
"exporting a foreign function");
return 1;
}
if ((func->flags & Ast_Flag_Intrinsic) != 0) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_LITERAL,
+ onyx_message_add(Msg_Type_Literal,
func->token->pos,
"exporting a intrinsic function");
return 1;
}
if ((func->flags & Ast_Flag_Inline) != 0) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_LITERAL,
+ onyx_message_add(Msg_Type_Literal,
func->token->pos,
"exporting a inlined function");
return 1;
}
if (func->exported_name == NULL) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_LITERAL,
+ onyx_message_add(Msg_Type_Literal,
func->token->pos,
"exporting function without a name");
return 1;
}
}
- state->expected_return_type = func->type->Function.return_type;
+ semstate.expected_return_type = func->type->Function.return_type;
if (func->body) {
- return check_block(state, func->body);
+ return check_block(func->body);
}
return 0;
CHECK(overloaded_function, AstOverloadedFunction* func) {
bh_arr_each(AstTyped *, node, func->overloads) {
if ((*node)->kind == Ast_Kind_Overloaded_Function) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_LITERAL,
+ onyx_message_add(Msg_Type_Literal,
(*node)->token->pos,
"overload option can not be another overloaded function (yet)");
}
if ((*node)->kind != Ast_Kind_Function) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_LITERAL,
+ onyx_message_add(Msg_Type_Literal,
(*node)->token->pos,
"overload option not function");
CHECK(node, AstNode* node) {
switch (node->kind) {
- case Ast_Kind_Function: return check_function(state, (AstFunction *) node);
- case Ast_Kind_Overloaded_Function: return check_overloaded_function(state, (AstOverloadedFunction *) node);
- case Ast_Kind_Block: return check_block(state, (AstBlock *) node);
- case Ast_Kind_Return: return check_return(state, (AstReturn *) node);
- case Ast_Kind_If: return check_if(state, (AstIf *) node);
- case Ast_Kind_While: return check_while(state, (AstWhile *) node);
- case Ast_Kind_Call: return check_call(state, (AstCall *) node);
- case Ast_Kind_Binary_Op: return check_binaryop(state, (AstBinaryOp *) node);
- default: return check_expression(state, (AstTyped *) node);
+ case Ast_Kind_Function: return check_function((AstFunction *) node);
+ case Ast_Kind_Overloaded_Function: return check_overloaded_function((AstOverloadedFunction *) node);
+ case Ast_Kind_Block: return check_block((AstBlock *) node);
+ case Ast_Kind_Return: return check_return((AstReturn *) node);
+ case Ast_Kind_If: return check_if((AstIf *) node);
+ case Ast_Kind_While: return check_while((AstWhile *) node);
+ case Ast_Kind_Call: return check_call((AstCall *) node);
+ case Ast_Kind_Binary_Op: return check_binaryop((AstBinaryOp *) node);
+ default: return check_expression((AstTyped *) node);
}
}
-void onyx_type_check(SemState* state, ProgramInfo* program) {
+void onyx_type_check(ProgramInfo* program) {
bh_arr_each(Entity, entity, program->entities) {
switch (entity->type) {
case Entity_Type_Function:
if (entity->function->flags & Ast_Kind_Foreign) program->foreign_func_count++;
- if (check_function(state, entity->function)) return;
+ if (check_function(entity->function)) return;
break;
case Entity_Type_Overloaded_Function:
- if (check_overloaded_function(state, entity->overloaded_function)) return;
+ if (check_overloaded_function(entity->overloaded_function)) return;
break;
case Entity_Type_Global:
if (entity->global->flags & Ast_Kind_Foreign) program->foreign_global_count++;
- if (check_global(state, entity->global)) return;
+ if (check_global(entity->global)) return;
break;
case Entity_Type_Expression:
- if (check_expression(state, entity->expr)) return;
+ if (check_expression(entity->expr)) return;
break;
case Entity_Type_String_Literal: break;
#define MAX_MSGS 10
+OnyxMessages msgs;
+
static const char* msg_formats[] = {
"%s",
"expected token '%s', got '%s'",
"unable to resolve symbol '%b'",
};
-void onyx_message_add(OnyxMessages* msgs, OnyxMessageType type, OnyxFilePos pos, ...) {
- OnyxMessage* msg = bh_alloc_item(msgs->allocator, OnyxMessage);
+void onyx_message_init(bh_allocator allocator, bh_table(bh_file_contents)* files) {
+ msgs.allocator = allocator;
+ msgs.first = NULL;
+ msgs.file_contents = files;
+}
+
+void onyx_message_add(MsgType type, OnyxFilePos pos, ...) {
+ Message* msg = bh_alloc_item(msgs.allocator, Message);
msg->type = type;
msg->pos = pos;
bh_snprintf_va(msg->text, ONYX_MSG_BUFFER_SIZE, msg_formats[type], arg_list);
va_end(arg_list);
- OnyxMessage** walker = &msgs->first;
+ Message** walker = &msgs.first;
while (*walker && (*walker)->pos.line < pos.line) walker = &(*walker)->next;
while (*walker && (*walker)->pos.line == pos.line && (*walker)->pos.column < pos.column) walker = &(*walker)->next;
*walker = msg;
}
-static void print_detailed_message(OnyxMessage* msg, bh_file_contents* fc) {
+static void print_detailed_message(Message* msg, bh_file_contents* fc) {
bh_printf("(%s:%l:%l) %s\n", msg->pos.filename, msg->pos.line, msg->pos.column, msg->text);
i32 linelength = 0;
bh_printf("| %s\n", pointer_str);
}
-void onyx_message_print(OnyxMessages* msgs) {
- OnyxMessage* msg = msgs->first;
+void onyx_message_print() {
+ Message* msg = msgs.first;
i32 msg_count = MAX_MSGS;
while (msg && msg_count-- > 0) {
if (msg->pos.filename) {
- bh_file_contents* fc = &bh_table_get(bh_file_contents, *msgs->file_contents, (char *) msg->pos.filename);
+ bh_file_contents* fc = &bh_table_get(bh_file_contents, *msgs.file_contents, (char *) msg->pos.filename);
print_detailed_message(msg, fc);
} else {
}
}
-b32 onyx_message_has_errors(OnyxMessages* msgs) {
- return msgs->first != NULL;
-}
-
-void onyx_message_create(bh_allocator allocator, OnyxMessages* msgs, bh_table(bh_file_contents)* files) {
- msgs->allocator = allocator;
- msgs->first = NULL;
- msgs->file_contents = files;
+b32 onyx_message_has_errors() {
+ return msgs.first != NULL;
}
consume_token(parser);
if (token->type != token_type) {
- onyx_message_add(parser->msgs,
- ONYX_MESSAGE_TYPE_EXPECTED_TOKEN,
+ onyx_message_add(Msg_Type_Expected_Token,
token->pos,
token_name(token_type), token_name(token->type));
return NULL;
break;
if (parser->curr->type != ',') {
- onyx_message_add(parser->msgs,
- ONYX_MESSAGE_TYPE_EXPECTED_TOKEN,
+ onyx_message_add(Msg_Type_Expected_Token,
parser->curr->pos,
token_name(','),
token_name(parser->curr->type));
}
default:
- onyx_message_add(parser->msgs,
- ONYX_MESSAGE_TYPE_UNEXPECTED_TOKEN,
+ onyx_message_add(Msg_Type_Unexpected_Token,
parser->curr->pos,
token_name(parser->curr->type));
return NULL;
AstTyped* expr = parse_expression(parser);
if (expr == NULL) {
token_toggle_end(parser->curr);
- onyx_message_add(parser->msgs,
- ONYX_MESSAGE_TYPE_EXPECTED_EXPRESSION,
+ onyx_message_add(Msg_Type_Expected_Expression,
assignment->token->pos,
parser->curr->text);
token_toggle_end(parser->curr);
if (needs_semicolon) {
if (parser->curr->type != ';') {
- onyx_message_add(parser->msgs,
- ONYX_MESSAGE_TYPE_EXPECTED_TOKEN,
+ onyx_message_add(Msg_Type_Expected_Token,
parser->curr->pos,
token_name(';'),
token_name(parser->curr->type));
else {
token_toggle_end(parser->curr);
- onyx_message_add(parser->msgs,
- ONYX_MESSAGE_TYPE_UNEXPECTED_TOKEN,
+ onyx_message_add(Msg_Type_Unexpected_Token,
parser->curr->pos,
parser->curr->text);
token_toggle_end(parser->curr);
OnyxToken* directive_token = expect_token(parser, '#');
OnyxToken* symbol_token = expect_token(parser, Token_Type_Symbol);
- onyx_message_add(parser->msgs,
- ONYX_MESSAGE_TYPE_UNKNOWN_DIRECTIVE,
+ onyx_message_add(Msg_Type_Unknown_Directive,
directive_token->pos,
symbol_token->text, symbol_token->length);
}
OnyxToken* directive_token = expect_token(parser, '#');
OnyxToken* symbol_token = expect_token(parser, Token_Type_Symbol);
- onyx_message_add(parser->msgs,
- ONYX_MESSAGE_TYPE_UNKNOWN_DIRECTIVE,
+ onyx_message_add(Msg_Type_Unknown_Directive,
directive_token->pos,
symbol_token->text, symbol_token->length);
}
return node;
}
-OnyxParser onyx_parser_create(bh_allocator alloc, OnyxTokenizer *tokenizer, OnyxMessages* msgs) {
+OnyxParser onyx_parser_create(bh_allocator alloc, OnyxTokenizer *tokenizer) {
OnyxParser parser;
parser.allocator = alloc;
parser.tokenizer = tokenizer;
parser.curr = tokenizer->tokens;
parser.prev = NULL;
- parser.msgs = msgs;
parser.results = (ParseResults) {
.allocator = global_heap_allocator,
#include "onyxsempass.h"
#include "onyxutils.h"
-SemState onyx_sempass_create(bh_allocator alloc, bh_allocator node_alloc, OnyxMessages* msgs) {
- SemState state = {
+SemState semstate;
+
+void onyx_sempass_init(bh_allocator alloc, bh_allocator node_alloc) {
+ semstate = (SemState) {
.allocator = alloc,
.node_allocator = node_alloc,
.global_scope = NULL,
.curr_scope = NULL,
-
- .msgs = msgs,
};
-
- return state;
}
-void onyx_sempass(SemState* state, ProgramInfo* program) {
- onyx_resolve_symbols(state, program);
- if (onyx_message_has_errors(state->msgs)) return;
+void onyx_sempass(ProgramInfo* program) {
+ onyx_resolve_symbols(program);
+ if (onyx_message_has_errors()) return;
- onyx_type_check(state, program);
- if (onyx_message_has_errors(state->msgs)) return;
+ onyx_type_check(program);
+ if (onyx_message_has_errors()) return;
}
#define BH_DEBUG
#include "onyxsempass.h"
-static b32 symbol_introduce(SemState* state, OnyxToken* tkn, AstNode* symbol);
-static AstNode* symbol_resolve(SemState* state, OnyxToken* tkn);
-static void symbol_basic_type_introduce(SemState* state, AstBasicType* basic_type);
-static void scope_enter(SemState* state, Scope* new_scope);
-static void scope_leave(SemState* state);
-
-static AstType* symres_type(SemState* state, AstType* type);
-static void symres_local(SemState* state, AstLocal** local);
-static void symres_call(SemState* state, AstCall* call);
-static void symres_expression(SemState* state, AstTyped** expr);
-static void symres_return(SemState* state, AstReturn* ret);
-static void symres_if(SemState* state, AstIf* ifnode);
-static void symres_while(SemState* state, AstWhile* whilenode);
-static void symres_statement_chain(SemState* state, AstNode* walker, AstNode** trailer);
-static b32 symres_statement(SemState* state, AstNode* stmt);
-static void symres_block(SemState* state, AstBlock* block);
-static void symres_function(SemState* state, AstFunction* func);
-static void symres_global(SemState* state, AstGlobal* global);
-static void symres_overloaded_function(SemState* state, AstOverloadedFunction* ofunc);
-
-static b32 symbol_introduce(SemState* state, OnyxToken* tkn, AstNode* symbol) {
+static b32 symbol_introduce(OnyxToken* tkn, AstNode* symbol);
+static AstNode* symbol_resolve(OnyxToken* tkn);
+static void symbol_basic_type_introduce(AstBasicType* basic_type);
+static void scope_enter(Scope* new_scope);
+static void scope_leave();
+
+static AstType* symres_type(AstType* type);
+static void symres_local(AstLocal** local);
+static void symres_call(AstCall* call);
+static void symres_expression(AstTyped** expr);
+static void symres_return(AstReturn* ret);
+static void symres_if(AstIf* ifnode);
+static void symres_while(AstWhile* whilenode);
+static void symres_statement_chain(AstNode* walker, AstNode** trailer);
+static b32 symres_statement(AstNode* stmt);
+static void symres_block(AstBlock* block);
+static void symres_function(AstFunction* func);
+static void symres_global(AstGlobal* global);
+static void symres_overloaded_function(AstOverloadedFunction* ofunc);
+
+static b32 symbol_introduce(OnyxToken* tkn, AstNode* symbol) {
token_toggle_end(tkn);
- if (bh_table_has(AstNode *, state->curr_scope->symbols, tkn->text)) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_REDECLARE_SYMBOL,
+ if (bh_table_has(AstNode *, semstate.curr_scope->symbols, tkn->text)) {
+ onyx_message_add(Msg_Type_Redeclare_Symbol,
tkn->pos,
tkn->text);
token_toggle_end(tkn);
return 0;
}
- bh_table_put(AstNode *, state->curr_scope->symbols, tkn->text, symbol);
+ bh_table_put(AstNode *, semstate.curr_scope->symbols, tkn->text, symbol);
if (symbol->kind == Ast_Kind_Local)
- bh_arr_push(state->curr_function->locals, (AstLocal *) symbol);
+ bh_arr_push(semstate.curr_function->locals, (AstLocal *) symbol);
token_toggle_end(tkn);
return 1;
}
-static void symbol_basic_type_introduce(SemState* state, AstBasicType* basic_type) {
- bh_table_put(AstNode *, state->curr_scope->symbols, basic_type->name, (AstNode *) basic_type);
+static void symbol_basic_type_introduce(AstBasicType* basic_type) {
+ bh_table_put(AstNode *, semstate.curr_scope->symbols, basic_type->name, (AstNode *) basic_type);
}
-static AstNode* symbol_resolve(SemState* state, OnyxToken* tkn) {
+static AstNode* symbol_resolve(OnyxToken* tkn) {
token_toggle_end(tkn);
AstNode* res = NULL;
- Scope* scope = state->curr_scope;
+ Scope* scope = semstate.curr_scope;
while (res == NULL && scope != NULL) {
if (bh_table_has(AstNode *, scope->symbols, tkn->text)) {
}
if (res == NULL ) {
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_UNKNOWN_SYMBOL,
+ onyx_message_add(Msg_Type_Unknown_Symbol,
tkn->pos,
tkn->text);
if (res->kind == Ast_Kind_Symbol) {
token_toggle_end(tkn);
- return symbol_resolve(state, res->token);
+ return symbol_resolve(res->token);
}
token_toggle_end(tkn);
return res;
}
-static void scope_enter(SemState* state, Scope* new_scope) {
- new_scope->parent = state->curr_scope;
- state->curr_scope = new_scope;
+static void scope_enter(Scope* new_scope) {
+ new_scope->parent = semstate.curr_scope;
+ semstate.curr_scope = new_scope;
}
-static void scope_leave(SemState* state) {
- state->curr_scope = state->curr_scope->parent;
+static void scope_leave() {
+ semstate.curr_scope = semstate.curr_scope->parent;
}
-static AstType* symres_type(SemState* state, AstType* type) {
+static AstType* symres_type(AstType* type) {
if (type == NULL) return NULL;
if (type->kind == Ast_Kind_Symbol) {
- return (AstType *) symbol_resolve(state, ((AstNode *) type)->token);
+ return (AstType *) symbol_resolve(((AstNode *) type)->token);
}
// NOTE: Already resolved
if (type->kind == Ast_Kind_Basic_Type) return type;
if (type->kind == Ast_Kind_Pointer_Type) {
- ((AstPointerType *) type)->elem = symres_type(state, ((AstPointerType *) type)->elem);
+ ((AstPointerType *) type)->elem = symres_type(((AstPointerType *) type)->elem);
return type;
}
if (type->kind == Ast_Kind_Function_Type) {
AstFunctionType* ftype = (AstFunctionType *) type;
- ftype->return_type = symres_type(state, ftype->return_type);
+ ftype->return_type = symres_type(ftype->return_type);
if (ftype->param_count > 0)
fori (i, 0, ftype->param_count - 1) {
- ftype->params[i] = symres_type(state, ftype->params[i]);
+ ftype->params[i] = symres_type(ftype->params[i]);
}
return type;
return NULL;
}
-static void symres_local(SemState* state, AstLocal** local) {
- (*local)->type_node = symres_type(state, (*local)->type_node);
+static void symres_local(AstLocal** local) {
+ (*local)->type_node = symres_type((*local)->type_node);
- symbol_introduce(state, (*local)->token, (AstNode *) *local);
+ symbol_introduce((*local)->token, (AstNode *) *local);
}
-static void symres_call(SemState* state, AstCall* call) {
- AstNode* callee = symbol_resolve(state, call->callee->token);
+static void symres_call(AstCall* call) {
+ AstNode* callee = symbol_resolve(call->callee->token);
if (callee)
call->callee = callee;
else {
token_toggle_end(call->callee->token);
- onyx_message_add(state->msgs,
- ONYX_MESSAGE_TYPE_UNKNOWN_SYMBOL,
+ onyx_message_add(Msg_Type_Unknown_Symbol,
call->callee->token->pos,
call->callee->token->text);
token_toggle_end(call->callee->token);
return;
}
- symres_statement_chain(state, (AstNode *) call->arguments, (AstNode **) &call->arguments);
+ symres_statement_chain((AstNode *) call->arguments, (AstNode **) &call->arguments);
}
-static void symres_unaryop(SemState* state, AstUnaryOp** unaryop) {
+static void symres_unaryop(AstUnaryOp** unaryop) {
if ((*unaryop)->operation == Unary_Op_Cast) {
- (*unaryop)->type_node = symres_type(state, (*unaryop)->type_node);
+ (*unaryop)->type_node = symres_type((*unaryop)->type_node);
}
- symres_expression(state, &(*unaryop)->expr);
+ symres_expression(&(*unaryop)->expr);
}
-static void symres_expression(SemState* state, AstTyped** expr) {
+static void symres_expression(AstTyped** expr) {
switch ((*expr)->kind) {
case Ast_Kind_Binary_Op:
- symres_expression(state, &((AstBinaryOp *)(*expr))->left);
- symres_expression(state, &((AstBinaryOp *)(*expr))->right);
+ symres_expression(&((AstBinaryOp *)(*expr))->left);
+ symres_expression(&((AstBinaryOp *)(*expr))->right);
break;
- case Ast_Kind_Unary_Op: symres_unaryop(state, (AstUnaryOp **) expr); break;
- case Ast_Kind_Call: symres_call(state, (AstCall *) *expr); break;
- case Ast_Kind_Block: symres_block(state, (AstBlock *) *expr); break;
+ case Ast_Kind_Unary_Op: symres_unaryop((AstUnaryOp **) expr); break;
+ case Ast_Kind_Call: symres_call((AstCall *) *expr); break;
+ case Ast_Kind_Block: symres_block((AstBlock *) *expr); break;
case Ast_Kind_Symbol:
- *expr = (AstTyped *) symbol_resolve(state, ((AstNode *) *expr)->token);
+ *expr = (AstTyped *) symbol_resolve(((AstNode *) *expr)->token);
break;
// NOTE: This is a good case, since it means the symbol is already resolved
case Ast_Kind_Function:
case Ast_Kind_NumLit:
case Ast_Kind_StrLit:
- (*expr)->type_node = symres_type(state, (*expr)->type_node);
+ (*expr)->type_node = symres_type((*expr)->type_node);
break;
case Ast_Kind_Array_Access:
- symres_expression(state, &((AstArrayAccess *)(*expr))->addr);
- symres_expression(state, &((AstArrayAccess *)(*expr))->expr);
+ symres_expression(&((AstArrayAccess *)(*expr))->addr);
+ symres_expression(&((AstArrayAccess *)(*expr))->expr);
break;
default:
}
}
-static void symres_return(SemState* state, AstReturn* ret) {
+static void symres_return(AstReturn* ret) {
if (ret->expr)
- symres_expression(state, &ret->expr);
+ symres_expression(&ret->expr);
}
-static void symres_if(SemState* state, AstIf* ifnode) {
- symres_expression(state, &ifnode->cond);
+static void symres_if(AstIf* ifnode) {
+ symres_expression(&ifnode->cond);
// BUG: This will not work for the following case:
// if cond foo := 10
//
// The declaration will cause a problem but semantically the above
// doesn't make sense.
- if (ifnode->true_stmt != NULL) symres_statement(state, ifnode->true_stmt);
- if (ifnode->false_stmt != NULL) symres_statement(state, ifnode->false_stmt);
+ if (ifnode->true_stmt != NULL) symres_statement(ifnode->true_stmt);
+ if (ifnode->false_stmt != NULL) symres_statement(ifnode->false_stmt);
}
-static void symres_while(SemState* state, AstWhile* whilenode) {
- symres_expression(state, &whilenode->cond);
- symres_statement(state, whilenode->stmt);
+static void symres_while(AstWhile* whilenode) {
+ symres_expression(&whilenode->cond);
+ symres_statement(whilenode->stmt);
}
// NOTE: Returns 1 if the statment should be removed
-static b32 symres_statement(SemState* state, AstNode* stmt) {
+static b32 symres_statement(AstNode* stmt) {
switch (stmt->kind) {
- case Ast_Kind_Local: symres_local(state, (AstLocal **) &stmt); return 1;
- case Ast_Kind_Return: symres_return(state, (AstReturn *) stmt); return 0;
- case Ast_Kind_If: symres_if(state, (AstIf *) stmt); return 0;
- case Ast_Kind_While: symres_while(state, (AstWhile *) stmt); return 0;
- case Ast_Kind_Call: symres_call(state, (AstCall *) stmt); return 0;
- case Ast_Kind_Argument: symres_expression(state, (AstTyped **) &((AstArgument *)stmt)->value); return 0;
- case Ast_Kind_Block: symres_block(state, (AstBlock *) stmt); return 0;
+ case Ast_Kind_Local: symres_local((AstLocal **) &stmt); return 1;
+ case Ast_Kind_Return: symres_return((AstReturn *) stmt); return 0;
+ case Ast_Kind_If: symres_if((AstIf *) stmt); return 0;
+ case Ast_Kind_While: symres_while((AstWhile *) stmt); return 0;
+ case Ast_Kind_Call: symres_call((AstCall *) stmt); return 0;
+ 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_Break: return 0;
case Ast_Kind_Continue: return 0;
- default: symres_expression(state, (AstTyped **) &stmt); return 0;
+ default: symres_expression((AstTyped **) &stmt); return 0;
}
}
-static void symres_statement_chain(SemState* state, AstNode* walker, AstNode** trailer) {
+static void symres_statement_chain(AstNode* walker, AstNode** trailer) {
while (walker) {
- if (symres_statement(state, walker)) {
+ if (symres_statement(walker)) {
*trailer = walker->next;
AstNode* tmp = walker->next;
}
}
-static void symres_block(SemState* state, AstBlock* block) {
+static void symres_block(AstBlock* block) {
if (block->scope == NULL)
- block->scope = scope_create(state->node_allocator, state->curr_scope);
+ block->scope = scope_create(semstate.node_allocator, semstate.curr_scope);
- scope_enter(state, block->scope);
+ scope_enter(block->scope);
if (block->body)
- symres_statement_chain(state, block->body, &block->body);
+ symres_statement_chain(block->body, &block->body);
- scope_leave(state);
+ scope_leave();
}
-static void symres_function(SemState* state, AstFunction* func) {
+static void symres_function(AstFunction* func) {
if (func->scope == NULL)
- func->scope = scope_create(state->node_allocator, state->curr_scope);
+ func->scope = scope_create(semstate.node_allocator, semstate.curr_scope);
- scope_enter(state, func->scope);
+ scope_enter(func->scope);
for (AstLocal *param = func->params; param != NULL; param = (AstLocal *) param->next) {
- param->type_node = symres_type(state, param->type_node);
+ param->type_node = symres_type(param->type_node);
- symbol_introduce(state, param->token, (AstNode *) param);
+ symbol_introduce(param->token, (AstNode *) param);
}
if (func->type_node != NULL) {
- func->type_node = symres_type(state, func->type_node);
+ func->type_node = symres_type(func->type_node);
}
- state->curr_function = func;
- symres_block(state, func->body);
+ semstate.curr_function = func;
+ symres_block(func->body);
- scope_leave(state);
+ scope_leave();
}
-static void symres_global(SemState* state, AstGlobal* global) {
- global->type_node = symres_type(state, global->type_node);
+static void symres_global(AstGlobal* global) {
+ global->type_node = symres_type(global->type_node);
}
-static void symres_overloaded_function(SemState* state, AstOverloadedFunction* ofunc) {
+static void symres_overloaded_function(AstOverloadedFunction* ofunc) {
bh_arr_each(AstTyped *, node, ofunc->overloads) {
if ((*node)->kind == Ast_Kind_Symbol) {
- *node = (AstTyped *) symbol_resolve(state, (*node)->token);
+ *node = (AstTyped *) symbol_resolve((*node)->token);
}
}
}
-void onyx_resolve_symbols(SemState* state, ProgramInfo* program) {
+void onyx_resolve_symbols(ProgramInfo* program) {
- state->global_scope = scope_create(state->node_allocator, NULL);
- scope_enter(state, state->global_scope);
+ semstate.global_scope = scope_create(semstate.node_allocator, NULL);
+ scope_enter(semstate.global_scope);
// NOTE: Add types to global scope
- symbol_basic_type_introduce(state, &basic_type_void);
- symbol_basic_type_introduce(state, &basic_type_bool);
- symbol_basic_type_introduce(state, &basic_type_i8);
- symbol_basic_type_introduce(state, &basic_type_u8);
- symbol_basic_type_introduce(state, &basic_type_i16);
- symbol_basic_type_introduce(state, &basic_type_u16);
- symbol_basic_type_introduce(state, &basic_type_i32);
- symbol_basic_type_introduce(state, &basic_type_u32);
- symbol_basic_type_introduce(state, &basic_type_i64);
- symbol_basic_type_introduce(state, &basic_type_u64);
- symbol_basic_type_introduce(state, &basic_type_f32);
- symbol_basic_type_introduce(state, &basic_type_f64);
- symbol_basic_type_introduce(state, &basic_type_rawptr);
+ symbol_basic_type_introduce(&basic_type_void);
+ symbol_basic_type_introduce(&basic_type_bool);
+ symbol_basic_type_introduce(&basic_type_i8);
+ symbol_basic_type_introduce(&basic_type_u8);
+ symbol_basic_type_introduce(&basic_type_i16);
+ symbol_basic_type_introduce(&basic_type_u16);
+ symbol_basic_type_introduce(&basic_type_i32);
+ symbol_basic_type_introduce(&basic_type_u32);
+ symbol_basic_type_introduce(&basic_type_i64);
+ symbol_basic_type_introduce(&basic_type_u64);
+ symbol_basic_type_introduce(&basic_type_f32);
+ symbol_basic_type_introduce(&basic_type_f64);
+ symbol_basic_type_introduce(&basic_type_rawptr);
bh_arr_each(AstBinding *, binding, program->bindings)
- if (!symbol_introduce(state, (*binding)->token, (*binding)->node)) return;
+ if (!symbol_introduce((*binding)->token, (*binding)->node)) return;
bh_arr_each(Entity, entity, program->entities) {
switch (entity->type) {
- case Entity_Type_Function: symres_function(state, entity->function); break;
- case Entity_Type_Overloaded_Function: symres_overloaded_function(state, entity->overloaded_function); break;
- case Entity_Type_Global: symres_global(state, entity->global); break;
- case Entity_Type_Expression: symres_expression(state, &entity->expr); break;
+ case Entity_Type_Function: symres_function(entity->function); break;
+ case Entity_Type_Overloaded_Function: symres_overloaded_function(entity->overloaded_function); break;
+ case Entity_Type_Global: symres_global(entity->global); break;
+ case Entity_Type_Expression: symres_expression(&entity->expr); break;
default: break;
}
bh_arr_push(mod->data, datum);
}
-OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc, OnyxMessages* msgs) {
+OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc) {
OnyxWasmModule module = {
.allocator = alloc,
- .msgs = msgs,
.type_map = NULL,
.next_type_idx = 0,