]> Nishi Git Mirror - gwion.git/commitdiff
:art: Check internal usr operators 150/head
authorfennecdjay <astor.jeremie@wanadoo.fr>
Wed, 2 Oct 2019 21:59:21 +0000 (23:59 +0200)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Wed, 2 Oct 2019 21:59:21 +0000 (23:59 +0200)
ast
src/emit/emit.c
src/parse/scan1.c

diff --git a/ast b/ast
index 03bc1aa5abcd342240fd41ad0c46e2f824940b2f..52b685d2b39fa1cdee9220d9a2f2eff18bb82424 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit 03bc1aa5abcd342240fd41ad0c46e2f824940b2f
+Subproject commit 52b685d2b39fa1cdee9220d9a2f2eff18bb82424
index 744195bafbc044452315184d62ff3218b4b4b71d..58b0460fba1bbe6e6d30a5f9768013957bad44ef 100644 (file)
@@ -1754,14 +1754,21 @@ ANN static void emit_func_def_return(const Emitter emit) {
     emit_add_instr(emit, MemoizeStore);
 }
 
-ANN static void emit_func_def_code(const Emitter emit, const Func func) {
-  const m_bool is_dtor = func->def->base->xid == insert_symbol("@dtor");// could be get flag
-  func->code = finalyze(emit, !is_dtor ? FuncReturn : DTOR_EOC);
-  if(is_dtor) {
-    emit->env->class_def->nspc->dtor = func->code;
-    ADD_REF(func->code)
-  } else if(func->def->base->xid == insert_symbol("@gack"))
-    emit->env->class_def->e->gack = func->code;
+ANN static VM_Code emit_internal(const Emitter emit, const Func f) {
+  if(f->def->base->xid == insert_symbol("@dtor")) {
+    emit->env->class_def->nspc->dtor = f->code = finalyze(emit, DTOR_EOC);
+    ADD_REF(f->code)
+    return f->code;
+  } else if(f->def->base->xid == insert_symbol("@gack"))
+    emit->env->class_def->e->gack = f->code;
+  return finalyze(emit, FuncReturn);
+}
+
+ANN static VM_Code emit_func_def_code(const Emitter emit, const Func func) {
+  if(GET_FLAG(func->def, typedef))
+    return emit_internal(emit, func);
+  else
+    return finalyze(emit, FuncReturn);
 }
 
 ANN static m_bool _fdef_body(const Emitter emit, const Func_Def fdef) {
@@ -1820,7 +1827,7 @@ ANN static m_bool emit_func_def(const Emitter emit, const Func_Def fdef) {
   if(fdef->base->tmpl)
     emit_pop_type(emit);
   if(ret > 0) {
-    emit_func_def_code(emit, func);
+    func->code = emit_func_def_code(emit, func);
     emit->env->func = former;
     if(!emit->env->class_def && !GET_FLAG(fdef, global) && !fdef->base->tmpl)
       emit_func_def_global(emit, func->value_ref);
index 056f0a8c7bf25012486246373dd73354fad07887..e96957fff4c4cf843e9ae981fc3913cc177246ca 100644 (file)
@@ -346,9 +346,50 @@ ANN static m_bool scan1_stmt_list(const Env env, Stmt_List l) {
   return GW_OK;
 }
 
+ANN static m_bool class_internal(const Env env, const Func_Base *base) {
+  if(!env->class_def)
+    ERR_B(td_pos(base->td), _("'%s' must be in class def!!"), s_name(base->xid))
+  if(base->args)
+    ERR_B(td_pos(base->td), _("'%s' must not have args"), s_name(base->xid))
+  if(base->ret_type != env->gwion->type[et_void])
+    ERR_B(td_pos(base->td), _("'%s' must return 'void'"), s_name(base->xid))
+  return GW_OK;
+}
+
+ANN static inline m_bool scan_internal_arg(const Env env, const Func_Base *base) {
+  if(base->args && !base->args->next)
+    return GW_OK;
+  ERR_B(td_pos(base->td), _("'%s' must have one (and only one) argument"), base->xid)
+}
+
+ANN static inline m_bool scan_internal_int(const Env env, const Func_Base *base) {
+    CHECK_BB(scan_internal_arg(env, base))
+    if(isa(base->ret_type, env->gwion->type[et_int]) > 0)
+      return GW_OK;
+    ERR_B(td_pos(base->td), _("'%s' must must return 'int'"), base->xid)
+}
+
+ANN static m_bool scan_internal(const Env env, const Func_Base *base) {
+  const Symbol op = base->xid;
+  if(op == insert_symbol("@dtor") || op == insert_symbol("@gack"))
+    return class_internal(env, base);
+  if(op == insert_symbol("@implicit"))
+    return scan_internal_arg(env, base);
+  if(op == insert_symbol("@access")       ||
+     op == insert_symbol("@repeat")       ||
+     op == insert_symbol("@conditionnal") ||
+     op == insert_symbol("@unconditionnal"))
+    return scan_internal_int(env, base);
+  return GW_ERROR;
+}
+
 ANN m_bool scan1_fdef(const Env env, const Func_Def fdef) {
   if(fdef->base->td)
     CHECK_OB((fdef->base->ret_type = known_type(env, fdef->base->td)))
+  if(GET_FLAG(fdef, typedef))
+    CHECK_BB(scan_internal(env, fdef->base))
+  else if(GET_FLAG(fdef, op) && env->class_def)
+    SET_FLAG(fdef, static);
   if(fdef->base->args)
     CHECK_BB(scan1_args(env, fdef->base->args))
   if(!GET_FLAG(fdef, builtin) && fdef->d.code)
@@ -361,14 +402,6 @@ ANN m_bool scan1_func_def(const Env env, const Func_Def fdef) {
     CHECK_BB(env_storage(env, fdef->flag, td_pos(fdef->base->td)))
   if(tmpl_base(fdef->base->tmpl))
     return GW_OK;
-  if(GET_FLAG(fdef, op)) {
-    if(fdef->base->xid == insert_symbol("@dtor") || fdef->base->xid == insert_symbol("@gack")) {
-      if(!env->class_def)
-        ERR_B(td_pos(fdef->base->td), _("'%s' must be in class def!!"), s_name(fdef->base->xid))
-      if(fdef->base->args)exit(3);
-    } else if(env->class_def)
-      SET_FLAG(fdef, static);
-  }
   struct Func_ fake = { .name=s_name(fdef->base->xid) }, *const former = env->func;
   env->func = &fake;
   ++env->scope->depth;