-Subproject commit bd7f714f19c2c2e237cbe4cd6a74aa2cb2dd7206
+Subproject commit 5d8450be617d21ac1aca168dd9c5cf267bebd8f1
--- /dev/null
+#ifndef __CPY_AST
+#define __CPY_AST
+ANN Func_Def cpy_func_def(MemPool, Func_Def);
+ANN struct Func_Base_* cpy_func_base(MemPool, struct Func_Base_*);
+ANN Class_Def cpy_class_def(MemPool, Class_Def);
+#endif
ANN static m_bool emit_class_def(const Emitter, const Class_Def);
ANN static m_bool emit_cdef(const Emitter, const Class_Def);
-ANN static m_bool emit_parent_inner(const Emitter emit, const Class_Def cdef) {
- CHECK_BB(traverse_cdef(emit->env, cdef))
- return emit_cdef(emit, cdef);
-}
-
ANN static inline m_bool emit_exp_decl_template(const Emitter emit, const Exp_Decl* decl) {
const Type t = decl->type;
- return !GET_FLAG(t, emit) ? emit_parent_inner(emit, t->e->def) : GW_OK;
+ return !GET_FLAG(t, emit) ? emit_cdef(emit, t->e->def) : GW_OK;
}
ANN static m_bool emit_exp_decl(const Emitter emit, const Exp_Decl* decl) {
return emit_exp(emit, exp_call->func, 0);
}
-ANN static inline m_int push_tmpl_func(const Emitter emit, const Func f) {
- const Value v = f->value_ref;
- if(isa(v->type, t_class) > 0 && is_fptr(v->type))
- return emit->env->scope->depth;
- const m_uint scope = emit_push(emit, v->owner_class, v->owner);
- CHECK_BB(traverse_func_def(emit->env, f->def))
- return (m_int)scope;
-}
-
-ANN static m_bool emit_exp_call_template(const Emitter emit, const Exp_Call* exp_call) {
- if(emit->env->func && emit->env->func == exp_call->m_func)
- return prepare_call(emit, exp_call);
- exp_call->m_func->def->base->tmpl->call = exp_call->tmpl->call;
- DECL_BB(const m_int,scope, = push_tmpl_func(emit, exp_call->m_func))
- CHECK_BB(prepare_call(emit, exp_call))
- if(!is_fptr(exp_call->m_func->value_ref->type))
- emit_pop(emit, (m_uint)scope);
- UNSET_FLAG(exp_call->m_func, checked);
- return GW_OK;
-}
-
ANN static m_bool emit_exp_call(const Emitter emit, const Exp_Call* exp_call) {
- if(!exp_call->tmpl)
- CHECK_BB(prepare_call(emit, exp_call))
- else
- CHECK_BB(emit_exp_call_template(emit, exp_call))
+ CHECK_BB(prepare_call(emit, exp_call))
return emit_exp_call1(emit, exp_call->m_func);
}
}
ANN static inline m_bool traverse_emit_func_def(const Emitter emit, const Func_Def fdef) {
- CHECK_BB(traverse_func_def(emit->env, fdef))
+ if(!fdef->base->ret_type)
+ CHECK_BB(traverse_func_def(emit->env, fdef))
return emit_func_def(emit, fdef);
}
}
ANN static m_bool emit_template_code(const Emitter emit, const Func f) {
- if(GET_FLAG(f, ref))
- CHECK_BB(traverse_class_def(emit->env, f->value_ref->owner_class->e->def))
const Value v = f->value_ref;
size_t scope = emit_push(emit, v->owner_class, v->owner);
const m_bool ret = emit_func_def(emit, f->def);
ANN static m_bool tmpl_rettype(const Emitter emit, const Func_Def fdef) {
CHECK_BB(template_push_types(emit->env, fdef->base->tmpl))
- const m_bool ret = emit_parent_inner(emit, fdef->base->ret_type->e->def);
+ const m_bool ret = emit_cdef(emit, fdef->base->ret_type->e->def);
emit_pop_type(emit);
return ret;
}
const Type parent = cdef->base.type->e->parent;
const Type base = parent->e->d.base_type;
if(base && !GET_FLAG(base, emit))
- CHECK_BB(emit_parent_inner(emit, base->e->def))
- return !GET_FLAG(parent, emit) ? emit_parent_inner(emit, parent->e->def) : GW_OK;
+ CHECK_BB(emit_cdef(emit, base->e->def))
+ return !GET_FLAG(parent, emit) ? emit_cdef(emit, parent->e->def) : GW_OK;
}
ANN static inline m_bool emit_cdef(const Emitter emit, const Class_Def cdef) {
return isa(t0, t1);
}
-ANN static m_bool fptr_args(const Env env, struct Func_Base_ *base[2]) {
+ANN static m_bool fptr_args(const Env env, Func_Base *base[2]) {
Arg_List arg0 = base[0]->args, arg1 = base[1]->args;
while(arg0) {
CHECK_OB(arg1)
const Symbol sym = (!info->lhs->def->base->tmpl || i != 0) ?
func_symbol(env, nspc->name, c, stmpl, i) : info->lhs->def->base->xid;
CHECK_OO((info->lhs = nspc_lookup_func1(nspc, sym)))
- struct Func_Base_ *base[2] = { info->lhs->def->base, info->rhs->def->base };
+ Func_Base *base[2] = { info->lhs->def->base, info->rhs->def->base };
if(fptr_tmpl_push(env, info) > 0) {
if(fptr_rettype(env, info) > 0 &&
fptr_arity(info) && fptr_args(env, base) > 0)
if(!(type_path = str2list(env, dl_fun->type, &array_depth)) ||
!(type_decl = new_type_decl(env->gwion->mp, type_path)))
GWI_ERR_O(_(" ... during fptr import '%s' (type)."), dl_fun->name);
- struct Func_Base_ *base = new_func_base(env->gwion->mp, type_decl, insert_symbol(env->gwion->st, dl_fun->name), args);
+ Func_Base *base = new_func_base(env->gwion->mp, type_decl, insert_symbol(env->gwion->st, dl_fun->name), args);
return new_stmt_fptr(env->gwion->mp, base, flag);
}
#include "gwion.h"
#include "operator.h"
#include "import.h"
+#include "cpy_ast.h"
INSTR(DTOR_EOC) {
const M_Object o = *(M_Object*)MEM(0);
const Symbol sym = func_symbol(env, nspc->name, s_name(fdef->base->xid),
"template", dt->vt_index);
DECL_OO(const Value, v, = nspc_lookup_value0(nspc, sym))
- const Func_Def base = v->d.func_ref->def;
- const Func_Def def = new_func_def(env->gwion->mp, new_func_base(env->gwion->mp, fdef->base->td, insert_symbol(env->gwion->st, v->name),
- fdef->base->args), base->d.code, fdef->flag, loc_cpy(env->gwion->mp, base->pos));
- def->base->tmpl = new_tmpl(env->gwion->mp, base->base->tmpl->list, dt->vt_index);
+ const Func_Def def = cpy_func_def(env->gwion->mp, v->d.func_ref->def);
def->base->tmpl->call = dt->tl;
+ def->base->tmpl->base = dt->vt_index;
dt->def = def;
dt->owner = v->owner;
dt->owner_class = v->owner_class;
const Type ret = type_copy(p, t);
ret->name = s_name(sym);
ret->flag = t->flag | ae_flag_force;
-// nspc_add_type(t->e->owner, sym, ret);
-// map_set(&t->e->owner->info->type->map, sym, ret);
- map_set(vector_front(&t->e->owner->info->type->ptr), sym, ret);
+ map_set(&t->e->owner->info->type->map, (vtype)sym, (vtype)ret);
return ret;
}
strcpy(name + len, STR_FORCE);
const Symbol sym = insert_symbol(env->gwion->st, name);
return nspc_lookup_type1(t->e->owner, sym) ?: new_force_type(env->gwion->mp, t, sym);
-// return nspc_lookup_type0(t->e->owner, sym) ?: new_force_type(env, t, sym);
}
static OP_CHECK(opck_object_cast) {
#include "parse.h"
#include "nspc.h"
#include "switch.h"
+#include "cpy_ast.h"
ANN static Type check_exp(const Env env, Exp exp);
ANN static m_bool check_stmt_list(const Env env, Stmt_List list);
if(decl->type == t_auto)
ERR_O(td_pos(decl->td), _("can't infer type."));
}
- if(!decl->type) // TODO: remove when scan passes are complete
+ if(!decl->type)
ERR_O(td_pos(decl->td), _("can't infer type."));
if(GET_FLAG(decl->type , template) && !GET_FLAG(decl->type, check))
CHECK_BO(traverse_cdef(env, decl->type->e->def))
const Symbol sym = func_symbol(env, v->owner->name, v->name, tmpl_name, 0);
const Value value = nspc_lookup_value1(v->owner, sym);
Func_Def base = v->d.func_ref ? v->d.func_ref->def : exp->func->type->e->d.func->def;
- struct Func_Base_ *fbase = new_func_base(env->gwion->mp, base->base->td, sym, base->base->args);
- fbase->tmpl = new_tmpl(env->gwion->mp, base->base->tmpl->list, 0);
+ Func_Base *fbase = cpy_func_base(env->gwion->mp, base->base);
+ fbase->xid = sym;
+ fbase->tmpl->base = 0;
fbase->tmpl->call = types;
if(template_push_types(env, fbase->tmpl) > 0) {
const Stmt stmt = new_stmt_fptr(env->gwion->mp, fbase, base->flag);
m_func = find_func_match(env, fbase->func, exp->args);
nspc_pop_type(env->gwion->mp, env->curr);
if(!value && m_func) {
- if(!m_func->def->base->ret_type)
- CHECK_BO(traverse_func_def(env, m_func->def))
map_set(&v->owner->info->type->map, (vtype)sym, (vtype)actual_type(m_func->value_ref->type));
}
}
}
} else {
for(m_uint i = 0; i < v->offset + 1; ++i) {
- Func_Def fdef = NULL;
- Func_Def base = NULL;
- Value value = template_get_ready(env, v, tmpl_name, i);
- if(value) {
- if(env->func == value->d.func_ref) {
+ const Value exists = template_get_ready(env, v, tmpl_name, i);
+ if(exists) {
+ if(env->func == exists->d.func_ref) {
if(check_call(env, exp) < 0)
continue;
m_func = env->func;
break;
}
- fdef = value->d.func_ref->def;
- if(!fdef->base->tmpl) {
- if(!(value = template_get_ready(env, v, "template", i)))
- continue;
- base = value->d.func_ref->def;
- fdef->base->tmpl = new_tmpl(env->gwion->mp, base->base->tmpl->list, (m_int)i);
- }
+ if((m_func = ensure_tmpl(env, exists->d.func_ref->def, exp)))
+ break;
} else {
- if(!(value = template_get_ready(env, v, "template", i)))
+ const Value value = template_get_ready(env, v, "template", i);
+ if(!value)
continue;
- base = value->d.func_ref->def;
- fdef = new_func_def(env->gwion->mp, new_func_base(env->gwion->mp, base->base->td, insert_symbol(v->name),
- base->base->args), base->d.code, base->flag, loc_cpy(env->gwion->mp, base->pos));
- fdef->base->tmpl = new_tmpl(env->gwion->mp, base->base->tmpl->list, (m_int)i);
+ const Func_Def fdef = (Func_Def)cpy_func_def(env->gwion->mp, value->d.func_ref->def);
SET_FLAG(fdef, template);
+ fdef->base->tmpl->call = types;
+ fdef->base->tmpl->base = i;
+ if((m_func = ensure_tmpl(env, fdef, exp)))
+ break;
}
- fdef->base->tmpl->call = types;
- if((m_func = ensure_tmpl(env, fdef, exp)))
- break;
}
}
free_mstr(env->gwion->mp, tmpl_name);
assert(exp_self(func));
ERR_O(exp_self(func)->pos,
_("function is template. automatic type guess not fully implemented yet.\n"
- " please provide template types. eg: '<type1, type2, ...>'"))
+ " please provide template types. eg: '<~type1, type2, ...~>'"))
+}
+
+ANN static Func predefined_func(const Env env, const Value v,
+ Exp_Call *exp, const Tmpl *tm) {
+ Tmpl tmpl = { .call=tm->call };
+ ((Exp_Call*)exp)->tmpl = &tmpl;
+ DECL_OO(const Func, func, = get_template_func(env, exp, v))
+ return v->d.func_ref = func;
}
ANN static Type check_exp_call_template(const Env env, const Exp_Call *exp) {
const Exp call = exp->func;
const Exp args = exp->args;
- m_uint args_number = 0;
DECL_OO(const Value, value, = nspc_lookup_value1(call->type->e->owner, insert_symbol(call->type->name)))
Tmpl *tm = value->d.func_ref ? value->d.func_ref->def->base->tmpl : call->type->e->d.func->def->base->tmpl;
- const m_uint type_number = get_type_number(tm->list);
- Type_List tl[type_number];
- ID_List list = tm->list;
if(tm->call) {
- if(!value->d.func_ref) {
- Tmpl tmpl = { .call=tm->call };
- ((Exp_Call*)exp)->tmpl = &tmpl;
- DECL_OO(const Func,func, = get_template_func(env, exp, value))
- assert(func->def->base->ret_type);
- value->d.func_ref = func;
- return func->def->base->ret_type;
- } else {
- const Func func = value->d.func_ref;
- if(!func->def->base->ret_type) { // template fptr
- const m_uint scope = env_push(env, value->owner_class, value->owner);
- CHECK_BO(traverse_func_def(env, func->def))
- env_pop(env, scope);
- }
- ((Exp_Call*)exp)->m_func = func;
- return func->def->base->ret_type;
+ const Func func = value->d.func_ref ?: predefined_func(env, value, exp, tm);
+ if(!func->def->base->ret_type) { // template fptr
+ const m_uint scope = env_push(env, value->owner_class, value->owner);
+ CHECK_BO(traverse_func_def(env, func->def))
+ env_pop(env, scope);
}
+ ((Exp_Call*)exp)->m_func = func;
+ return func->def->base->ret_type;
}
+ m_uint args_number = 0;
+ const m_uint type_number = get_type_number(tm->list);
+ Type_List tl[type_number];
+ ID_List list = tm->list;
while(list) {
Arg_List arg = value->d.func_ref->def->base->args;
Exp template_arg = args;
Tmpl tmpl = { .call=tl[0] };
((Exp_Call*)exp)->tmpl = &tmpl;
DECL_OO(const Func,func, = get_template_func(env, exp, value))
- if(!func->def->base->ret_type) // template fptr
- CHECK_BO(traverse_func_def(env, func->def))
return func->def->base->ret_type;
}
ANN static m_bool check_exp_call1_check(const Env env, const Exp exp) {
CHECK_OB(check_exp(env, exp))
-// if(!check_exp(env, exp))
-// ERR_B(exp->pos, _("function call using a non-existing function"))
if(isa(exp->type, t_function) < 0)
ERR_B(exp->pos, _("function call using a non-function value"))
return GW_OK;
ERR_O(exp_self(exp)->pos, _("template call of non-function value."))
if(!v->d.func_ref->def->base->tmpl)
ERR_O(exp_self(exp)->pos, _("template call of non-template function."))
- if(t->e->d.func->def->base->tmpl->call)
+ if(t->e->d.func->def->base->tmpl->call) {
+ if(env->func == t->e->d.func) {
+ CHECK_OO(check_exp(env, exp->args))
+ exp->m_func = env->func;
+ return env->func->def->base->ret_type;
+ } else
CHECK_BO(predefined_call(env, t, exp_self(exp)->pos))
+ }
const Func ret = find_template_match(env, v, exp);
CHECK_OO((exp->m_func = ret))
return ret->def->base->ret_type;
struct Op_Import opi = { .op=insert_symbol("@implicit"), .lhs=ret_type, .rhs=env->func->def->base->ret_type,
.data=(m_uint)&imp, .pos=stmt_self(stmt)->pos };
const Type ret = op_check(env, &opi);
- if(!ret)
+ if(!ret && isa(ret_type, env->func->def->base->ret_type) < 0)
ERR_B(stmt_self(stmt)->pos, _("invalid return type '%s' -- expecting '%s'"),
ret_type->name, env->func->def->base->ret_type->name)
return GW_OK;
}
ANN m_bool check_stmt_union(const Env env, const Stmt_Union stmt) {
+ if(stmt->tmpl && stmt->tmpl->base == -1) // there's a func for this
+ return GW_OK;
if(stmt->xid) {
if(env->class_def)
(!GET_FLAG(stmt, static) ? decl_member : decl_static)(env->curr, stmt->value);
return traverse_func_def(env, fdef);
}
CHECK_BB(check_func_def_override(env, fdef))
+ DECL_BB(const m_int, scope, = GET_FLAG(fdef, global) ? env_push_global(env) : env->scope->depth)
if(env->class_def) // tmpl ?
CHECK_BB(check_parent_match(env, fdef))
- else if(GET_FLAG(fdef, global))
- env_push_global(env);
const Func former = env->func;
env->func = func;
++env->scope->depth;
--env->scope->depth;
env->func = former;
if(GET_FLAG(fdef, global))
- env_push_global(env);
+ env_pop(env,scope);
return ret;
}
--- /dev/null
+#include "gwion_util.h"
+#include "gwion_ast.h"
+
+ANN static Stmt cpy_stmt(MemPool p, const Stmt src);
+ANN static Exp cpy_exp(MemPool p, const Exp src);
+ANN static ID_List cpy_id_list(MemPool p, const ID_List src);
+ANN static Type_List cpy_type_list(MemPool p, const Type_List src);
+ANN static Arg_List cpy_arg_list(MemPool p, const Arg_List src);
+ANN Class_Def cpy_class_def(MemPool p, const Class_Def src);
+ANN static Stmt_List cpy_stmt_list(MemPool p, const Stmt_List src);
+
+ANN static void cpy_exp_dot(MemPool p, Exp_Dot *a, const Exp_Dot *src) {
+ a->base = cpy_exp(p, src->base);
+ a->xid = src->xid;
+}
+
+ANN static void cpy_exp_lambda(MemPool p, Exp_Lambda *a, const Exp_Lambda *src) {
+ if(src->args)
+ a->args = cpy_arg_list(p, src->args);
+ a->code = cpy_stmt(p, src->code);
+ a->name = src->name;
+}
+
+ANN static Array_Sub cpy_array_sub(MemPool p, const Array_Sub src) {
+ Array_Sub a = mp_calloc(p, Array_Sub);
+ if(src->exp)
+ a->exp = cpy_exp(p, src->exp);
+ a->depth = src->depth;
+ return a;
+}
+
+ANN static void cpy_exp_array(MemPool p, Exp_Array *a, const Exp_Array *src) {
+ a->base = cpy_exp(p, src->base);
+ a->array = cpy_array_sub(p, src->array);
+}
+
+ANN static Var_Decl cpy_var_decl(MemPool p, const Var_Decl src) {
+ Var_Decl a = mp_calloc(p, Var_Decl);
+ a->xid = src->xid; // 1
+ if(src->array)
+ a->array = cpy_array_sub(p, src->array); // 1
+ a->pos = loc_cpy(p, src->pos); // 1
+ return a;
+}
+
+ANN static Var_Decl_List cpy_var_decl_list(MemPool p, const Var_Decl_List src) {
+ Var_Decl_List a = mp_calloc(p, Var_Decl_List);
+ a->self = cpy_var_decl(p, src->self); // 1
+ if(src->next)
+ a->next = cpy_var_decl_list(p, src->next); // 1
+ return a;
+}
+
+ANN static Type_Decl* cpy_type_decl(MemPool p, const Type_Decl* src) {
+ Type_Decl* a = mp_calloc(p, Type_Decl);
+ if(src->xid)
+ a->xid = cpy_id_list(p, src->xid); // 1
+ if(src->exp)
+ a->exp = cpy_exp(p, src->exp); // 1
+ if(src->array)
+ a->array = cpy_array_sub(p, src->array); // 1
+ if(src->types)
+ a->types = cpy_type_list(p, src->types); // 1
+ a->flag = src->flag; // 1
+ return a;
+}
+
+ANN static ID_List cpy_id_list(MemPool p, const ID_List src) {
+ ID_List a = mp_calloc(p, ID_List);
+ a->xid = src->xid; // 1
+ if(src->next)
+ a->next = cpy_id_list(p, src->next); // 1
+ a->pos = loc_cpy(p, src->pos); // 1
+ return a;
+}
+
+ANN static Type_List cpy_type_list(MemPool p, const Type_List src) {
+ Type_List a = mp_calloc(p, Type_List);
+ if(src->td)
+ a->td = cpy_type_decl(p, src->td); // 1
+ if(src->next)
+ a->next = cpy_type_list(p, src->next); // 1
+ return a;
+}
+
+ANN static void cpy_vec(MemPool p, Vec* a, const Vec* src) {
+ a->exp = cpy_exp(p, src->exp);
+ a->dim = src->dim;
+}
+
+ANN static Arg_List cpy_arg_list(MemPool p, const Arg_List src) {
+ Arg_List a = mp_calloc(p, Arg_List);
+ if(src->td)
+ a->td = cpy_type_decl(p, src->td); // 1
+ if(src->var_decl)
+ a->var_decl = cpy_var_decl(p, src->var_decl); // 1
+ if(src->next)
+ a->next = cpy_arg_list(p, src->next); // 1
+ return a;
+}
+
+ANN static void cpy_exp_decl(MemPool p, Exp_Decl *a, const Exp_Decl *src) {
+ a->td = cpy_type_decl(p, src->td);
+ a->list = cpy_var_decl_list(p, src->list);
+}
+
+ANN static void cpy_exp_primary(MemPool p, Exp_Primary *a, const Exp_Primary *src) {
+ switch(src->primary_type) {
+ case ae_primary_id:
+ a->d.var = src->d.var;
+ break;
+ case ae_primary_num:
+ a->d.num = src->d.num;
+ break;
+ case ae_primary_float:
+ a->d.fnum = src->d.fnum;
+ break;
+ case ae_primary_char:
+ a->d.chr = src->d.chr;
+ break;
+ case ae_primary_str:
+ a->d.str = src->d.str;
+ break;
+ case ae_primary_array:
+ a->d.array = cpy_array_sub(p, src->d.array);
+ break;
+ case ae_primary_vec:
+ cpy_vec(p, &a->d.vec, &src->d.vec);
+ break;
+ default:
+ a->d.exp = cpy_exp(p, src->d.exp);
+ break;
+ }
+ a->primary_type = src->primary_type;
+}
+
+ANN static Tmpl* cpy_tmpl(MemPool p, const Tmpl *src) {
+ Tmpl *a = mp_calloc(p, Tmpl);
+ if(src->list)
+ a->list = cpy_id_list(p, src->list);
+ if(src->call)
+ a->call = cpy_type_list(p, src->call);
+ a->base = src->base;
+ return a;
+}
+
+ANN static void cpy_exp_call(MemPool p, Exp_Call *a, const Exp_Call *src) {
+ a->func = cpy_exp(p, src->func);
+ if(src->args)
+ a->args = cpy_exp(p, src->args);
+ if(src->tmpl)
+ a->tmpl = cpy_tmpl(p, src->tmpl);
+}
+
+ANN static void cpy_exp_cast(MemPool p, Exp_Cast *a, const Exp_Cast *src) {
+ a->td = cpy_type_decl(p, src->td);
+ a->exp = cpy_exp(p, src->exp);
+}
+
+ANN static void cpy_exp_binary(MemPool p, Exp_Binary *a, const Exp_Binary *src) {
+ a->lhs = cpy_exp(p, src->lhs);
+ a->rhs = cpy_exp(p, src->rhs);
+ a->op = src->op;
+}
+
+ANN static void cpy_exp_postfix(MemPool p, Exp_Postfix *a, const Exp_Postfix *src) {
+ a->op = src->op;
+ a->exp = cpy_exp(p, src->exp);
+}
+
+ANN static void cpy_exp_if(MemPool p, Exp_If *a, const Exp_If *src) {
+ a->cond = cpy_exp(p, src->cond);
+ a->if_exp = cpy_exp(p, src->if_exp);
+ if(src->else_exp)
+ a->else_exp = cpy_exp(p, src->else_exp);
+}
+
+
+// TODO check me
+ANN static void cpy_exp_unary(MemPool p, Exp_Unary *a, const Exp_Unary *src) {
+ a->op = src->op;
+ if(src->exp)
+ a->exp = cpy_exp(p, src->exp);
+ if(src->td)
+ a->td = cpy_type_decl(p, src->td);
+ if(src->code)
+ a->code = cpy_stmt(p, src->code);
+}
+
+ANN static void cpy_exp_typeof(MemPool p, Exp_Typeof *a, const Exp_Typeof *src) {
+ a->exp = cpy_exp(p, src->exp);
+}
+
+ANN static Exp cpy_exp(MemPool p, const Exp src) {
+ Exp a = mp_calloc(p, Exp);
+ if(src->next)
+ a->next = cpy_exp(p, src->next);
+ switch(src->exp_type) {
+ case ae_exp_post: // !! naming
+ cpy_exp_postfix(p, &a->d.exp_post, &src->d.exp_post);
+ break;
+ case ae_exp_primary:
+ cpy_exp_primary(p, &a->d.exp_primary, &src->d.exp_primary);
+ break;
+ case ae_exp_decl:
+ cpy_exp_decl(p, &a->d.exp_decl, &src->d.exp_decl);
+ break;
+ case ae_exp_unary:
+ cpy_exp_unary(p, &a->d.exp_unary, &src->d.exp_unary);
+ break;
+ case ae_exp_binary:
+ cpy_exp_binary(p, &a->d.exp_binary, &src->d.exp_binary);
+ break;
+ case ae_exp_cast:
+ cpy_exp_cast(p, &a->d.exp_cast, &src->d.exp_cast);
+ break;
+ case ae_exp_call:
+ cpy_exp_call(p, &a->d.exp_call, &src->d.exp_call);
+ break;
+ case ae_exp_if:
+ cpy_exp_if(p, &a->d.exp_if, &src->d.exp_if);
+ break;
+ case ae_exp_dot:
+ cpy_exp_dot(p, &a->d.exp_dot, &src->d.exp_dot);
+ break;
+ case ae_exp_array:
+ cpy_exp_array(p, &a->d.exp_array, &src->d.exp_array);
+ break;
+ case ae_exp_lambda:
+ cpy_exp_lambda(p, &a->d.exp_lambda, &src->d.exp_lambda);
+ break;
+ case ae_exp_typeof:
+ cpy_exp_typeof(p, &a->d.exp_typeof, &src->d.exp_typeof);
+ break;
+ }
+ a->exp_type = src->exp_type;
+ a->meta = src->meta;// maybe meta shoyuld be set as in constructors
+ a->pos = loc_cpy(p, src->pos);
+ return a;
+}
+
+ANN static Decl_List cpy_decl_list(MemPool p, const Decl_List src) {
+ Decl_List a = mp_calloc(p, Decl_List);
+ a->self = cpy_exp(p, src->self);
+ if(src->next)
+ a->next = cpy_decl_list(p, src->next);
+ return a;
+}
+
+ANN static void cpy_stmt_exp(MemPool p, const Stmt_Exp a, const Stmt_Exp src) {
+ if(src->val)
+ a->val = cpy_exp(p, src->val);
+}
+
+ANN static void cpy_stmt_flow(MemPool p, Stmt_Flow a,const Stmt_Flow src) {
+ if(src->cond)
+ a->cond = cpy_exp(p, src->cond);
+ if(src->body)
+ a->body = cpy_stmt(p, src->body);
+ a->is_do = src->is_do;
+}
+
+ANN static void cpy_stmt_code(MemPool p, Stmt_Code a, const Stmt_Code src) {
+ if(src->stmt_list)
+ a->stmt_list = cpy_stmt_list(p, src->stmt_list);
+}
+
+ANN static void cpy_stmt_for(MemPool p, Stmt_For a, const Stmt_For src) {
+ if(src->c1)
+ a->c1 = cpy_stmt(p, src->c1);
+ if(src->c2)
+ a->c2 = cpy_stmt(p, src->c2);
+ if(src->c3)
+ a->c3 = cpy_exp(p, src->c3);
+ if(src->body)
+ a->body = cpy_stmt(p, src->body);
+}
+
+ANN static void cpy_stmt_auto(MemPool p, Stmt_Auto a, const Stmt_Auto src) {
+ if(src->sym)
+ a->sym = src->sym;
+ if(src->exp)
+ a->exp = cpy_exp(p, src->exp);
+ if(src->body)
+ a->body = cpy_stmt(p, src->body);
+ if(src->is_ptr)
+ a->is_ptr = src->is_ptr;
+}
+
+ANN static void cpy_stmt_loop(MemPool p, Stmt_Loop a, const Stmt_Loop src) {
+ if(src->cond)
+ a->cond = cpy_exp(p, src->cond);
+ if(src->body)
+ a->body = cpy_stmt(p, src->body);
+}
+
+ANN static void cpy_stmt_if(MemPool p, Stmt_If a, const Stmt_If src) {
+ if(src->cond)
+ a->cond = cpy_exp(p, src->cond);
+ if(src->if_body)
+ a->if_body = cpy_stmt(p, src->if_body);
+ if(src->else_body)
+ a->else_body = cpy_stmt(p, src->else_body);
+}
+
+ANN static void cpy_stmt_jump(MemPool p, const Stmt_Jump a,const Stmt_Jump src) {
+ a->name = src->name;
+}
+
+ANN static void cpy_stmt_switch(MemPool p, Stmt_Switch a, const Stmt_Switch src) {
+ a->val = cpy_exp(p, src->val);
+ a->stmt = cpy_stmt(p, src->stmt);
+}
+
+ANN static void cpy_stmt_enum(MemPool p, Stmt_Enum a, const Stmt_Enum src) {
+ a->list = cpy_id_list(p, src->list);
+ a->xid = src->xid;
+ a->flag = src->flag;
+}
+
+ANN Func_Base* cpy_func_base(MemPool p, const Func_Base* src) {
+ Func_Base *a = mp_calloc(p, Func_Base);
+ if(src->td)
+ a->td = cpy_type_decl(p, src->td); // 1
+ if(src->xid)
+ a->xid = src->xid; // 1
+ if(src->args)
+ a->args = cpy_arg_list(p, src->args); // 1
+ if(src->tmpl)
+ a->tmpl = cpy_tmpl(p, src->tmpl); // 1
+ return a;
+}
+
+ANN static void cpy_stmt_fptr(MemPool p, Stmt_Fptr a, const Stmt_Fptr src) {
+ a->base = cpy_func_base(p, src->base);
+}
+
+ANN static void cpy_stmt_type(MemPool p, Stmt_Type a, const Stmt_Type src) {
+ if(src->ext)
+ a->ext = cpy_type_decl(p, src->ext);
+ a->xid = src->xid;
+ if(src->tmpl)
+ a->tmpl = cpy_tmpl(p, src->tmpl);
+}
+
+ANN static void cpy_stmt_union(MemPool p, Stmt_Union a,const Stmt_Union src) {
+ a->l = cpy_decl_list(p, src->l); // 1
+ if(src->xid)
+ a->xid = src->xid; // 1
+ if(src->type_xid)
+ a->type_xid = src->type_xid; // 1
+ if(src->tmpl)
+ a->tmpl = cpy_tmpl(p, src->tmpl); // 1
+ a->flag = src->flag; // 1
+}
+
+ANN static Stmt cpy_stmt(MemPool p, const Stmt src) {
+ Stmt a = mp_calloc(p, Stmt);
+ switch(src->stmt_type) {
+ case ae_stmt_case:
+ case ae_stmt_exp:
+ if(src->d.stmt_exp.val)
+ a->d.stmt_exp.val = cpy_exp(p, src->d.stmt_exp.val);
+
+// cpy_stmt_exp(p, &a->d.stmt_exp, &src->d.stmt_exp);
+ break;
+ case ae_stmt_return:
+ if(&src->d.stmt_exp)
+ cpy_stmt_exp(p, &a->d.stmt_exp, &src->d.stmt_exp);
+ break;
+ case ae_stmt_code:
+ cpy_stmt_code(p, &a->d.stmt_code, &src->d.stmt_code);
+ break;
+ case ae_stmt_while:
+ case ae_stmt_until:
+ cpy_stmt_flow(p, &a->d.stmt_flow, &src->d.stmt_flow);
+ break;
+ case ae_stmt_loop:
+ cpy_stmt_loop(p, &a->d.stmt_loop, &src->d.stmt_loop);
+ break;
+ case ae_stmt_for:
+ cpy_stmt_for(p, &a->d.stmt_for, &src->d.stmt_for);
+ break;
+ case ae_stmt_auto:
+ cpy_stmt_auto(p, &a->d.stmt_auto, &src->d.stmt_auto);
+ break;
+ case ae_stmt_if:
+ cpy_stmt_if(p, &a->d.stmt_if, &src->d.stmt_if);
+ break;
+ case ae_stmt_jump:
+ cpy_stmt_jump(p, &a->d.stmt_jump, &src->d.stmt_jump);
+ break;
+ case ae_stmt_switch:
+ cpy_stmt_switch(p, &a->d.stmt_switch, &src->d.stmt_switch);
+ break;
+ case ae_stmt_enum:
+ cpy_stmt_enum(p, &a->d.stmt_enum, &src->d.stmt_enum);
+ break;
+ case ae_stmt_fptr:
+ cpy_stmt_fptr(p, &a->d.stmt_fptr, &src->d.stmt_fptr);
+ break;
+ case ae_stmt_type:
+ cpy_stmt_type(p, &a->d.stmt_type, &src->d.stmt_type);
+ break;
+ case ae_stmt_union:
+ cpy_stmt_union(p, &a->d.stmt_union, &src->d.stmt_union);
+ break;
+ case ae_stmt_break:
+ case ae_stmt_continue:
+ break;
+ }
+ a->stmt_type = src->stmt_type;
+ a->pos = loc_cpy(p, src->pos);
+ return a;
+}
+
+ANN Func_Def cpy_func_def(MemPool p, const Func_Def src) {
+ Func_Def a = mp_calloc(p, Func_Def);
+ a->base = cpy_func_base(p, src->base);
+ if(!GET_FLAG(a, builtin)) {
+ if(src->d.code)
+ a->d.code = cpy_stmt(p, src->d.code);
+ } else
+ a->d.dl_func_ptr = src->d.dl_func_ptr;
+ a->pos = loc_cpy(p, src->pos);
+ a->flag = src->flag;
+ return a;
+}
+
+ANN static Stmt_List cpy_stmt_list(MemPool p, const Stmt_List src) {
+ Stmt_List a = mp_calloc(p, Stmt_List);
+ if(src->next)
+ a->next = cpy_stmt_list(p, src->next);
+ a->stmt = cpy_stmt(p, src->stmt);
+ return a;
+}
+
+ANN static Section* cpy_section(MemPool p, const Section *src) {
+ Section* a = mp_calloc(p, Section);
+ switch(src->section_type) {
+ case ae_section_stmt:
+ a->d.stmt_list = cpy_stmt_list(p, src->d.stmt_list);
+ break;
+ case ae_section_class:
+ a->d.class_def = cpy_class_def(p, src->d.class_def);
+ break;
+ case ae_section_func:
+ a->d.func_def = cpy_func_def(p, src->d.func_def);
+ break;
+ }
+ a->section_type = src->section_type;
+ return a;
+}
+
+ANN static Class_Body cpy_class_body(MemPool p, const Class_Body src) {
+ Class_Body a = mp_calloc(p, Class_Body);
+ a->section = cpy_section(p, src->section);
+ if(src->next)
+ a->next = cpy_class_body(p, src->next);
+ return a;
+}
+
+ANN Class_Def cpy_class_def(MemPool p, const Class_Def src) {
+ Class_Def a = mp_calloc(p, Class_Def);
+ cpy_stmt_type(p, &a->base, &src->base);
+ if(src->body) {
+ if(!GET_FLAG(src, union))
+ a->body = cpy_class_body(p, src->body);
+ else
+ a->list = cpy_decl_list(p, src->list);
+ }
+ a->flag = src->flag;
+ a->pos = loc_cpy(p, src->pos);
+ return a;
+}
+
+ANN static Ast cpy_ast(MemPool p, const Ast src) {
+ Ast a = mp_calloc(p, Ast);
+ a->section = cpy_section(p, src->section);
+ if(src->next)
+ a->next = cpy_ast(p, src->next);
+ return a;
+}
+
#include "value.h"
ANN static void free_func(Func a, Gwion gwion) {
-// if(GET_FLAG(a, template) && !is_fptr(a->value_ref->type)) {
- if(GET_FLAG(a, template) && !GET_FLAG(a, builtin) && a->def->d.code) {
- free_tmpl(gwion->mp, a->def->base->tmpl);
- free_func_base(gwion->mp, a->def->base);
- free_loc(gwion->mp, a->def->pos);
- mp_free(gwion->mp, Func_Def, a->def);
- }
+ if(GET_FLAG(a, template) && !GET_FLAG(a, builtin)/* && a->def->d.code*/)
+ free_func_def(gwion->mp, a->def);
if(a->code)
REM_REF(a->code, gwion);
mp_free(gwion->mp, Func, a);
static inline void add_type(const Env env, const Nspc nspc, const Type t) {
map_set(&nspc->info->type->map, (m_uint)insert_symbol(t->name), (m_uint)t);
- map_set(vector_front(&nspc->info->type->ptr), (m_uint)insert_symbol(t->name), (m_uint)t);
+// map_set((Map)vector_front((Vector)&nspc->info->type->ptr), (m_uint)insert_symbol(t->name), (m_uint)t);
}
ANN static Value mk_class(const Env env, const Type base) {
if(stmt->tmpl) {
if(tmpl_base(stmt->tmpl)) {
const Class_Def cdef = new_class_def(env->gwion->mp, stmt->flag, stmt->type_xid,
- NULL, (Class_Body)stmt->l, stmt_self(stmt)->pos);
+ NULL, (Class_Body)stmt->l, loc_cpy(env->gwion->mp, stmt_self(stmt)->pos));
stmt->type->e->def = cdef;
cdef->base.tmpl = stmt->tmpl;
cdef->base.type = stmt->type;
cdef->list = stmt->l;
+ SET_FLAG(cdef, union);
SET_FLAG(stmt->type, pure);
SET_FLAG(stmt, template);
SET_FLAG(stmt->type, template);
ANN m_bool scan1_stmt_fptr(const Env env, const Stmt_Fptr stmt) {
if(!stmt->type)
CHECK_BB(scan0_stmt_fptr(env, stmt))
- if(stmt->base->tmpl)//
- return GW_OK;//
+ if(tmpl_base(stmt->base->tmpl))
+ return GW_OK;
CHECK_OB((stmt->base->ret_type = known_type(env, stmt->base->td)))
return stmt->base->args ? scan1_args(env, stmt->base->args) : GW_OK;
}
}
ANN m_bool scan1_stmt_union(const Env env, const Stmt_Union stmt) {
- if(stmt->tmpl)
+ if(tmpl_base(stmt->tmpl))
return GW_OK;
if(!stmt->value)
CHECK_BB(scan0_stmt_union(env, stmt))
ANN m_bool scan2_stmt_fptr(const Env env, const Stmt_Fptr ptr) {
const Func_Def def = ptr->type->e->d.func->def;
- if(!ptr->base->tmpl) {
+ if(!tmpl_base(ptr->base->tmpl)) {
def->base->ret_type = ptr->base->ret_type;
if(ptr->base->args)
CHECK_BB(scan2_args(env, def))
} else
SET_FLAG(ptr->type, func);
-// nspc_add_value(env->curr, ptr->base->xid, ptr->value);
nspc_add_func(ptr->type->e->owner, ptr->base->xid, ptr->base->func);
return GW_OK;
}
}
ANN m_bool scan2_stmt_union(const Env env, const Stmt_Union stmt) {
- if(stmt->tmpl)
+ if(tmpl_base(stmt->tmpl))
return GW_OK;
const m_uint scope = union_push(env, stmt);
Decl_List l = stmt->l;
#include "vm.h"
#include "parse.h"
#include "gwion.h"
+#include "cpy_ast.h"
ANN static inline Type owner_type(const Env env, const Type t) {
const Nspc nspc = t->nspc ? t->nspc->parent : NULL;
if(env->class_def && name == insert_symbol(env->class_def->name))
return env->class_def->e->def;
const Type t = nspc_lookup_type1(env->curr, name);
- return t ? t->e->def : new_class_def(env->gwion->mp, def->flag, name, def->base.ext, def->body,
- loc_cpy(env->gwion->mp, def->pos));
+ if(t)
+ return t->e->def;
+ const Class_Def c = cpy_class_def(env->gwion->mp, def);
+ c->base.xid = name;
+ return c;
+
}
ANN m_bool template_push_types(const Env env, const Tmpl *tmpl) {
map_set(&t->e->owner->info->type->map, (vtype)a->base.xid, (vtype)a->base.type);
map_set((Map)vector_front((Vector)&t->e->owner->info->type->ptr), (vtype)a->base.xid, (vtype)a->base.type);
} else {
- a->stmt = new_stmt_union(env->gwion->mp, (Decl_List)a->body, t->e->def->pos);
+ a->stmt = new_stmt_union(env->gwion->mp, a->list, t->e->def->pos);
a->stmt->d.stmt_union.type_xid = a->base.xid;
CHECK_BO(scan0_stmt_union(env, &a->stmt->d.stmt_union))
a->base.type = a->stmt->d.stmt_union.type;
a->base.type->e->def = a;
- SET_FLAG(a, union);
+ assert(GET_FLAG(a, union));
}
SET_FLAG(a->base.type, template | ae_flag_ref);
a->base.type->e->owner = t->e->owner;
} else if(type->types) { // TODO: clean me
if(isa(t, t_function) > 0 && t->e->d.func->def->base->tmpl) {
DECL_OO(const m_str, tl_name, = tl2str(env, type->types))
-// err_msg here ?
const Symbol sym = func_symbol(env, t->e->owner->name, t->e->d.func->name, tl_name, 0);
free_mstr(env->gwion->mp, tl_name);
const Type base_type = nspc_lookup_type1(t->e->owner, sym);
ret->name = s_name(sym);
SET_FLAG(ret, func);
nspc_add_type(env->curr, sym, ret);
- const Func_Def def = new_func_def(env->gwion->mp,
- new_func_base(env->gwion->mp, t->e->d.func->def->base->td, sym, t->e->d.func->def->base->args),
- NULL, t->e->d.func->def->flag, loc_cpy(env->gwion->mp, td_pos(type)));
+ const Func_Def def = cpy_func_def(env->gwion->mp, t->e->d.func->def);
const Func func = ret->e->d.func = new_func(env->gwion->mp, s_name(sym), def);
const Value value = new_value(env->gwion->mp, ret, s_name(sym));
func->flag = def->flag;
if(exist)
return exist;
const Type t = type_copy(env->gwion->mp, ret);
-assert(t->size == SZ_INT);
t->name = s_name(sym);
t->e->parent = ret;
SET_FLAG(t, nonnull);
ADD_REF(ret);
- map_set(vector_front(&t->e->owner->info->type->ptr), sym, t);
+ map_set(&t->e->owner->info->type->map, (vtype)sym, (vtype)t);
return t;
}
return ret;
--- /dev/null
+fun void test(...) {
+ vararg.start;
+}
--- /dev/null
+class C {
+int i;
+ typedef void t_fptr0();
+ typedef void t_fptr1(int i);
+ fun void test() { <<< this , " ", __func__ >>>;}
+ fun void test(int i) { <<< __func__, " ", i >>>;}
+#! fun t_fptr call() {
+#! <<< this >>>;
+#! return test $ t_fptr;
+#! }
+#! spork call();
+#! me.yield();
+#!<<< this >>>;
+#! test @=>
+test @=> t_fptr0 ptr0;
+test @=> t_fptr1 ptr1;
+<<<ptr0>>>;
+ spork ptr0();
+#! spork ptr1(2);
+ me.yield();
+}
+<<< C c >>>;
+#!<<< c.test >>>;
+#!<<< c.call() >>>;
--- /dev/null
+class C {
+ typedef void T();
+ fun int f(T t) { <<< t >>>; t();}
+ fun void test() { <<< __func__ >>>; }
+ test => f;
+ f(test);
+}
+C c;
--- /dev/null
+fun float test(float f) {
+ return f;
+}
+
+<<< 1 - 2.0 => test >>>;
+
+
+<<< 1.9 > 1 >>>;
+
+int i;
+
+<<< .1 -=> i >>>;
+
+<<< 1 -.1 >>>;
--- /dev/null
+#! <<< \ { <<< __func__ >>>; }() >>>;
+
+
+ <<< \ { if(maybe)return .2; return 1; }() >>>;
--- /dev/null
+fun void test<~A~>(int i, A a) {
+ A b;
+ <<< __func__, " ", a >>>;
+ <<< i, " ", a >>>;
+ if(i)
+ test<~int~>((i-2, b));
+#! test((i-2.0));
+}
+test<~float~>(2, 2);
--- /dev/null
+fun void test<~A~>(int i) {
+ A a;
+ <<< a >>>;
+ <<< __func__, " ", i, " ", a >>>;
+ if(i)
+#!me.exit();
+ test<~float~>((i-2));
+}
+test<~float~>(2);
--- /dev/null
+fun void test<~A~>(int i) {
+ A a;
+ <<< a >>>;
+#! <<< __func__, " ", i, " ", a >>>;
+ if(i)
+#!me.exit();
+ test<~float~>((i-2));
+}
+test<~Object~>(2);
--- /dev/null
+fun void test<~A~>(A i) {
+ A a;
+ <<< a , " ", __func__>>>;
+ <<< i, " ", a >>>;
+ if(i > 0)
+#!me.exit();
+ test(i-2.0);
+}
+test<~int~>(2);
--- /dev/null
+fun void test<~A~>(A i) {
+ A a;
+ <<< a >>>;
+ <<< i, " ", a, " ", i > 1 >>>;
+ if(i > 1) {
+#! 2 -=> i;
+#! i => A a;
+#! test(a);
+ .1 -=> i;
+ test(i);
+#! test(i);
+ }
+}
+test(2.0);
--- /dev/null
+fun void test<~A~>(int i) {
+ <<< __func__ >>>;
+
+ <<< 1 >>>;
+}
+test<~int~>(1);
--- /dev/null
+class C {
+typedef void t_fptr(int i);
+fun void test(int i) { <<< this , " ", __func__, " ", i >>>;}
+test @=> t_fptr ptr;
+}
+typedef void t_fptr(int i);
+fun void test(int i) { <<< __func__, " ", i >>>;}
+test @=> t_fptr ptr;
+<<< ptr >>>;
+spork ptr(2);
+me.yield();
+<<<C c>>>;
+<<< c.ptr >>>;
+spork c.ptr(3);
+me.yield();
--- /dev/null
+class C {
+ typedef void t_fptr(int i, int);
+ fun void test(int i, int j) { <<< this ,
+ " ", __func__, " ", i, " " , j >>>;}
+ test @=> t_fptr ptr;
+<<< this, ptr >>>;
+#! ptr(2);
+ spork ptr(1,2);
+#! me.yield();
+ second => now;
+}
+<<<C c>>>;