typedef struct Scope {
struct Scope *parent;
+ OnyxFilePos created_at;
bh_table(AstNode *) symbols;
} Scope;
-extern Scope* scope_create(bh_allocator a, Scope* parent);
+extern Scope* scope_create(bh_allocator a, Scope* parent, OnyxFilePos created_at);
typedef enum AstKind {
} PolyProcLookupMethod;
AstFunction* polymorphic_proc_lookup(AstPolyProc* pp, PolyProcLookupMethod pp_lookup, ptr actual, OnyxFilePos pos);
-AstStructType* polymorphic_struct_lookup(AstPolyStructType* ps_type, bh_arr(Type *) params);
+AstStructType* polymorphic_struct_lookup(AstPolyStructType* ps_type, bh_arr(Type *) params, OnyxFilePos pos);
// NOTE: Useful inlined functions
static inline b32 is_lval(AstNode* node) {
Package* program_info_package_lookup(ProgramInfo* prog, char* package_name);
Package* program_info_package_lookup_or_create(ProgramInfo* prog, char* package_name, Scope* parent_scope, bh_allocator alloc);
-Scope* scope_create(bh_allocator a, Scope* parent);
void scope_include(Scope* target, Scope* source);
b32 symbol_introduce(Scope* scope, OnyxToken* tkn, AstNode* symbol);
b32 symbol_raw_introduce(Scope* scope, char* tkn, OnyxFilePos pos, AstNode* symbol);
syn match onyxDefinitionGroup "\<[a-zA-Z_][a-zA-Z0-9_]*\> *::" contains=onyxDefinition
syn match onyxDefinition "\<[a-zA-Z_][a-zA-Z0-9_]*\>" contained
-syn region onyxDirective start="#" end=" "
+syn match onyxDirective "\#[a-zA-Z_]\+"
syn region onyxString display start=+"+ skip=+\\\\\|\\"+ end=+"+ keepend
return num;
}
+static AstUnaryOp* wrap_in_auto_cast(bh_allocator a, AstTyped* expr) {
+ AstUnaryOp* ac = onyx_ast_node_new(a, sizeof(AstUnaryOp), Ast_Kind_Unary_Op);
+ ac->operation = Unary_Op_Auto_Cast;
+ ac->token = expr->token;
+ ac->expr = expr;
+ return ac;
+}
+
static AstNumLit* parse_int_literal(OnyxParser* parser) {
AstNumLit* int_node = make_node(AstNumLit, Ast_Kind_NumLit);
}
if (parser->curr->type == '(') {
- consume_token(parser);
+ OnyxToken* paren_token = expect_token(parser, '(');
bh_arr(AstType *) params = NULL;
bh_arr_new(global_heap_allocator, params, 2);
expect_token(parser, ')');
AstPolyCallType* pc_type = make_node(AstPolyCallType, Ast_Kind_Poly_Call_Type);
+ pc_type->token = paren_token;
pc_type->callee = *next_insertion;
pc_type->params = params;
parser->package = package;
}
- parser->file_scope = scope_create(parser->allocator, parser->package->private_scope);
+ parser->file_scope = scope_create(parser->allocator, parser->package->private_scope, parser->tokenizer->tokens[0].pos);
AstUsePackage* implicit_use_builtin = make_node(AstUsePackage, Ast_Kind_Use_Package);
implicit_use_builtin->package = (AstPackage *) &builtin_package_node;
static void symres_memres(AstMemRes** memres);
static void scope_enter(Scope* new_scope) {
- if (new_scope->parent == NULL)
- new_scope->parent = semstate.curr_scope;
+ // if (new_scope->parent == NULL)
+ // new_scope->parent = semstate.curr_scope;
semstate.curr_scope = new_scope;
}
if (type->kind == Ast_Kind_Poly_Struct_Type) {
AstPolyStructType* pst_node = (AstPolyStructType *) type;
- pst_node->scope = scope_create(semstate.node_allocator, semstate.curr_scope);
+ pst_node->scope = scope_create(semstate.node_allocator, semstate.curr_scope, pst_node->token->pos);
return type;
}
}
static void symres_struct_literal(AstStructLiteral* sl) {
+ // @CLEANUP
if (sl->stnode != NULL) symres_expression(&sl->stnode);
+ sl->stnode = (AstTyped *) symres_type((AstType *) sl->stnode);
if (sl->stnode == NULL || sl->stnode->kind == Ast_Kind_Error || sl->stnode->kind == Ast_Kind_Symbol) return;
- sl->type_node = symres_type((AstType *) sl->stnode);
+ sl->type_node = (AstType *) sl->stnode;
+ while (sl->type_node->kind == Ast_Kind_Type_Alias)
+ sl->type_node = ((AstTypeAlias *) sl->type_node)->to;
+
sl->type = type_build_from_ast(semstate.allocator, sl->type_node);
+ if (sl->type == NULL) return;
+
if (!type_is_structlike_strict(sl->type)) {
onyx_report_error(sl->token->pos, "Type is not a constructable using a struct literal.");
return;
u32 idx = (*smem)->idx;
if (sl->values[idx] == NULL) {
- if (st->members[idx]->initial_value == NULL) {
- onyx_report_error(sl->token->pos, "No value was given for the field '%b'.",
- st->members[idx]->token->text,
- st->members[idx]->token->length);
+ if (st->kind != Ast_Kind_Struct_Type || st->members[idx]->initial_value == NULL) {
+ onyx_report_error(sl->token->pos, "No value was given for the field '%s'.", (*smem)->name);
return;
}
static void symres_if(AstIfWhile* ifnode) {
if (ifnode->assignment != NULL) {
- ifnode->scope = scope_create(semstate.node_allocator, semstate.curr_scope);
+ ifnode->scope = scope_create(semstate.node_allocator, semstate.curr_scope, ifnode->token->pos);
scope_enter(ifnode->scope);
symbol_introduce(semstate.curr_scope, ifnode->local->token, (AstNode *) ifnode->local);
static void symres_while(AstIfWhile* whilenode) {
if (whilenode->assignment != NULL) {
- whilenode->scope = scope_create(semstate.node_allocator, semstate.curr_scope);
+ whilenode->scope = scope_create(semstate.node_allocator, semstate.curr_scope, whilenode->token->pos);
scope_enter(whilenode->scope);
symbol_introduce(semstate.curr_scope, whilenode->local->token, (AstNode *) whilenode->local);
}
static void symres_for(AstFor* fornode) {
- fornode->scope = scope_create(semstate.node_allocator, semstate.curr_scope);
+ fornode->scope = scope_create(semstate.node_allocator, semstate.curr_scope, fornode->token->pos);
scope_enter(fornode->scope);
symres_expression(&fornode->iter);
static void symres_switch(AstSwitch* switchnode) {
if (switchnode->assignment != NULL) {
- switchnode->scope = scope_create(semstate.node_allocator, semstate.curr_scope);
+ switchnode->scope = scope_create(semstate.node_allocator, semstate.curr_scope, switchnode->token->pos);
scope_enter(switchnode->scope);
symbol_introduce(semstate.curr_scope, switchnode->local->token, (AstNode *) switchnode->local);
static void symres_block(AstBlock* block) {
if (block->scope == NULL)
- block->scope = scope_create(semstate.node_allocator, semstate.curr_scope);
+ block->scope = scope_create(semstate.node_allocator, semstate.curr_scope, block->token->pos);
scope_enter(block->scope);
bh_arr_push(semstate.block_stack, block);
void symres_function(AstFunction* func) {
if (func->scope == NULL)
- func->scope = scope_create(semstate.node_allocator, semstate.curr_scope);
+ func->scope = scope_create(semstate.node_allocator, semstate.curr_scope, func->token->pos);
bh_arr_each(AstParam, param, func->params) {
if (param->default_value != NULL) {
if (enum_node->backing == NULL) return;
enum_node->backing_type = type_build_from_ast(semstate.allocator, enum_node->backing);
- enum_node->scope = scope_create(semstate.node_allocator, NULL);
+ enum_node->scope = scope_create(semstate.node_allocator, NULL, enum_node->token->pos);
u64 next_assign_value = (enum_node->flags & Ast_Flag_Enum_Is_Flags) ? 1 : 0;
bh_arr_each(AstEnumValue *, value, enum_node->values) {
}
static void symres_polyproc(AstPolyProc* pp) {
- pp->poly_scope = scope_create(semstate.node_allocator, semstate.curr_scope);
+ pp->poly_scope = scope_create(semstate.node_allocator, semstate.curr_scope, pp->token->pos);
}
void onyx_resolve_symbols() {
if (a_node->count_expr) {
a_node->count_expr->type = type_build_from_ast(alloc, a_node->count_expr->type_node);
+ if (node_is_auto_cast((AstNode *) a_node->count_expr)) {
+ a_node->count_expr = ((AstUnaryOp *) a_node)->expr;
+ }
+
// NOTE: Currently, the count_expr has to be an I32 literal
if (a_node->count_expr->kind != Ast_Kind_NumLit
|| a_node->count_expr->type->kind != Type_Kind_Basic
bh_arr_push(param_types, type_build_from_ast(alloc, *ptype));
}
- AstStructType* concrete = polymorphic_struct_lookup(ps_type, param_types);
+ AstStructType* concrete = polymorphic_struct_lookup(ps_type, param_types, pc_type->token->pos);
bh_arr_free(param_types);
void program_info_init(ProgramInfo* prog, bh_allocator alloc) {
- prog->global_scope = scope_create(alloc, NULL);
+ prog->global_scope = scope_create(alloc, NULL, (OnyxFilePos) { 0 });
bh_table_init(alloc, prog->packages, 16);
memcpy(pac_name, package_name, strlen(package_name) + 1);
package->name = pac_name;
- package->scope = scope_create(alloc, parent_scope);
- package->private_scope = scope_create(alloc, package->scope);
+ package->scope = scope_create(alloc, parent_scope, (OnyxFilePos) { 0 });
+ package->private_scope = scope_create(alloc, package->scope, (OnyxFilePos) { 0 });
bh_table_put(Package *, prog->packages, pac_name, package);
}
}
-Scope* scope_create(bh_allocator a, Scope* parent) {
+Scope* scope_create(bh_allocator a, Scope* parent, OnyxFilePos created_at) {
Scope* scope = bh_alloc_item(a, Scope);
scope->parent = parent;
+ scope->created_at = created_at;
scope->symbols = NULL;
bh_table_init(global_heap_allocator, scope->symbols, 64);
AstNode* res = symbol_raw_resolve(start_scope, tkn->text);
if (res == NULL) {
- onyx_report_error(tkn->pos, "Unable to resolve symbol '%s'", tkn->text);
+ onyx_report_error(tkn->pos, "Unable to resolve symbol '%s'.", tkn->text);
token_toggle_end(tkn);
return &empty_node;
}
}
Type* old_return_type = semstate.expected_return_type;
+ Scope* old_scope = semstate.curr_scope;
semstate.curr_scope = pp->poly_scope;
AstFunction* func = (AstFunction *) ast_clone(semstate.node_allocator, pp->base_func);
bh_table_put(AstFunction *, pp->concrete_funcs, key_buf, func);
symres_function(func);
+ semstate.curr_scope = old_scope;
+
if (onyx_has_errors()) goto has_error;
if (check_function_header(func)) goto has_error;
if (check_function(func)) goto has_error;
-AstStructType* polymorphic_struct_lookup(AstPolyStructType* ps_type, bh_arr(Type *) params) {
+AstStructType* polymorphic_struct_lookup(AstPolyStructType* ps_type, bh_arr(Type *) params, OnyxFilePos pos) {
// @Cleanup
assert(bh_arr_length(ps_type->poly_params) == bh_arr_length(params));
assert(ps_type->scope != NULL);
AstStructType* concrete_struct = (AstStructType *) ast_clone(semstate.node_allocator, ps_type->base_struct);
+ Scope* old_scope = semstate.curr_scope;
semstate.curr_scope = ps_type->scope;
concrete_struct = (AstStructType *) symres_type((AstType *) concrete_struct);
+ semstate.curr_scope = old_scope;
+
if (onyx_has_errors()) goto has_error;
goto no_errors;
has_error:
- // onyx_report_error((OnyxFilePos) { 0 }, "Error in polymorphic struct generated from this call site.");
+ // onyx_report_error(pos, "Error in polymorphic struct generated from this call site.");
return NULL;
no_errors: