#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;
}