CFLAGS += -DGWION_BUILTIN
-all: options-show ${GWLIBS} src/main.o
+all: options-show ${PRG}
+
+${PRG}: ${GWLIBS} src/main.o
@$(info link ${PRG})
@${CC} src/main.o -o ${PRG} ${LDFLAGS} ${LIBS}
@rm ${DESTDIR}/${PREFIX}/include/gwion/*.h
@rmdir --ignore-fail-on-non-empty ${DESTDIR}/${PREFIX}/include/gwion
-test:
+test: ${PRG}
@bash scripts/test.sh ${test_dir}
scan:
-Subproject commit c02c76b8d22fdf40fd407861e625b6e741f64ffc
+Subproject commit 1f60e2df75ddd542a0cdf1853c37d5b685bf9641
--- /dev/null
+#ifndef __DEFAULT_ARGS
+#define __DEFAULT_ARGS
+ANN void default_args(const Env, const Section *, Ast *acc);
+#endif
fflag_valid = 1 << 4,
fflag_emit = 1 << 5,
fflag_return = 1 << 6,
- fflag_recurs = 1 << 7,
} __attribute__((packed));
struct Func_ {
ANN static inline void config_end(const Vector config) {
for (m_uint i = 0; i < vector_size(config); ++i) {
const Vector v = (Vector)vector_at(config, i);
- for (m_uint i = 1; i < vector_size(v); ++i) xfree((m_str)vector_at(v, i));
+ for (m_uint i = 0; i < vector_size(v); ++i) xfree((m_str)vector_at(v, i));
vector_release(v);
xfree(v);
}
else if (tflag(a, tflag_cdef))
class_def_cleaner(gwion, a->info->cdef);
}
- if (tflag(a, tflag_cdef) && a->info->parent)
- type_remref(a->info->parent, gwion);
+// if (tflag(a, tflag_cdef) && a->info->parent)
+// type_remref(a->info->parent, gwion);
if (a->effects.ptr) vector_release(&a->effects);
if (a->nspc) nspc_remref(a->nspc, gwion);
if (a->info->tuple) free_tupleform(a->info->tuple, gwion);
return NULL;
}
+ANN static Type class_type(const Env env, const Exp_Dot *member, const Type base) {
+ const Type parent = actual_type(env->gwion, base);
+ if(!tflag(parent, tflag_tmpl)) return parent;
+ Type_Decl td = {
+ .xid=insert_symbol(env->gwion->st, parent->name),
+ .types = member->is_call->tmpl ? member->is_call->tmpl->call : NULL
+ };
+ return known_type(env, &td);
+}
+
OP_CHECK(opck_object_dot) {
Exp_Dot *const member = (Exp_Dot *)data;
const m_str str = s_name(member->xid);
if (is_func(env->gwion, v->type) && (!v->from->owner_class || isa(the_base, v->from->owner_class) > 0))
return v->type;
if (is_class(env->gwion, v->type)) {
- const Type parent = actual_type(env->gwion, v->type);
- if (isa(the_base, parent) > 0 && parent->nspc) { // beware templates
+ DECL_OO(const Type, parent, = class_type(env, member, v->type));
+ if (isa(the_base, parent) > 0 && parent->nspc) {
const Symbol sym = insert_symbol(env->gwion->st, "new");
const Value ret = nspc_lookup_value1(parent->nspc, sym);
member->xid = sym;
-// member->base->type = parent;
if(ret)
return ret->type;
}
ANN m_bool func_check(const Env env, Exp_Call *const exp) {
if(exp->func->exp_type == ae_exp_dot)
- exp->func->d.exp_dot.is_call = true;
+ exp->func->d.exp_dot.is_call = exp;
CHECK_OB(check_exp(env, exp->func));
if (exp->func->exp_type == ae_exp_decl)
ERR_B(exp->func->pos, _("Can't call late function pointer at declaration "
}
exp->func->type = func->value_ref->type;
call_add_effect(env, func, exp->func->pos);
- if (func == env->func) set_fflag(env->func, fflag_recurs);
+// if (func == env->func) set_fflag(env->func, fflag_recurs);
return func->def->base->ret_type != env->gwion->type[et_auto] ?
func->def->base->ret_type : exp->func->d.exp_dot.base->type;
}
return false;
}
+ANN static Type check_exp_call_tmpl(const Env env, Exp_Call *exp, const Type t) {
+ if(isa(t, env->gwion->type[et_lambda]) > 0)
+ if (!t->info->func)
+ ERR_O(exp->func->pos, _("invalid lambda use."))
+ if (exp->args) CHECK_OO(check_exp(env, exp->args));
+ if (!t->info->func->def->base->tmpl)
+ ERR_O(exp_self(exp)->pos, _("template call of non-template function."))
+ if (t->info->func->def->base->tmpl->call) {
+ if (env->func == t->info->func) {
+ exp->func->type = env->func->value_ref->type;
+ return env->func->def->base->ret_type;
+ } else
+ CHECK_BO(predefined_call(env, t, exp_self(exp)->pos));
+ }
+ const Value v = type_value(env->gwion, t);
+ DECL_OO(const Func, f, = find_template_match(env, v, exp));
+ exp->func->type = f->value_ref->type;
+ return f->def->base->ret_type;
+}
+
ANN static Type check_exp_call(const Env env, Exp_Call *exp) {
if (exp->apms && curried(env, exp->args))
return env->gwion->type[et_curry];
if (!ret) return exp_self(exp)->type;
const Type t = actual_type(env->gwion, exp->func->type);
if (!is_func(env->gwion, t)) return check_exp_call1(env, exp);
- if(isa(t, env->gwion->type[et_lambda]) > 0)
- if (!t->info->func)
- ERR_O(exp->func->pos, _("invalid lambda use."))
- if (exp->args) CHECK_OO(check_exp(env, exp->args));
- if (!t->info->func->def->base->tmpl)
- ERR_O(exp_self(exp)->pos, _("template call of non-template function."))
- if (t->info->func->def->base->tmpl->call) {
- if (env->func == t->info->func) {
- exp->func->type = env->func->value_ref->type;
- return env->func->def->base->ret_type;
- } else
- CHECK_BO(predefined_call(env, t, exp_self(exp)->pos));
- }
- const Value v = type_value(env->gwion, t);
- DECL_OO(const Func, f, = find_template_match(env, v, exp));
- exp->func->type = f->value_ref->type;
- return f->def->base->ret_type;
+ if(strcmp("new", s_name(t->info->func->def->base->xid)))
+ return check_exp_call_tmpl(env, exp, t);
}
return check_exp_call1(env, exp);
}
ANN static m_bool _check_trait_def(const Env env, const Trait_Def pdef) {
const Trait trait = nspc_lookup_trait1(env->curr, pdef->xid);
Ast ast = pdef->body;
-// while (ast) {
-// Section *section = ast->section;
for(m_uint i = 0; i < ast->len; i++) {
Section * section = mp_vector_at(ast, Section, i);
if (section->section_type == ae_section_stmt) {
vector_add(&trait->requested_values, (m_uint)value);
}
}
-// list = list->next;
}
}
-// ast = ast->next;
}
return GW_OK;
}
--- /dev/null
+#include "gwion_util.h"
+#include "gwion_ast.h"
+#include "gwion_env.h"
+#include "vm.h"
+#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++) {
+ 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;
+ }
+ // now add default args
+ for(uint32_t i = args->len; i < max; i++) {
+ 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;
+ }
+ return base_exp;
+}
+
+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, sizeof(struct Stmt_), 1);
+ mp_vector_set(slist, struct Stmt_, 0,
+ ((struct Stmt_) {
+ .stmt_type = ae_stmt_return, .d = { .stmt_exp = { .val = ecall }},
+ .pos = base->pos
+ }));
+ return slist;
+}
+
+ANN static Stmt_List new_code(const Env env, Func_Base *base, const Arg_List args, const uint32_t len) {
+ 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, sizeof(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;
+}
+
+ANN void default_args(const Env env, const Section *s, Ast *acc) {
+ const MemPool p = env->gwion->mp;
+ const Func_Def base_fdef = s->d.func_def;
+ Arg_List args = base_fdef->base->args;
+ uint32_t len = args->len;
+ while(args->len--) {
+ 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 slist = strcmp("new", s_name(base->xid))
+ ? 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, body);
+ 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;
+}
CHECK_BO(scan0_defined(env, cdef->base.xid, cdef->pos));
const Type parent = cdef_parent(env, cdef);
if (parent == (Type)GW_ERROR) return NULL;
- if(parent) type_addref(parent);
+ //if(parent) type_addref(parent);
if (cdef->traits) CHECK_BO(find_traits(env, cdef->traits, cdef->pos));
const Type t = scan0_type(env, s_name(cdef->base.xid), parent);
if (cflag(cdef, cflag_struct)) {
return GW_OK;
}
-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++) {
- 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;
- }
- // now add default args
- for(uint32_t i = args->len; i < max; i++) {
- 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;
- }
- return base_exp;
-}
-
-ANN2(1) static void scan0_func_def_default(const MemPool p, const Section *s,
- Ast *acc) {
- const Func_Def base_fdef = s->d.func_def;
- Arg_List args = base_fdef->base->args;
- const uint32_t len = args->len;
- while(args->len--) {
- Arg *arg = mp_vector_at(args, Arg, args->len);
- if(!arg->exp) break;
- Func_Base *base = new_func_base(
- p, base_fdef->base->td ? cpy_type_decl(p, base_fdef->base->td) : NULL, base_fdef->base->xid,
- cpy_arg_list(p, args),
- base_fdef->base->flag, base_fdef->base->pos);
- 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, sizeof(struct Stmt_), 1);
- mp_vector_set(slist, struct Stmt_, 0,
- ((struct Stmt_) {
- .stmt_type = ae_stmt_return, .d = { .stmt_exp = { .val = ecall }},
- .pos = base_fdef->base->pos
- }));
- const Stmt body = new_stmt_code(p, slist, base->pos);
- const Func_Def fdef = new_func_def(p, base, body);
- Section section = MK_SECTION(func, func_def, fdef);
- mp_vector_add(p, acc, Section, section);
- }
- args->len = len;
-}
-
#define scan0_func_def dummy_func
ANN static m_bool scan0_extend_def(const Env env, const Extend_Def xdef) {
set_tflag(cdef->base.type, tflag_scan0);
(void)mk_class(env, cdef->base.type, cdef->pos);
add_type(env, cdef->base.type->info->value->from->owner, cdef->base.type);
- const m_uint scope = env_push(env, cdef->base.type->info->value->from->owner_class, cdef->base.type->info->value->from->owner);
+// const m_uint scope = env_push(env, cdef->base.type->info->value->from->owner_class, cdef->base.type->info->value->from->owner);
const m_bool ret = cdef->body ? env_body(env, cdef, scan0_section) : GW_OK;
- env_pop(env, scope);
+// env_pop(env, scope);
return ret;
}
ANN m_bool scan0_ast(const Env env, Ast *ast) {
Ast a = *ast;
- Ast acc = new_mp_vector(env->gwion->mp, sizeof(Section), 0);
for(m_uint i = 0; i < a->len; i++) {
Section * section = mp_vector_at(a, Section, i);
CHECK_BB(scan0_section(env, section));
-
- if (section->section_type != ae_section_func ||
- !fbflag(section->d.func_def->base, fbflag_default))
- continue;
- scan0_func_def_default(env->gwion->mp, section, &acc);
-
}
-
- for(m_uint i = 0; i < acc->len; i++) {
- Section * section = mp_vector_at(acc, Section, i);
- mp_vector_add(env->gwion->mp, ast, Section, *section);
- }
- free_mp_vector(env->gwion->mp, sizeof(Section), acc);
-
return GW_OK;
}
#include "object.h"
#include "instr.h"
#include "import.h"
+#include "default_args.h"
ANN static m_bool scan2_stmt(const Env, const Stmt);
ANN static m_bool scan2_stmt_list(const Env, Stmt_List);
const Exp_Binary *bin) {
CHECK_BB(scan2_exp(env, bin->lhs));
CHECK_BB(scan2_exp(env, bin->rhs));
-if(bin->rhs->exp_type == ae_exp_call)bin->rhs->d.exp_call.apms = true;
+ if(bin->rhs->exp_type == ae_exp_call)bin->rhs->d.exp_call.apms = true;
CHECK_BB(multi_decl(env, bin->lhs, bin->op));
return multi_decl(env, bin->rhs, bin->op);
}
ANN2(1, 2)
m_bool scan2_fdef_std(const Env env, const Func_Def f, const Value overload) {
- const m_str name = func_name(env, f, overload ?: NULL);
+ const m_str name = func_name(env, f, overload);
if (!name) return GW_ERROR;
const Func base = f->base->func;
if (!base)
CHECK_OB(func_create(env, f, overload, name));
- else
- f->base->func = base;
if (f->base->args) CHECK_BB(scan2_args(f));
if (!f->builtin && f->d.code) CHECK_BB(scan2_func_def_code(env, f));
if (!base) {
if (tflag(t, tflag_scan2)) return GW_OK;
set_tflag(t, tflag_scan2);
if (c->base.ext) CHECK_BB(cdef_parent(env, c));
- if (c->body) CHECK_BB(env_body(env, c, scan2_section));
+ if (c->body) {
+ const m_uint scope = env_push_type(env, t);
+ const Tmpl *tmpl = cdef->base.tmpl;
+ if(tmpl && tmpl->call && tmpl->call != (Type_List)1 && tmpl->list)
+ template_push_types(env, tmpl);
+ const m_bool ret = scan2_ast(env, &c->body);
+ if(tmpl && tmpl->call && tmpl->call != (Type_List)1 && tmpl->list)
+ nspc_pop_type(env->gwion->mp, env->curr);
+ env_pop(env, scope);
+ return ret;
+ }
return GW_OK;
}
ANN m_bool scan2_ast(const Env env, Ast *ast) {
Ast a = *ast;
+ Ast acc = new_mp_vector(env->gwion->mp, sizeof(Section), 0);
+ m_bool ret = GW_OK;
for(m_uint i = 0; i < a->len; i++) {
Section *section = mp_vector_at(a, Section, i);
- CHECK_BB(scan2_section(env, section));
+ if((ret = scan2_section(env, section)) < 0) break;
+ if (section->section_type == ae_section_func &&
+ fbflag(section->d.func_def->base, fbflag_default)) {
+ mp_vector_add(env->gwion->mp, &acc, Section, *section);
+ }
}
- return GW_OK;
+
+ for(uint32_t i = 0; i < acc->len; i++) {
+ Section * section = mp_vector_at(acc, Section, i);
+ default_args(env, section, ast);
+ }
+ free_mp_vector(env->gwion->mp, sizeof(Section), acc);
+ return ret;
}