diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-02-16 00:20:18 +0200 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-02-16 00:20:18 +0200 |
| commit | a83f6a2e53de7a9322755d68ebc9f13e3babecc2 (patch) | |
| tree | 599c2a5173f42d5a9b99e5cfdc1dcfe288bb2165 /src/actualize.c | |
| parent | c85e4b4d2411e60af7387dec663ea62b03743eab (diff) | |
| download | ek-a83f6a2e53de7a9322755d68ebc9f13e3babecc2.tar.gz ek-a83f6a2e53de7a9322755d68ebc9f13e3babecc2.zip | |
rework
+ Kind of only a partial commit, but whatever, this history is pretty
ugly anyway
Diffstat (limited to 'src/actualize.c')
| -rw-r--r-- | src/actualize.c | 147 |
1 files changed, 67 insertions, 80 deletions
diff --git a/src/actualize.c b/src/actualize.c index 694eca9..591df1a 100644 --- a/src/actualize.c +++ b/src/actualize.c @@ -288,7 +288,7 @@ static int analyze_file_visibility(struct scope *scope, struct ast_node *node) case AST_IMPORT: { const char *file = AST_IMPORT(node).file; ret |= process_file(&scope, - ast_flags(node, AST_FLAG_PUBLIC), file); + ast_flags(node, AST_FLAG_PUBLIC), file); break; } @@ -329,11 +329,6 @@ static int analyze_file_visibility(struct scope *scope, struct ast_node *node) break; } - case AST_TYPE_CONSTRUCT: { - ret |= scope_add_type_construct(scope, node); - break; - } - case AST_MACRO_CONSTRUCT: { ret |= scope_add_macro(scope, node); break; @@ -377,7 +372,6 @@ static int analyze(struct scope *scope, struct ast_node *tree) int analyze_root(struct scope *scope, struct ast_node *tree) { - scope_add_defaults(scope); if (analyze(scope, tree)) return -1; @@ -410,10 +404,6 @@ int types_match(struct ast_node *a, struct ast_node *b) assert(a->node_type == AST_TYPE); assert(b->node_type == AST_TYPE); - /* typeofs match 'everything' */ - if (AST_TYPE(a).kind == AST_TYPE_TYPEOF || AST_TYPE(b).kind == AST_TYPE_TYPEOF) - return 1; - /* if the type kind doesn't match, we're done. */ if (AST_TYPE(a).kind != AST_TYPE(b).kind) return 0; @@ -423,7 +413,7 @@ int types_match(struct ast_node *a, struct ast_node *b) if (AST_TYPE(a).kind == AST_TYPE_POINTER) return types_match(AST_PTR_TYPE(a).base, - AST_PTR_TYPE(b).base); + AST_PTR_TYPE(b).base); if (AST_TYPE(a).kind == AST_TYPE_PRIMITIVE) return primitives_match(a, b); @@ -467,7 +457,7 @@ static int replace_id(struct ast_node *body, struct ast_node *id, } static int actualize_macro_construct(struct act_state *state, - struct scope *scope, struct ast_node *n) + struct scope *scope, struct ast_node *n) { UNUSED(state); /* macro bodies, arguments, etc aren't expanded upon until the macro is @@ -476,18 +466,6 @@ static int actualize_macro_construct(struct act_state *state, return scope_add_macro(scope, n); } -struct ast_node *extract_typeof(struct ast_node *type) -{ - if (!type) - return 0; - - assert(type->node_type == AST_TYPE); - if (type->_type.kind == AST_TYPE_TYPEOF) - return type; - - return extract_typeof(type->_type.next); -} - struct ast_node *extract_trait(struct ast_node *type) { if (!type) @@ -501,7 +479,7 @@ struct ast_node *extract_trait(struct ast_node *type) } static void actualize_trait_types(struct ast_node *params, - struct ast_node *args) + struct ast_node *args) { /** @todo replace trait types with arg types, should probably be merged * */ @@ -534,11 +512,12 @@ static int actualize_proc_call(struct act_state *state, } static int actualize_macro_expand(struct act_state *state, - struct scope *scope, struct ast_node *macro_expand) + struct scope *scope, + struct ast_node *macro_expand) { assert(macro_expand->node_type == AST_MACRO_EXPAND); struct ast_node *id = AST_MACRO_EXPAND(macro_expand).id; - struct ast_node *macro = file_scope_resolve_macro(scope, id); + struct ast_node *macro = file_scope_find_macro(scope, id); if (!macro) { semantic_error(scope->fctx, macro_expand, "no such macro"); return -1; @@ -596,11 +575,16 @@ static int actualize_call(struct act_state *state, /* check that arguments exist, make sure they have types etc. */ /* TODO: procedure callbacks? */ - int ret = actualize(state, scope, call->_call.args); + int ret = actualize(state, scope, AST_CALL(call).args); if (ret) return ret; - struct ast_node *callable = file_scope_resolve_call(scope, call); + ret = actualize(state, scope, AST_CALL(call).expr); + if (ret) + return ret; + + /** @todo check if call args and expr types match */ + struct ast_node *callable = file_scope_find_proc(scope, call); if (!callable) { char *str = call_str(call); semantic_error(scope->fctx, call, "no such callable: %s", str); @@ -609,6 +593,8 @@ static int actualize_call(struct act_state *state, } assert(callable->node_type == AST_PROC); + /** @todo we should probably start with just iterating over all procs and check + * if they're valid rather than generating them on 'demand' */ return actualize_proc_call(state, scope, call, callable); } @@ -622,7 +608,7 @@ static void warn_unused_labels(struct act_state *state, struct scope *scope) struct ast_node *label = labels->node; if (!ast_flags(label, AST_FLAG_ACTUAL)) semantic_warn(scope->fctx, label, - "unused label"); + "unused label"); } while ((labels = labels->next)); } @@ -638,7 +624,7 @@ static int undefined_gotos(struct act_state *state, struct scope *scope) struct ast_node *got = gotos->node; if (!ast_flags(got, AST_FLAG_ACTUAL)) { semantic_warn(scope->fctx, got, - "undefined label"); + "undefined label"); ret = -1; } @@ -808,27 +794,27 @@ static int actualize_id(struct act_state *state, /** @todo at the moment we always assume an ID is a variable, but stuff * like function callbacks should be added in the future */ struct ast_node *decl = file_scope_find_var(scope, id); - if (!decl) { - semantic_error(scope->fctx, id, "no such object"); - return -1; + if (decl) { + id->type = decl->type; + return 0; } - if (!decl->type) { - semantic_error(scope->fctx, id, - "no type associated with object"); - return -1; + decl = file_scope_find_proc(scope, id); + if (decl) { + id->type = decl->type; + return 0; } - id->type = decl->type; - return 0; + semantic_error(scope->fctx, id, "no such object"); + return -1; } static int actualize_var(struct act_state *state, struct scope *scope, struct ast_node *var) { assert(var && var->node_type == AST_VAR); - struct ast_node *init = var->_var.init; - struct ast_node *type = var->_var.type; + struct ast_node *init = AST_VAR(var).init; + struct ast_node *type = AST_VAR(var).type; /* one of these must be defined, otherwise the parser fucked up */ assert(type || init); @@ -881,11 +867,11 @@ static int actualize_var(struct act_state *state, enum act_flags old_flags = state->flags; \ struct ast_node *old_trait = state->cur_trait; -#define EXIT_ACT(r) \ - do { \ +#define EXIT_ACT(r) \ + do { \ state->cur_trait = old_trait; \ - state->flags = old_flags; \ - return r; \ + state->flags = old_flags; \ + return r; \ } while (0); static int actualize_type(struct act_state *state, @@ -908,10 +894,12 @@ static int actualize_type(struct act_state *state, * they're missing, void */ if (!AST_ID_TYPE(type).id) { /* no ID means void */ - AST_ID_TYPE(type).id = gen_id(strdup("void"), NULL_LOC()); + AST_ID_TYPE(type).id = + gen_id(strdup("void"), NULL_LOC()); } - struct ast_node *exists = file_scope_find_type(scope, AST_ID_TYPE(type).id); + struct ast_node *exists = file_scope_find_type(scope, AST_ID_TYPE( + type).id); if (!exists) { semantic_error(scope->fctx, type, "no such type"); EXIT_ACT(-1); @@ -945,26 +933,16 @@ static int actualize_type(struct act_state *state, break; } - case AST_TYPE_ARR: - /* TODO: expression should be expandable to integer constant */ + case AST_TYPE_CONSTRUCT: + semantic_info(scope->fctx, type, + "constructs unimplemented, continuing with compilation to see what breaks"); break; - case AST_TYPE_TYPEOF: { - struct ast_node *expr = AST_TYPEOF_TYPE(type).expr; - /* TODO: expressions in top-level type declarations should - * probably be checked for, as we might not want to accidentally - * actualize procedure calls? */ - if (actualize(state, scope, expr)) - EXIT_ACT(-1); - - /* TODO: for now just trust that the expression is not looped or - * anything dumb like that, but I would feel better if I figure - * out some check */ - assert(type->_type.next == NULL); - /** @todo add in some 'from' field for this situation? */ - type->type = expr->type; + case AST_TYPE_ARR: + /* TODO: expression should be expandable to integer constant */ + semantic_info(scope->fctx, type, + "arrays unimplemented, continuing with compilation to see what breaks"); break; - } case AST_TYPE_POINTER: assert(AST_PTR_TYPE(type).base); @@ -1019,7 +997,7 @@ static int actualize_empty(struct act_state *state, return -1; } - node->type = gen_type(AST_TYPE_ID, void_id, NULL, NULL); + node->type = gen_type(AST_TYPE_ID, void_id, NULL, NULL_LOC()); if (!node->type) { internal_error("couldn't allocate type for empty statement\n"); return -1; @@ -1186,11 +1164,11 @@ static int init_struct(struct act_state *state, struct scope *scope, break; } - if (!implements(0, scope, args->type, member->type)) { + if (!types_match(args->type, member->type)) { char *astr = type_str(args->type); char *mstr = type_str(member->type); semantic_error(scope->fctx, args, - "%s does not implement %s", astr, mstr); + "%s does not match %s", astr, mstr); free(astr); free(mstr); ret = -1; @@ -1351,7 +1329,7 @@ static int actualize_alias(struct act_state *state, struct scope *scope, } static int actualize_trait(struct act_state *state, struct scope *scope, - struct ast_node *trait) + struct ast_node *trait) { assert(trait->node_type == AST_TRAIT); ast_set_flags(trait, AST_FLAG_ACTUAL); @@ -1565,8 +1543,9 @@ static int actualize_unop(struct act_state *state, } case AST_REF: { - node->type = gen_type(AST_TYPE_POINTER, NULL, NULL, NULL); - node->type->_type.next = expr->type; + node->type = gen_type(AST_TYPE_POINTER, NULL, NULL, + NULL_LOC()); + node->AST_TYPE(type).next = expr->type; break; } @@ -1613,7 +1592,8 @@ static int actualize_struct(struct act_state *state, /* cloning slightly odd, but I guess it's fine? */ struct ast_node *clone_id = clone_ast_node(node->_struct.id); - node->type = gen_type(AST_TYPE_STRUCT, clone_id, NULL, NULL); + node->type = + gen_type(AST_TYPE_STRUCT, clone_id, NULL, NULL_LOC()); ast_set_flags(node, AST_FLAG_ACTUAL); return 0; @@ -1634,6 +1614,9 @@ static int has_members(struct ast_node *type) if (AST_TYPE(type).kind == AST_TYPE_TRAIT) return 1; + if (AST_TYPE(type).kind == AST_TYPE_CONSTRUCT) + return 1; + return 0; } @@ -1708,7 +1691,8 @@ static int actualize_assign(struct act_state *state, struct scope *scope, /** @todo rvalue vs lvalue? */ if (!is_lvalue(to)) { - semantic_error(scope->fctx, node, "rvalue used where lvalue required"); + semantic_error(scope->fctx, node, + "rvalue used where lvalue required"); return -1; } @@ -1730,7 +1714,8 @@ static int actualize_fetch(struct act_state *state, struct scope *scope, } struct ast_node *id = fetch->_fetch.id; - struct ast_node *def = file_scope_find_type(scope, AST_ID_TYPE(type).id); + struct ast_node *def = + file_scope_find_type(scope, AST_ID_TYPE(type).id); assert(def); struct ast_node *member = lookup_enum_member(def, id); @@ -1806,7 +1791,8 @@ static int actualize(struct act_state *state, struct scope *scope, if (!node->scope) node->scope = scope; - if (ast_flags(node, AST_FLAG_INIT) && !ast_flags(node, AST_FLAG_ACTUAL)) { + if (ast_flags(node, + AST_FLAG_INIT) && !ast_flags(node, AST_FLAG_ACTUAL)) { semantic_error(scope->fctx, node, "detected dependency loop"); return -1; } @@ -1823,8 +1809,10 @@ static int actualize(struct act_state *state, struct scope *scope, case AST_TRAIT: ret |= actualize_trait(state, scope, node); break; case AST_ALIAS: ret |= actualize_alias(state, scope, node); break; - case AST_MACRO_CONSTRUCT: ret |= actualize_macro_construct(state, scope, node); break; - case AST_MACRO_EXPAND: ret |= actualize_macro_expand(state, scope, node); break; + case AST_MACRO_CONSTRUCT: ret |= actualize_macro_construct(state, scope, + node); break; + case AST_MACRO_EXPAND: ret |= + actualize_macro_expand(state, scope, node); break; case AST_CALL: ret |= actualize_call(state, scope, node); break; case AST_BINOP: ret |= actualize_binop(state, scope, node); break; case AST_BLOCK: ret |= actualize_block(state, scope, node); break; @@ -1866,12 +1854,11 @@ static int actualize(struct act_state *state, struct scope *scope, int actualize_main(struct scope *root) { struct ast_node *main_id = gen_id(strdup("main"), NULL_LOC()); - struct ast_node *main_call = gen_call(main_id, NULL); struct act_state state = {0}; /* skip checking signature for now */ - struct ast_node *main = file_scope_resolve_call(root, main_call); + struct ast_node *main = file_scope_find_proc(root, main_id); if (!main) { /* libraries are not really compilable... */ error("no main"); |
