]> Nishi Git Mirror - gwion.git/commitdiff
:art: Improve default args
authorfennecdjay <fennecdjay@gmail.com>
Mon, 5 Dec 2022 15:36:07 +0000 (16:36 +0100)
committerfennecdjay <fennecdjay@gmail.com>
Mon, 5 Dec 2022 15:36:07 +0000 (16:36 +0100)
src/parse/default_arg.c

index eb0231c332ad2d742f07342bc66cbe4c7ffd1765..0de4a28d82b2eccca95b71e85ce12079fdd9c47b 100644 (file)
@@ -5,74 +5,82 @@
 #include "gwion.h"
 #include "traverse.h"
 
-ANN static Exp mk_default_args(const MemPool p, const Arg_List args, const uint32_t max) {
-  Exp exp = NULL, base_exp = NULL;
-  for(uint32_t i = 0; i < args->len; i++) {
+ANN2(1,2) static Exp base_args(const MemPool p, const Arg_List args, Exp next, const uint32_t min) {
+  for(uint32_t i = min; i--;) {
     Arg *arg = mp_vector_at(args, Arg, i);
-    const Exp arg_exp = new_prim_id(p, arg->var_decl.xid, arg->var_decl.pos);
-    if(exp)
-      exp = (exp->next = arg_exp);
-    else
-      base_exp = exp = arg_exp;
+    const Exp exp = new_prim_id(p, arg->var_decl.xid, arg->var_decl.pos);
+    exp->next = next;
+    next = exp;
   }
-  // now add default args
-  for(uint32_t i = args->len; i < max; i++) {
+  return next;
+}
+
+ANN static Exp additional_args(const MemPool p, const Arg_List args, const uint32_t max) {
+  Exp next = NULL;
+  for(uint32_t i = max; i-- > args->len;) {
     Arg *arg = mp_vector_at(args, Arg, i);
-    const Exp arg_exp = cpy_exp(p, arg->exp);
-    if(exp)
-      exp = (exp->next = arg_exp);
-    else
-      base_exp = exp = arg_exp;
+    const Exp exp = cpy_exp(p, arg->exp);
+    exp->next = next;
+    next = exp;
   }
-  return base_exp;
+  return next;
+}
+
+ANN static Exp mk_args(const MemPool p, const Arg_List args, const uint32_t max) {
+  const Exp next = additional_args(p, args, max);
+  return base_args(p, args, next, args->len);
 }
 
-ANN static Stmt_List std_code(const MemPool p, Func_Base *base, const Arg_List args, const uint32_t len) {
-  const Exp efunc = new_prim_id(p, base->xid, base->pos);
-  const Exp exp_arg = mk_default_args(p, args, len);
-  const Exp ecall = new_exp_call(p, efunc, exp_arg, base->pos);
-  Stmt_List slist = new_mp_vector(p, struct Stmt_, 1);
-  mp_vector_set(slist, struct Stmt_, 0,
+ANN static Stmt_List code(const MemPool p, const Exp func, const Arg_List lst,
+       const uint32_t max, const ae_stmt_t type) {
+  const Exp arg = mk_args(p, lst, max);
+  const Exp call = new_exp_call(p, func, arg, func->pos);
+  Stmt_List code = new_mp_vector(p, struct Stmt_, 1);
+  mp_vector_set(code, struct Stmt_, 0,
     ((struct Stmt_) {
-      .stmt_type = ae_stmt_return, .d = { .stmt_exp = { .val = ecall }},
-      .pos = base->pos
+      .stmt_type = type, .d = { .stmt_exp = { .val = call }},
+      .pos = func->pos
   }));
-  return slist;
+  return code;
 }
 
-ANN static Stmt_List new_code(const Env env, Func_Base *base, const Arg_List args, const uint32_t len) {
+ANN static Stmt_List std_code(const Env env, Func_Base *base, const uint32_t max) {
   const MemPool p = env->gwion->mp;
-  const Exp dbase  = new_prim_id(p, insert_symbol(env->gwion->st, "this"), base->pos);
-  const Exp dot  = new_exp_dot(p, dbase, insert_symbol(env->gwion->st, env->class_def->name), base->pos);
-  const Exp exp_args = mk_default_args(p, args, len);
-  const Exp ecall = new_exp_call(p, dot, exp_args, base->pos);
-  Stmt_List slist = new_mp_vector(p, struct Stmt_, 1);
-  mp_vector_set(slist, struct Stmt_, 0,
-    ((struct Stmt_) {
-      .stmt_type = ae_stmt_exp, .d = { .stmt_exp = { .val = ecall }},
-      .pos = base->pos
-  }));
-  return slist;
+  const Exp func = new_prim_id(p, base->xid, base->pos);
+  return code(p, func, base->args, max, ae_stmt_return);
 }
 
-ANN void default_args(const Env env, const Section *s, Ast *acc) {
+ANN static Stmt_List new_code(const Env env, Func_Base *base, const uint32_t max) {
   const MemPool p = env->gwion->mp;
-  const Func_Def base_fdef = s->d.func_def;
-  Arg_List       args = base_fdef->base->args;
+  SymTable *st = env->gwion->st;
+  const Exp dbase  = new_prim_id(p, insert_symbol(st, "this"), base->pos);
+  const Symbol sym = insert_symbol(st, "new");
+  const Exp func  = new_exp_dot(p, dbase, sym, base->pos);
+  return code(p, func, base->args, max, ae_stmt_exp);
+}
+
+
+ANN static Func_Def _default_args(const Env env, Func_Base *fb, Ast *acc, uint32_t max) {
+  Func_Base *const base = cpy_func_base(env->gwion->mp, fb);
+  Stmt_List code = strcmp(s_name(base->xid), "new")
+      ? std_code(env, fb, max)
+      : new_code(env, fb, max);
+  const Func_Def  fdef  = new_func_def(env->gwion->mp, base, code);
+  Section section = MK_SECTION(func, func_def, fdef);
+  mp_vector_add(env->gwion->mp, acc, Section, section);
+  return fdef;
+}
+
+ANN void default_args(const Env env, const Section *s, Ast *acc) {
+  Func_Base *const fb = s->d.func_def->base;
+  Arg_List       args = fb->args;
   uint32_t len = args->len;
   while(args->len--) {
-    Arg *arg = mp_vector_at(args, Arg, args->len);
+    const Arg *arg = mp_vector_at(args, Arg, args->len);
     if(!arg->exp) break;
-    Func_Base *const base = cpy_func_base(p, base_fdef->base);
-    Stmt_List code = strcmp(s_name(base->xid), "new")
-        ? std_code(env->gwion->mp, base, args, len)
-        : new_code(env, base, args, len);
-//    const Stmt      body  = new_stmt_code(p, slist, base->pos);
-    const Func_Def  fdef  = new_func_def(p, base, code);
+    const Func_Def fdef = _default_args(env, fb, acc, len);
     scan1_func_def(env, fdef);
     scan2_func_def(env, fdef);
-    Section section = MK_SECTION(func, func_def, fdef);
-    mp_vector_add(p, acc, Section, section);
   }
   args->len = len;
 }