AstKind kind; \
u32 flags; \
OnyxToken *token; \
+ struct Entity* entity; \
AstNode *next
struct AstNode { AstNode_base; };
// without the 'next' member. This is because types
// can't be in expressions so a 'next' thing
// doesn't make sense.
-#define AstType_base \
- AstKind kind; \
- u32 flags; \
- OnyxToken* token; \
+#define AstType_base \
+ AstKind kind; \
+ u32 flags; \
+ OnyxToken* token; \
+ struct Entity* entity; \
char* name
struct AstType { AstType_base; };
// NOTE: Used to store statically bound expressions in the struct.
Scope* scope;
+
+ struct Entity* entity_type;
+ struct Entity* entity_defaults;
};
struct AstStructMember {
AstTyped_base;
}
static b32 process_entity(Entity* ent) {
+ static char verbose_output_buffer[512];
if (context.options->verbose_output == 3) {
if (ent->expr && ent->expr->token)
- printf("%s | %s (%d, %d) | %s:%i:%i\n",
+ snprintf(verbose_output_buffer, 511,
+ "%15s | %20s (%d, %d) | %s:%i:%i \n",
entity_state_strings[ent->state],
entity_type_strings[ent->type],
(u32) ent->macro_attempts,
ent->expr->token->pos.column);
else if (ent->expr)
- printf("%s | %s (%d, %d) \n",
+ snprintf(verbose_output_buffer, 511,
+ "%15s | %20s (%d, %d) \n",
entity_state_strings[ent->state],
entity_type_strings[ent->type],
(u32) ent->macro_attempts,
case Entity_State_Code_Gen: emit_entity(ent); break;
}
- return ent->state != before_state;
+ b32 changed = ent->state != before_state;
+ if (context.options->verbose_output == 3) {
+ if (changed) printf("SUCCESS | %s", verbose_output_buffer);
+ else printf("YIELD | %s", verbose_output_buffer);
+ }
+
+ return changed;
}
// Just having fun with some visual output - brendanfh 2020/12/14
#include "onyxerrors.h"
#include "onyxutils.h"
-AstBasicType basic_type_void = { Ast_Kind_Basic_Type, 0, NULL, "void" , &basic_types[Basic_Kind_Void] };
-AstBasicType basic_type_bool = { Ast_Kind_Basic_Type, 0, NULL, "bool" , &basic_types[Basic_Kind_Bool] };
-AstBasicType basic_type_i8 = { Ast_Kind_Basic_Type, 0, NULL, "i8" , &basic_types[Basic_Kind_I8] };
-AstBasicType basic_type_u8 = { Ast_Kind_Basic_Type, 0, NULL, "u8" , &basic_types[Basic_Kind_U8] };
-AstBasicType basic_type_i16 = { Ast_Kind_Basic_Type, 0, NULL, "i16" , &basic_types[Basic_Kind_I16] };
-AstBasicType basic_type_u16 = { Ast_Kind_Basic_Type, 0, NULL, "u16" , &basic_types[Basic_Kind_U16] };
-AstBasicType basic_type_i32 = { Ast_Kind_Basic_Type, 0, NULL, "i32" , &basic_types[Basic_Kind_I32] };
-AstBasicType basic_type_u32 = { Ast_Kind_Basic_Type, 0, NULL, "u32" , &basic_types[Basic_Kind_U32] };
-AstBasicType basic_type_i64 = { Ast_Kind_Basic_Type, 0, NULL, "i64" , &basic_types[Basic_Kind_I64] };
-AstBasicType basic_type_u64 = { Ast_Kind_Basic_Type, 0, NULL, "u64" , &basic_types[Basic_Kind_U64] };
-AstBasicType basic_type_f32 = { Ast_Kind_Basic_Type, 0, NULL, "f32" , &basic_types[Basic_Kind_F32] };
-AstBasicType basic_type_f64 = { Ast_Kind_Basic_Type, 0, NULL, "f64" , &basic_types[Basic_Kind_F64] };
-AstBasicType basic_type_rawptr = { Ast_Kind_Basic_Type, 0, NULL, "rawptr", &basic_types[Basic_Kind_Rawptr] };
+AstBasicType basic_type_void = { Ast_Kind_Basic_Type, 0, NULL, NULL, "void" , &basic_types[Basic_Kind_Void] };
+AstBasicType basic_type_bool = { Ast_Kind_Basic_Type, 0, NULL, NULL, "bool" , &basic_types[Basic_Kind_Bool] };
+AstBasicType basic_type_i8 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "i8" , &basic_types[Basic_Kind_I8] };
+AstBasicType basic_type_u8 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "u8" , &basic_types[Basic_Kind_U8] };
+AstBasicType basic_type_i16 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "i16" , &basic_types[Basic_Kind_I16] };
+AstBasicType basic_type_u16 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "u16" , &basic_types[Basic_Kind_U16] };
+AstBasicType basic_type_i32 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "i32" , &basic_types[Basic_Kind_I32] };
+AstBasicType basic_type_u32 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "u32" , &basic_types[Basic_Kind_U32] };
+AstBasicType basic_type_i64 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "i64" , &basic_types[Basic_Kind_I64] };
+AstBasicType basic_type_u64 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "u64" , &basic_types[Basic_Kind_U64] };
+AstBasicType basic_type_f32 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "f32" , &basic_types[Basic_Kind_F32] };
+AstBasicType basic_type_f64 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "f64" , &basic_types[Basic_Kind_F64] };
+AstBasicType basic_type_rawptr = { Ast_Kind_Basic_Type, 0, NULL, NULL, "rawptr", &basic_types[Basic_Kind_Rawptr] };
// NOTE: Types used for numeric literals
-AstBasicType basic_type_int_unsized = { Ast_Kind_Basic_Type, 0, NULL, "unsized_int", &basic_types[Basic_Kind_Int_Unsized] };
-AstBasicType basic_type_float_unsized = { Ast_Kind_Basic_Type, 0, NULL, "unsized_float", &basic_types[Basic_Kind_Float_Unsized] };
+AstBasicType basic_type_int_unsized = { Ast_Kind_Basic_Type, 0, NULL, NULL, "unsized_int", &basic_types[Basic_Kind_Int_Unsized] };
+AstBasicType basic_type_float_unsized = { Ast_Kind_Basic_Type, 0, NULL, NULL, "unsized_float", &basic_types[Basic_Kind_Float_Unsized] };
static OnyxToken simd_token = { Token_Type_Symbol, 0, "", { 0 } };
-AstBasicType basic_type_i8x16 = { Ast_Kind_Basic_Type, 0, &simd_token, "i8x16", &basic_types[Basic_Kind_I8X16] };
-AstBasicType basic_type_i16x8 = { Ast_Kind_Basic_Type, 0, &simd_token, "i16x8", &basic_types[Basic_Kind_I16X8] };
-AstBasicType basic_type_i32x4 = { Ast_Kind_Basic_Type, 0, &simd_token, "i32x4", &basic_types[Basic_Kind_I32X4] };
-AstBasicType basic_type_i64x2 = { Ast_Kind_Basic_Type, 0, &simd_token, "i64x2", &basic_types[Basic_Kind_I64X2] };
-AstBasicType basic_type_f32x4 = { Ast_Kind_Basic_Type, 0, &simd_token, "f32x4", &basic_types[Basic_Kind_F32X4] };
-AstBasicType basic_type_f64x2 = { Ast_Kind_Basic_Type, 0, &simd_token, "f64x2", &basic_types[Basic_Kind_F64X2] };
-AstBasicType basic_type_v128 = { Ast_Kind_Basic_Type, 0, &simd_token, "v128", &basic_types[Basic_Kind_V128] };
+AstBasicType basic_type_i8x16 = { Ast_Kind_Basic_Type, 0, &simd_token, NULL, "i8x16", &basic_types[Basic_Kind_I8X16] };
+AstBasicType basic_type_i16x8 = { Ast_Kind_Basic_Type, 0, &simd_token, NULL, "i16x8", &basic_types[Basic_Kind_I16X8] };
+AstBasicType basic_type_i32x4 = { Ast_Kind_Basic_Type, 0, &simd_token, NULL, "i32x4", &basic_types[Basic_Kind_I32X4] };
+AstBasicType basic_type_i64x2 = { Ast_Kind_Basic_Type, 0, &simd_token, NULL, "i64x2", &basic_types[Basic_Kind_I64X2] };
+AstBasicType basic_type_f32x4 = { Ast_Kind_Basic_Type, 0, &simd_token, NULL, "f32x4", &basic_types[Basic_Kind_F32X4] };
+AstBasicType basic_type_f64x2 = { Ast_Kind_Basic_Type, 0, &simd_token, NULL, "f64x2", &basic_types[Basic_Kind_F64X2] };
+AstBasicType basic_type_v128 = { Ast_Kind_Basic_Type, 0, &simd_token, NULL, "v128", &basic_types[Basic_Kind_V128] };
OnyxToken builtin_package_token = { Token_Type_Symbol, 7, "builtin ", { 0 } };
static OnyxToken builtin_heap_start_token = { Token_Type_Symbol, 12, "__heap_start ", { 0 } };
static OnyxToken builtin_stack_top_token = { Token_Type_Symbol, 11, "__stack_top ", { 0 } };
-AstNumLit builtin_heap_start = { Ast_Kind_NumLit, Ast_Flag_Const, &builtin_heap_start_token, NULL, (AstType *) &basic_type_rawptr, NULL, 0 };
-AstGlobal builtin_stack_top = { Ast_Kind_Global, Ast_Flag_Const | Ast_Flag_Global_Stack_Top, &builtin_stack_top_token, NULL, (AstType *) &basic_type_rawptr, NULL };
+AstNumLit builtin_heap_start = { Ast_Kind_NumLit, Ast_Flag_Const, &builtin_heap_start_token, NULL, NULL, (AstType *) &basic_type_rawptr, NULL, 0 };
+AstGlobal builtin_stack_top = { Ast_Kind_Global, Ast_Flag_Const | Ast_Flag_Global_Stack_Top, &builtin_stack_top_token, NULL, NULL, (AstType *) &basic_type_rawptr, NULL };
// :TypeExprHack
static OnyxToken type_expr_token = { Token_Type_Symbol, 9, "type_expr", { 0 } };
-AstNode type_expr_symbol = { Ast_Kind_Error, 0, &type_expr_token, NULL };
+AstNode type_expr_symbol = { Ast_Kind_Error, 0, &type_expr_token, NULL, NULL };
AstType *builtin_string_type;
AstType *builtin_range_type;
arguments_clone(&call->original_args, &call->args);
if (call->callee->kind == Ast_Kind_Overloaded_Function) {
- call->callee = find_matching_overload_by_arguments(((AstOverloadedFunction *) call->callee)->overloads, &call->args);
- if (call->callee == NULL) {
- report_unable_to_match_overload(call);
- return Check_Error;
+ AstTyped* new_callee = find_matching_overload_by_arguments(((AstOverloadedFunction *) call->callee)->overloads, &call->args);
+ if (new_callee == NULL) {
+ if (call->callee->entity->state > Entity_State_Check_Types) {
+ report_unable_to_match_overload(call);
+ return Check_Error;
+
+ } else {
+ return Check_Yield_Macro;
+ }
}
+
+ call->callee = new_callee;
}
if (call->callee->kind == Ast_Kind_Polymorphic_Proc) {
- call->callee = (AstTyped *) polymorphic_proc_lookup((AstPolyProc *) call->callee, PPLM_By_Arguments, &call->args, call->token);
- if (call->callee == NULL) return Check_Error;
+ AstTyped* new_callee = (AstTyped *) polymorphic_proc_lookup((AstPolyProc *) call->callee, PPLM_By_Arguments, &call->args, call->token);
+ if (new_callee == NULL) return Check_Error;
arguments_remove_baked(&call->args);
+ call->callee = new_callee;
}
AstFunction* callee = (AstFunction *) call->callee;
resolve_expression_type(binop->right);
if (binop->right->type == NULL) {
- onyx_report_error(binop->token->pos, "Could not resolve type of right hand side to infer.");
- return Check_Error;
+ if (binop->right->entity == NULL || binop->right->entity->state > Entity_State_Check_Types) {
+ onyx_report_error(binop->token->pos, "Could not resolve type of right hand side to infer.");
+ return Check_Error;
+
+ } else {
+ return Check_Yield_Macro;
+ }
}
if (binop->right->type->kind == Type_Kind_Compound) {
fori (i, 0, mem_count) {
CHECK(expression, actual);
+ // HACK HACK HACK
+ if ((*actual)->type == NULL && (*actual)->kind == Ast_Kind_Function) {
+ return Check_Yield_Macro;
+ }
+
// NOTE: Not checking the return on this function because
// this for loop is bounded by the number of members in the
// type.
AstFieldAccess* field = *pfield;
CHECK(expression, &field->expr);
if (field->expr->type == NULL) {
- onyx_report_error(field->token->pos, "Unable to deduce type of expression for accessing field.");
- return Check_Error;
+ // onyx_report_error(field->token->pos, "Unable to deduce type of expression for accessing field.");
+ return Check_Yield_Macro;
}
if (!type_is_structlike(field->expr->type)) {
}
CheckStatus check_overloaded_function(AstOverloadedFunction* func) {
+ b32 done = 1;
+
bh_arr_each(AstTyped *, node, func->overloads) {
if ( (*node)->kind != Ast_Kind_Function
&& (*node)->kind != Ast_Kind_Polymorphic_Proc
return Check_Error;
}
+
+ if ((*node)->entity && (*node)->entity->state <= Entity_State_Check_Types) {
+ done = 0;
+ }
}
- return Check_Success;
+ if (done) return Check_Success;
+ else return Check_Yield_Macro;
}
CheckStatus check_struct(AstStructType* s_node) {
+ if (s_node->entity_defaults && s_node->entity_defaults->state < Entity_State_Check_Types) return Check_Yield_Macro;
+
bh_arr_each(AstStructMember *, smem, s_node->members) {
if ((*smem)->type_node == NULL && (*smem)->initial_value != NULL) {
CHECK(expression, &(*smem)->initial_value);
// NOTE: fills in the stcache
type_build_from_ast(context.ast_alloc, (AstType *) s_node);
- if (s_node->stcache == NULL) return Check_Error;
+ if (s_node->stcache == NULL) return Check_Yield_Macro;
bh_arr_each(StructMember *, smem, s_node->stcache->Struct.memarr) {
if ((*smem)->type->kind == Type_Kind_Compound) {
}
CheckStatus check_struct_defaults(AstStructType* s_node) {
+ if (s_node->entity_type && s_node->entity_type->state < Entity_State_Code_Gen) return Check_Yield_Macro;
+
bh_arr_each(StructMember *, smem, s_node->stcache->Struct.memarr) {
if ((*smem)->initial_value && *(*smem)->initial_value) {
CHECK(expression, (*smem)->initial_value);
}
CheckStatus check_function_header(AstFunction* func) {
+ if (func->entity_body && func->entity_body->state < Entity_State_Check_Types) return Check_Yield_Macro;
+
b32 expect_default_param = 0;
b32 has_had_varargs = 0;
if (local->type == NULL) {
onyx_report_error(param->local->token->pos,
- "Unable to resolve type for parameter, '%b'.\n",
+ "Unable to resolve type for parameter, '%b'",
local->token->text,
local->token->length);
return Check_Error;
}
} else {
+ if (memres->initial_value->type == NULL && memres->initial_value->entity != NULL && memres->initial_value->entity->state <= Entity_State_Check_Types) {
+ return Check_Yield_Macro;
+ }
memres->type = memres->initial_value->type;
}
}
return Check_Complete;
}
+CheckStatus check_process_directive(AstNode* directive) {
+ if (directive->kind == Ast_Kind_Directive_Export) {
+ AstTyped* export = ((AstDirectiveExport *) directive)->export;
+ if (export->entity && export->entity->state <= Entity_State_Check_Types) return Check_Yield_Macro;
+ }
+
+ return Check_Success;
+}
+
CheckStatus check_node(AstNode* node) {
switch (node->kind) {
case Ast_Kind_Function: return check_function((AstFunction *) node);
cs = check_type(ent->type_alias);
break;
+ case Entity_Type_Process_Directive: cs = check_process_directive((AstNode *) ent->expr); break;
+
default: break;
}
if (cs == Check_Success) ent->state = Entity_State_Code_Gen;
if (cs == Check_Complete) ent->state = Entity_State_Finalized;
if (cs == Check_Yield_Macro) ent->macro_attempts++;
+ else {
+ ent->macro_attempts = 0;
+ ent->micro_attempts = 0;
+ }
}
static inline i32 entity_phase(Entity* e1) {
if (e1->state <= Entity_State_Parse) return 1;
- if (e1->state < Entity_State_Code_Gen) return 3;
- return 4;
+ if (e1->state < Entity_State_Code_Gen) return 2;
+ return 3;
}
// NOTE: Returns >0 if e1 should be processed after e2.
ent.type = Entity_Type_Struct_Member_Default;
ent.type_alias = (AstType *) node;
ENTITY_INSERT(ent);
+ ((AstStructType *) node)->entity_defaults = entity;
// fallthrough
}
ent.type = Entity_Type_Type_Alias;
ent.type_alias = (AstType *) node;
ENTITY_INSERT(ent);
+
+ if (node->kind == Ast_Kind_Struct_Type) {
+ ((AstStructType *) node)->entity_type = entity;
+ }
+
break;
}
break;
}
}
+
+ node->entity = entity;
}
AstStructMember *member = s_node->members[i];
if (member->type_node) {
- SYMRES(type, &member->type_node);
+ SymresStatus ss = symres_type(&member->type_node);
+ if (ss != Symres_Success) {
+ s_node->flags &= ~Ast_Flag_Type_Is_Resolved;
+ return ss;
+ }
if (!node_is_type((AstNode *) member->type_node)) {
onyx_report_error(member->token->pos, "Member type is not a type.");
scope_enter(func->scope);
if ((func->flags & Ast_Flag_Has_Been_Symres) == 0) {
- func->flags |= Ast_Flag_Has_Been_Symres;
-
bh_arr_each(AstParam, param, func->params) {
symbol_introduce(curr_scope, param->local->token, (AstNode *) param->local);
if (param->local->flags & Ast_Flag_Param_Use) {
if (param->local->type_node != NULL && param->local->type == NULL) {
param->local->type = type_build_from_ast(context.ast_alloc, param->local->type_node);
+
+ if (param->local->type == NULL) {
+ // HACK HACK HACK
+ return Symres_Yield_Macro;
+ }
}
if (type_is_struct(param->local->type)) {
}
}
}
+
+ func->flags |= Ast_Flag_Has_Been_Symres;
}
SYMRES(block, func->body);
switch (type_node->kind) {
case Ast_Kind_Pointer_Type: {
Type* ptr_type = type_make_pointer(alloc, type_build_from_ast(alloc, ((AstPointerType *) type_node)->elem));
- ptr_type->ast_type = type_node;
+ if (ptr_type) ptr_type->ast_type = type_node;
return ptr_type;
}
if ((*member)->type == NULL) {
// :ExplicitTyping
- onyx_report_error((*member)->token->pos, "Unable to resolve member type. Try adding it explicitly.");
+ // onyx_report_error((*member)->token->pos, "Unable to resolve member type. Try adding it explicitly.");
s_node->stcache = NULL;
return NULL;
}
case Ast_Kind_Slice_Type: {
Type* slice_type = type_make_slice(alloc, type_build_from_ast(alloc, ((AstSliceType *) type_node)->elem));
- slice_type->ast_type = type_node;
+ if (slice_type) slice_type->ast_type = type_node;
return slice_type;
}
case Ast_Kind_DynArr_Type: {
Type* dynarr_type = type_make_dynarray(alloc, type_build_from_ast(alloc, ((AstDynArrType *) type_node)->elem));
- dynarr_type->ast_type = type_node;
+ if (dynarr_type) dynarr_type->ast_type = type_node;
return dynarr_type;
}
case Ast_Kind_VarArg_Type: {
Type* va_type = type_make_varargs(alloc, type_build_from_ast(alloc, ((AstVarArgType *) type_node)->elem));
- va_type->ast_type = type_node;
+ if (va_type) va_type->ast_type = type_node;
return va_type;
}
}
Type* type_make_pointer(bh_allocator alloc, Type* to) {
+ if (to == NULL) return NULL;
+
Type* ptr_type = bh_alloc_item(alloc, Type);
ptr_type->kind = Type_Kind_Pointer;
}
Type* type_make_array(bh_allocator alloc, Type* to, u32 count) {
+ if (to == NULL) return NULL;
+
Type* arr_type = bh_alloc_item(alloc, Type);
arr_type->kind = Type_Kind_Array;
}
Type* type_make_slice(bh_allocator alloc, Type* of) {
+ if (of == NULL) return NULL;
+
Type* slice_type = bh_alloc(alloc, sizeof(Type));
slice_type->kind = Type_Kind_Slice;
slice_type->Slice.ptr_to_data = type_make_pointer(alloc, of);
}
Type* type_make_dynarray(bh_allocator alloc, Type* of) {
+ if (of == NULL) return NULL;
+
Type* dynarr = bh_alloc(alloc, sizeof(Type));
dynarr->kind = Type_Kind_DynArray;
dynarr->DynArray.ptr_to_data = type_make_pointer(alloc, of);
}
Type* type_make_varargs(bh_allocator alloc, Type* of) {
+ if (of == NULL) return NULL;
+
Type* va_type = bh_alloc(alloc, sizeof(Type));
va_type->kind = Type_Kind_VarArgs;
va_type->VarArgs.ptr_to_data = type_make_pointer(alloc, of);
// NOTE: Overload is not something that is known to be overloadable.
if (overload == NULL) continue;
if (overload->kind != Ast_Kind_Function) continue;
+ if (overload->type == NULL) continue;
// NOTE: If the arguments cannot be placed successfully in the parameters list
if (!fill_in_arguments(&args, (AstNode *) overload, NULL)) continue;
}
else if (type->kind == Type_Kind_Function) {
- // CLEANUP ROBUSTNESS: This should use the 'null_proc' instead of whatever is at
- // function index 0.
WID(WI_I32_CONST, mod->null_proc_func_idx);
}
else {