]> Nishi Git Mirror - gwion.git/commitdiff
:art: Class extensions
authorJérémie Astor <fennecdjay@gmail.com>
Thu, 1 Apr 2021 13:13:56 +0000 (15:13 +0200)
committerJérémie Astor <fennecdjay@gmail.com>
Thu, 1 Apr 2021 13:13:56 +0000 (15:13 +0200)
ast
include/env/envset.h
src/clean.c
src/emit/emit.c
src/parse/check.c
src/parse/scan0.c
src/parse/scan1.c
src/parse/scan2.c

diff --git a/ast b/ast
index 013b45fa2eb8fe73168edcba9db48c82b604f697..28c178f86cbd1ecab069ce30807d8394b051b985 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit 013b45fa2eb8fe73168edcba9db48c82b604f697
+Subproject commit 28c178f86cbd1ecab069ce30807d8394b051b985
index c9838df6997cf489ac20854d805c6f63d3bc2add..ef11dadf4afbfb18bcdf05bcd3f8ccf67b88967f 100644 (file)
@@ -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
index f677fd1749db1cc1c443b907bbcbc00882ce8bc5..92651251e3e11c184c3fcf23af41cd80d0227888 100644 (file)
@@ -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) {
index f0e0d2ceaa3305d830945229c133a6773b8e5a6b..82bf748802c32aae1eb5aef939750e8a5e614ba1 100644 (file)
@@ -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;
index 82c2b10a5b0d31a9074b48e8176ca5c8b72a4e57..6133d0dde8477f19cccf32fa5045bca27380caf1 100644 (file)
@@ -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) {
index 401008e6f1d55f53ee6a224ca6dcc1187cefc46c..9c743131ddc5c7526ec60132bc30d1f6837d3409 100644 (file)
@@ -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) {
index 1ee0c1d0b474000ff692377f3b6400f3ffe5b812..77e7cdbe6f04426452d0fc3dd57da9d4a509f8be 100644 (file)
@@ -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) {
index 1196b2b944d1a2313c90b73ad222a54e413bf996..3cd0aeb405398ba512bf0544bf94822d9a4de39c 100644 (file)
@@ -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) {