ONYX_MESSAGE_TYPE_BINOP_MISMATCH_TYPE,
ONYX_MESSAGE_TYPE_ASSIGNMENT_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,
syn keyword onyxKeyword struct proc use export foreign global
syn keyword onyxKeyword if elseif else
-syn keyword onyxKeyword for return do
+syn keyword onyxKeyword for while loop return do
syn keyword onyxKeyword return
syn keyword onyxKeyword as
syn keyword onyxType f32
syn keyword onyxType f64
+syn keyword onyxConstant true false
+
syn keyword onyxCommentStart contained TODO NOTE BUG HACK
syn region onyxComment start="//" end="$" keepend contains=onyxCommentStart
-hi def link onyxKeyword Statement
-hi def link onyxType Type
-hi def link onyxComment Comment
+hi def link onyxKeyword Statement
+hi def link onyxType Type
+hi def link onyxComment Comment
hi def link onyxCommentStart Todo
+hi def link onyxConstant Constant
let b:current_syntax = "onyx"
let &cpo = s:cpo_save
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 {
}
-export main :: proc {
+update :: proc {}
- while true {
- update();
- draw();
- }
+draw :: proc {
+ gfx_draw_rect(0, 0, 100, 100);
}
+
OnyxParser parser = onyx_parser_create(ast_alloc, &tokenizer, &msgs);
OnyxAstNode* program = onyx_parse(&parser);
- bh_printf("BEFORE SYMBOL_RESOLUTION: ");
- onyx_ast_print(program, 1);
-
bh_arena sp_arena;
bh_arena_init(&sp_arena, alloc, 16 * 1024);
bh_allocator sp_alloc = bh_arena_allocator(&sp_arena);
// NOTE: if there are errors, assume the parse tree was generated wrong,
// even if it may have still been generated correctly.
if (onyx_message_has_errors(&msgs)) {
- bh_printf("\n\n");
onyx_message_print(&msgs);
goto main_exit;
} else {
- bh_printf("\n\nAFTER SYMBOL RESOLUTION: ");
- onyx_ast_print(program, 1);
+ // onyx_ast_print(program, 1);
bh_printf("\nNo errors.\n");
}
"expected token '%s', got '%s'",
"unexpected token '%s'",
"unknown type '%s'",
- "expected lval '%s'",
- "attempt to assign to constant '%s'",
+ "expected lval '%b'",
+ "attempt to assign to constant '%b'",
"unknown symbol '%s'",
"redefinition of function '%s'",
"mismatched types for binary operator, '%s', '%s'",
"mismatched types on assignment, expected '%s', got '%s'",
"expected expression, got '%s'",
+ "attempt to call non-function, '%b'",
"returning '%s' from function that returns '%s'",
"function '%b' expected type '%s' in position '%d', got '%s'",
// NOTE: Assignment
case TOKEN_TYPE_SYM_EQUALS:
{
+ OnyxAstNode* assignment = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_ASSIGNMENT);
+ assignment->token = parser->curr_token;
parser_next_token(parser);
OnyxAstNode* lval = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_SYMBOL);
lval->token = symbol;
OnyxAstNode* rval = parse_expression(parser);
- OnyxAstNode* assignment = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_ASSIGNMENT);
assignment->right = rval;
assignment->left = lval;
*ret = assignment;
}
static OnyxAstNodeBlock* parse_block(OnyxParser* parser) {
+ OnyxAstNodeBlock* block = (OnyxAstNodeBlock *) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_BLOCK);
+ OnyxAstNodeScope* scope = (OnyxAstNodeScope *) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_SCOPE);
+ block->scope = scope;
+
// --- is for an empty block
if (parser->curr_token->type == TOKEN_TYPE_SYM_MINUS) {
expect(parser, TOKEN_TYPE_SYM_MINUS);
expect(parser, TOKEN_TYPE_SYM_MINUS);
expect(parser, TOKEN_TYPE_SYM_MINUS);
- return NULL;
+ return block;
}
expect(parser, TOKEN_TYPE_OPEN_BRACE);
- OnyxAstNodeBlock* block = (OnyxAstNodeBlock *) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_BLOCK);
- OnyxAstNodeScope* scope = (OnyxAstNodeScope *) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_SCOPE);
- block->scope = scope;
-
OnyxAstNode** next = &block->body;
OnyxAstNode* stmt = NULL;
while (parser->curr_token->type != TOKEN_TYPE_CLOSE_BRACE) {
return state;
}
+static void collapse_scopes(OnyxAstNode* root_node, OnyxAstNodeScope* prev_scope) {
+
+}
+
void onyx_sempass(OnyxSemPassState* state, OnyxAstNode* root_node) {
onyx_resolve_symbols(state, root_node);
onyx_type_check(state, root_node);
+ collapse_scopes(root_node, NULL);
}
return;
}
+ if ((assign->left->flags & ONYX_AST_FLAG_LVAL) == 0) {
+ onyx_message_add(state->msgs,
+ ONYX_MESSAGE_TYPE_NOT_LVAL,
+ assign->token->pos,
+ assign->left->token->token, assign->left->token->length);
+ return;
+ }
+
+ if ((assign->left->flags & ONYX_AST_FLAG_CONST) != 0 && assign->left->type->is_known) {
+ onyx_message_add(state->msgs,
+ ONYX_MESSAGE_TYPE_ASSIGN_CONST,
+ assign->token->pos,
+ assign->left->token->token, assign->left->token->length);
+ return;
+ }
+
typecheck_expression(state, assign->right);
if (!assign->left->type->is_known) {
return;
}
+ if (callee->kind != ONYX_AST_NODE_KIND_FUNCDEF) {
+ onyx_message_add(state->msgs,
+ ONYX_MESSAGE_TYPE_CALL_NON_FUNCTION,
+ call->token->pos,
+ callee->token->token, callee->token->length);
+ return;
+ }
+
call->type = callee->return_type;
OnyxAstNodeParam* formal_param = callee->params;