From 4654d47a7cac4a9c6c7a3c58658d571c1b0d858d Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Thu, 1 Apr 2021 15:13:56 +0200 Subject: [PATCH] :art: Class extensions --- ast | 2 +- include/env/envset.h | 12 ++++++++++++ src/clean.c | 6 +++++- src/emit/emit.c | 21 ++++++++++++++------- src/parse/check.c | 8 +++++++- src/parse/scan0.c | 18 +++++++++++++++++- src/parse/scan1.c | 9 ++++++++- src/parse/scan2.c | 9 ++++++++- 8 files changed, 72 insertions(+), 13 deletions(-) diff --git a/ast b/ast index 013b45fa..28c178f8 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit 013b45fa2eb8fe73168edcba9db48c82b604f697 +Subproject commit 28c178f86cbd1ecab069ce30807d8394b051b985 diff --git a/include/env/envset.h b/include/env/envset.h index c9838df6..ef11dadf 100644 --- a/include/env/envset.h +++ b/include/env/envset.h @@ -14,4 +14,16 @@ struct EnvSet { ANN m_bool envset_run(struct EnvSet*, const Type); ANN2(1,3) m_bool envset_push(struct EnvSet*, const Type, const Nspc); ANN2(1) void envset_pop(struct EnvSet*, const Type); + +ANN static inline m_bool extend_push(const Env env, const Type t) { + if(t->info->parent) + CHECK_BB(extend_push(env, t->info->parent)) + return env_push_type(env, t); +} + +ANN static inline void extend_pop(const Env env, const Type t) { + env_pop(env, 0); + if(t->info->parent) + extend_pop(env, t->info->parent); +} #endif diff --git a/src/clean.c b/src/clean.c index f677fd17..92651251 100644 --- a/src/clean.c +++ b/src/clean.c @@ -293,6 +293,11 @@ ANN void func_def_cleaner(const Gwion gwion, Func_Def b) { free_func_def(gwion->mp, b); } +ANN static void clean_extend_def(Clean *a, Extend_Def b) { + clean_type_decl(a, b->td); + clean_ast(a, b->body); +} + ANN static void clean_class_def(Clean *a, Class_Def b) { clean_type_def(a, &b->base); if(b->body) @@ -340,7 +345,6 @@ ANN static void clean_type_def(Clean *a, Type_Def b) { if(b->tmpl) clean_tmpl(a, b->tmpl); } -#define clean_extend clean_class_def DECL_SECTION_FUNC(clean, void, Clean*) ANN static inline void clean_section(Clean *a, Section *b) { diff --git a/src/emit/emit.c b/src/emit/emit.c index f0e0d2ce..82bf7488 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -2287,10 +2287,23 @@ ANN static m_bool emit_func_def(const Emitter emit, const Func_Def f) { return ret; } +ANN static m_bool emit_extend_def(const Emitter emit, const Extend_Def xdef); #define emit_fptr_def dummy_func -#define emit_extend dummy_func HANDLE_SECTION_FUNC(emit, m_bool, Emitter) +ANN static inline m_bool emit_ast_inner(const Emitter emit, Ast ast) { + do CHECK_BB(emit_section(emit, ast->section)) + while((ast = ast->next)); + return emit_defers(emit); +} + +ANN static m_bool emit_extend_def(const Emitter emit, const Extend_Def xdef) { + CHECK_BB(extend_push(emit->env, xdef->t)) + const m_bool ret = emit_ast_inner(emit, xdef->body); + extend_pop(emit->env, xdef->t); + return ret; +} + ANN Code* emit_class_code(const Emitter emit, const m_str name) { const m_uint len = strlen(name) + 7; char c[len]; @@ -2360,12 +2373,6 @@ ANN static VM_Code emit_free_stack(const Emitter emit) { return NULL; } -ANN static inline m_bool emit_ast_inner(const Emitter emit, Ast ast) { - do CHECK_BB(emit_section(emit, ast->section)) - while((ast = ast->next)); - return emit_defers(emit); -} - ANN m_bool emit_ast(const Env env, Ast ast) { const Emitter emit = env->gwion->emit; emit->info->memoize = 0; diff --git a/src/parse/check.c b/src/parse/check.c index 82c2b10a..6133d0dd 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -1333,8 +1333,14 @@ ANN m_bool check_func_def(const Env env, const Func_Def f) { return ret; } +ANN static m_bool check_extend_def(const Env env, const Extend_Def xdef) { + CHECK_BB(extend_push(env, xdef->t)) + const m_bool ret = check_ast(env, xdef->body); + extend_pop(env, xdef->t); + return ret; +} + #define check_fptr_def dummy_func -#define check_extend dummy_func HANDLE_SECTION_FUNC(check, m_bool, Env) ANN static m_bool check_parent(const Env env, const Class_Def cdef) { diff --git a/src/parse/scan0.c b/src/parse/scan0.c index 401008e6..9c743131 100644 --- a/src/parse/scan0.c +++ b/src/parse/scan0.c @@ -342,7 +342,23 @@ ANN static m_bool scan0_stmt_list(const Env env, Stmt_List list) { } #define scan0_func_def dummy_func -#define scan0_extend dummy_func + +ANN static m_bool scan0_extend_def(const Env env, const Extend_Def xdef) { + DECL_OB(const Type, t, = known_type(env, xdef->td)) + if(isa(t, env->gwion->type[et_compound]) < 0) + ERR_B(xdef->td->pos, _("only compound types can be extended")) + if(GET_FLAG(t, final)) // TODO: add type initial declaration + ERR_B(xdef->td->pos, _("can't extend final type")) + Ast ast = xdef->body; + do { + if(ast->section->section_type == ae_section_func && + GET_FLAG(ast->section->d.func_def->base, abstract)) + ERR_B(ast->section->d.func_def->base->pos, _("can't use {/+}abstract{0} functions in {+/}extends{0}")) + } while((ast = ast->next)); + xdef->t = t; + return GW_OK; +} + HANDLE_SECTION_FUNC(scan0, m_bool, Env) ANN static m_bool scan0_class_def_inner(const Env env, const Class_Def cdef) { diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 1ee0c1d0..77e7cdbe 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -593,7 +593,14 @@ ANN m_bool scan1_func_def(const Env env, const Func_Def fdef) { env_pop(env, scope); return ret; } -#define scan1_extend dummy_func + +ANN static m_bool scan1_extend_def(const Env env, const Extend_Def xdef) { + CHECK_BB(extend_push(env, xdef->t)) + const m_bool ret = scan1_ast(env, xdef->body); + extend_pop(env, xdef->t); + return ret; +} + HANDLE_SECTION_FUNC(scan1, m_bool, Env) ANN static Type scan1_get_parent(const Env env, const Type_Def tdef) { diff --git a/src/parse/scan2.c b/src/parse/scan2.c index 1196b2b9..3cd0aeb4 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -527,8 +527,15 @@ ANN m_bool scan2_func_def(const Env env, const Func_Def fdef) { return GW_OK; } + +ANN static m_bool scan2_extend_def(const Env env, const Extend_Def xdef) { + CHECK_BB(extend_push(env, xdef->t)) + const m_bool ret = scan2_ast(env, xdef->body); + extend_pop(env, xdef->t); + return ret; +} + #define scan2_enum_def dummy_func -#define scan2_extend dummy_func HANDLE_SECTION_FUNC(scan2, m_bool, Env) ANN static m_bool scan2_parent(const Env env, const Class_Def cdef) { -- 2.43.0