-Subproject commit 5796cf89170539636d4f1405c59bc938e055acb0
+Subproject commit 476773eed83abcd74bf28cccebc59cf9eccca8bb
} Frame;
typedef struct VMValue_ {
- Type t;
+ Type t;
uint16_t offset;
uint16_t start;
uint16_t end;
if (e->exp_type != ae_exp_dot) return true;
const Exp_Dot *member = &e->d.exp_dot;
return GET_FLAG(member->base->type, final) ||
+ !vflag(exp_self(member)->type->info->value, vflag_member) ||
is_class(emit->gwion, member->base->type) ||
member->base->exp_type == ae_exp_cast;
}
-ANN Instr emit_kind(Emitter, const m_uint size, const bool addr, const f_instr func[]);
+ANN Instr emit_kind(Emitter, const m_uint size, const bool addr,
+ const f_instr func[]);
ANN Instr emit_regpushimm(Emitter, const m_uint, const bool);
ANN Instr emit_regpushmem(Emitter, const m_uint, const bool);
ANN Instr emit_regpushbase(Emitter, const m_uint, const bool);
uint16_t depth;
bool in_try;
bool in_loop;
+ bool allow_curry;
};
typedef struct Env_ {
fflag_ftmpl = 1 << 2,
fflag_tmpl = 1 << 3,
fflag_valid = 1 << 4,
- fflag_return = 1 << 5,
- fflag_recurs = 1 << 6,
+ fflag_emit = 1 << 5,
+ fflag_return = 1 << 6,
+ fflag_recurs = 1 << 7,
} __attribute__((packed));
struct Func_ {
#ifndef __NSPC
#define __NSPC
struct NspcInfo_ {
- m_bit * class_data;
- struct Map_ op_map;
- Scope value;
- Scope type;
- Scope func;
- Scope trait;
- size_t offset;
- size_t class_data_size;
+ m_bit * class_data;
+ struct Map_ op_map;
+ Scope value;
+ Scope type;
+ Scope func;
+ Scope trait;
+ struct Vector_ op_map_tmpl;
+ uint16_t offset;
+ uint16_t class_data_size;
};
struct Nspc_ {
ANN void valuefrom(const Env, struct ValueFrom_ *, const loc_t loc);
ANN static inline void defined_here(const Value v) {
- gwerr_secondary(_("defined here"), v->from->filename, v->from->loc);
+ if (v->from->filename) // TODO: check why is that from check
+ gwerr_secondary(_("defined here"), v->from->filename, v->from->loc);
}
#endif
__attribute__((hot)) ANN2(1) void a(const VM_Shred shred NUSED, \
const Instr instr NUSED)
-//enum Kind { KIND_INT, KIND_FLOAT, KIND_OTHER, KIND_ADDR };
+// enum Kind { KIND_INT, KIND_FLOAT, KIND_OTHER, KIND_ADDR };
typedef struct Instr_ *Instr;
typedef void (*f_instr)(const VM_Shred, const Instr);
ANN static inline bool is_hole(const Env env, const Exp exp) {
const Symbol hole = insert_symbol("_");
- if(exp->exp_type == ae_exp_primary) {
- if(exp->d.prim.prim_type == ae_prim_id) {
- if(exp->d.prim.d.var == hole)
- return true;
+ if (exp->exp_type == ae_exp_primary) {
+ if (exp->d.prim.prim_type == ae_prim_id) {
+ if (exp->d.prim.d.var == hole) return true;
}
}
return false;
struct Vector_ instr;
m_uint native_func;
};
- Type ret_type; // could be `struct Vector_ tmpl_types;`
+ Type ret_type; // could be `struct Vector_ tmpl_types;`
union {
void * memoize;
Closure *closure;
};
- m_str name;
- struct Map_ handlers;
+ m_str name;
+ struct Map_ handlers;
struct M_Vector_ live_values;
- uint16_t stack_depth;
- uint16_t ref;
- bool builtin;
- bool callback;
- bool is_memoize;
+ uint16_t stack_depth;
+ uint16_t ref;
+ bool builtin;
+ bool callback;
+ bool is_memoize;
};
typedef struct frame_t {
struct ShredInfo_ *info;
};
REF_FUNC(VM_Code, vmcode)
-ANN2(1,4)
-ANEW VM_Code new_vmcode(MemPool p, const Vector instr, const M_Vector live_values, const m_str name,
- const uint16_t stack_depth, const bool builtin);
+ANN2(1, 4)
+ANEW VM_Code new_vmcode(MemPool p, const Vector instr,
+ const M_Vector live_values, const m_str name,
+ const uint16_t stack_depth, const bool builtin);
ANN ANEW VM_Code vmcode_callback(MemPool p, const VM_Code code);
ANN VM_Shred shreduler_get(const Shreduler s) __attribute__((hot));
: emit_regpushbase(emit, size, exp_getvar(prim_exp(data)));
instr->m_val = v->from->offset;
if (GET_FLAG(v, late) && !exp_getvar(prim_exp(data)) &&
- (isa(v->type, emit->gwion->type[et_object]) > 0 || is_fptr(emit->gwion, v->type))) {
+ (isa(v->type, emit->gwion->type[et_object]) > 0 ||
+ is_fptr(emit->gwion, v->type))) {
const Instr instr = emit_add_instr(emit, GWOP_EXCEPT);
instr->m_val = -SZ_INT;
}
}
ANN static m_bool emit_symbol(const Emitter emit, const Exp_Primary *prim) {
+ if (!prim->value) // assume it's an operator
+ ERR_B(exp_self(prim)->pos, "missing value for operator");
return _emit_symbol(emit, &prim->d.var);
}
// skip when recursing
const Type t = actual_type(emit->gwion, exp_call->func->type);
const Func f = t->info->func;
- if (is_fptr(emit->gwion, t) || f != emit->env->func ||
- f->value_ref->from->owner_class || strstr(emit->code->name, "ork~"))
+ if (is_fptr(emit->gwion, t) || strstr(emit->code->name, "ork~") ||
+ (f != emit->env->func || f->value_ref->from->owner_class))
CHECK_BB(prepare_call(emit, exp_call));
else
CHECK_BB(emit_func_args(emit, exp_call));
ANN static m_uint pop_exp_size(Exp e) {
const bool emit_addr = exp_getvar(e);
m_uint size = 0;
- do { // account for emit_var ?
+ do {
size += (e->exp_type == ae_exp_decl
? get_decl_size(e->d.exp_decl.list, emit_addr)
- : e->type->size);
+ : !emit_addr ? e->type->size
+ : SZ_INT);
} while ((e = e->next));
return size;
}
}
} else if (emit->env->func != f && !f->value_ref->from->owner_class &&
!f->code && !is_fptr(emit->gwion, f->value_ref->type)) {
+ // ensure env?
+ CHECK_BB(emit_func_def(emit, f->def));
if (fbflag(f->def->base, fbflag_op)) {
const Instr back = (Instr)vector_back(&emit->code->instr);
back->m_val = (m_uint)f;
} else {
- // ensure env?
- CHECK_BB(emit_func_def(emit, f->def));
const Instr instr = emit_add_instr(emit, RegSetImm);
instr->m_val = (m_uint)f->code;
instr->m_val2 = -SZ_INT;
}
if (vector_size(&emit->code->instr) && vflag(f->value_ref, vflag_member) &&
is_fptr(emit->gwion, f->value_ref->type)) {
- const Instr back = (Instr)vector_back(&emit->code->instr);
- const bool is_except = back->opcode == eGWOP_EXCEPT;
- const Instr base = !is_except
- ? back
- : (Instr)vector_at(&emit->code->instr,
- vector_size(&emit->code->instr) - 2);
- if(is_except)
- vector_pop(&emit->code->instr);
+ const Instr back = (Instr)vector_back(&emit->code->instr);
+ const bool is_except = back->opcode == eGWOP_EXCEPT;
+ const Instr base =
+ !is_except ? back
+ : (Instr)vector_at(&emit->code->instr,
+ vector_size(&emit->code->instr) - 2);
+ if (is_except) vector_pop(&emit->code->instr);
const m_bit exec = base->opcode;
const m_uint val = base->m_val;
const m_uint val2 = base->m_val2;
const Instr instr = emit_add_instr(emit, (f_instr)(m_uint)exec);
instr->m_val = val;
instr->m_val2 = val2;
- if(is_except) {
- vector_add(&emit->code->instr, (m_uint)back);
- back->m_val = -SZ_INT;
+ if (is_except) {
+ vector_add(&emit->code->instr, (m_uint)back);
+ back->m_val = -SZ_INT;
}
} else if (f != emit->env->func && !f->code &&
!is_fptr(emit->gwion, f->value_ref->type)) {
exp_setvar(exp_if->else_exp, 1);
}
DECL_OB(const Instr, op, = emit_flow(emit, exp_if->cond));
- CHECK_BB(emit_exp_pop_next(emit, exp_if->if_exp ?: exp_if->cond));
+ CHECK_BB(emit_exp_pop_next(emit, e));
const Instr op2 = emit_add_instr(emit, Goto);
op->m_val = emit_code_size(emit);
const m_bool ret = emit_exp_pop_next(emit, exp_if->else_exp);
}
ANN static m_bool emit_exp_td(const Emitter emit, Type_Decl *td) {
- regpushi(emit, (m_uint)_class_base(exp_self(td)->type));
+ const Type base = exp_self(td)->type;
+ const Type t = _class_base(base) ?: base;
+ regpushi(emit, (m_uint)t);
return GW_OK;
}
const Func func = f->base->func;
const Func_Def fdef = func->def;
const Func former = emit->env->func;
- if (func->code || tmpl_base(fdef->base->tmpl)) return GW_OK;
+ if (func->code || tmpl_base(fdef->base->tmpl) || fflag(func, fflag_emit))
+ return GW_OK;
+ set_fflag(func, fflag_emit);
if (vflag(func->value_ref, vflag_builtin) &&
safe_tflag(emit->env->class_def, tflag_tmpl)) {
const Func base =
ANN static m_bool emit_class_def(const Emitter emit, const Class_Def cdef) {
if (tmpl_base(cdef->base.tmpl)) return GW_OK;
- const Type t = cdef->base.type;
+ const Type t = cdef->base.type;
const Class_Def c = t->info->cdef;
if (tflag(t, tflag_emit)) return GW_OK;
set_tflag(t, tflag_emit);
DECL_OO(Type_Decl *, td, = _str2td(gwion, &tdc));
if (*tdc.str) {
free_type_decl(gwion->mp, td);
- GWION_ERR_O(pos, "excedental character '%c'", *tdc.str);
+ GWION_ERR_O(pos, "excedental character '%c' in '%s'", *tdc.str, str);
}
return td;
}
const Class_Def c = t_array->info->cdef;
DECL_ON(const Type, base,
= ts->t != t_array ? ts->t : known_type(env, ts->td->types->td));
+ if (base->size == 0) {
+ gwerr_basic("Can't use type of size 0 as array base", NULL, NULL,
+ "/dev/null", (loc_t) {}, 0);
+ env->context->error = true;
+ return env->gwion->type[et_error];
+ }
if (!strncmp(base->name, "Ref:[", 5)) {
gwerr_basic("Can't use ref types as array base", NULL, NULL, "/dev/null",
(loc_t) {}, 0);
const m_uint scope = env_push(env, base->info->value->from->owner_class,
base->info->value->from->owner);
(void)scan0_class_def(env, cdef);
- const Type t = cdef->base.type;
- (void)traverse_cdef(env, t);
+ const Type t = cdef->base.type;
+ const m_bool ret = traverse_cdef(env, t);
env_pop(env, scope);
env->context = ctx;
+ if (ret == GW_ERROR) return NULL;
if (GET_FLAG(base, abstract))
SET_FLAG(t, abstract);
else
const Type t_curry = gwi_mk_type(gwi, "@Curry", 0, NULL);
GWI_BB(gwi_set_global_type(gwi, t_curry, et_curry))
-
gwidoc(gwi, "type for internal pointer data.");
GWI_BB(gwi_typedef_ini(gwi, "int", "@internal"))
GWI_BB(gwi_typedef_end(gwi, ae_flag_none))
}
ANN static inline Exp cpy_nonext(const Env env, const Exp e) {
- const MemPool mp = env->gwion->mp;
- const Exp next = e->next;
- e->next = NULL;
- const Exp ret = cpy_exp(mp, e);
- e->next = next;
- if(!check_exp(env, ret)) {
+ const MemPool mp = env->gwion->mp;
+ const Exp next = e->next;
+ e->next = NULL;
+ const Exp ret = cpy_exp(mp, e);
+ e->next = next;
+ if (!check_exp(env, ret)) {
free_exp(mp, ret);
return NULL;
}
}
ANN static Exp order_curry(const Env env, Exp fn, Exp arg) {
- const MemPool mp = env->gwion->mp;
- Exp base = NULL;
- Exp next = NULL;
+ const MemPool mp = env->gwion->mp;
+ Exp base = NULL;
+ Exp next = NULL;
do {
const bool hole = is_hole(env, fn);
- const Exp curr = !hole ? fn : arg;
- if(hole) {
- if(!arg) {
- if(base)
- free_exp(mp, base);
+ const Exp curr = !hole ? fn : arg;
+ if (hole) {
+ if (!arg) {
+ if (base) free_exp(mp, base);
ERR_O(fn->pos, "no enough arguments for holes");
}
arg = arg->next;
}
- if(!base)
+ if (!base)
base = next = cpy_nonext(env, curr);
else {
next->next = cpy_nonext(env, curr);
- next = next->next;
+ next = next->next;
}
} while ((fn = fn->next));
assert(base);
- if(arg) {
+ if (arg) {
free_exp(mp, base);
ERR_O(arg->pos, "too many arguments for holes");
}
Exp_Binary *bin = (Exp_Binary *)data;
Exp lhs = bin->lhs;
Exp_Call base = bin->rhs->d.exp_call;
- DECL_OO(const Exp, args, = order_curry(env, base.args, lhs));
- Exp_Call call = {.func = base.func, .args = args};
- Exp e = exp_self(bin);
- e->exp_type = ae_exp_call;
- e->type = NULL;
+ DECL_ON(const Exp, args, = order_curry(env, base.args, lhs));
+ Exp_Call call = {.func = base.func, .args = args};
+ Exp e = exp_self(bin);
+ e->exp_type = ae_exp_call;
+ e->type = NULL;
memcpy(&e->d.exp_call, &call, sizeof(Exp_Call));
const MemPool mp = env->gwion->mp;
free_exp(mp, base.args);
free_exp(mp, lhs);
+ env->scope->allow_curry = true;
return check_exp_call1(env, &e->d.exp_call) ?: env->gwion->type[et_error];
}
fptr_instr(emit, bin->lhs->type->info->func, 2);
(void)emit_add_instr(emit, int_r_assign);
if (!is_fptr(emit->gwion, bin->lhs->type) &&
- vflag(bin->rhs->type->info->func->value_ref, vflag_member)) {
+ vflag(bin->rhs->type->info->func->value_ref, vflag_member)/*&&
+ bin->lhs->exp_type != ae_exp_td*/) {
const Instr pop = emit_add_instr(emit, RegMove);
pop->m_val = -SZ_INT;
const Instr cpy = emit_add_instr(emit, Reg2Reg);
Exp_Binary *bin = (Exp_Binary *)data;
if (bin->rhs->exp_type == ae_exp_decl)
UNSET_FLAG(bin->rhs->d.exp_decl.list->self->value, late);
+ if (bin->lhs->exp_type == ae_exp_td)
+ ERR_N(bin->lhs->pos, "can't use type_decl expression");
+ // UNSET_FLAG(bin->rhs->d.exp_decl.list->self->value, late);
if (bin->rhs->type->info->func->def->base->tmpl &&
bin->rhs->type->info->func->def->base->tmpl->call) {
struct FptrInfo info = {bin->lhs->type->info->func,
exp_setvar(bin->rhs, 1);
return bin->rhs->type;
}
-
+/*
static OP_CHECK(opck_fptr_cast) {
Exp_Cast * cast = (Exp_Cast *)data;
const Type t = exp_self(cast)->type;
CHECK_BN(fptr_do(env, &info));
return t;
}
-
+*/
static void member_fptr(const Emitter emit) {
const Instr instr = emit_add_instr(emit, RegMove);
instr->m_val = -SZ_INT;
static inline int is_member(const Type from) {
return vflag(from->info->func->value_ref, vflag_member);
}
-
+/*
static OP_EMIT(opem_fptr_cast) {
const Exp_Cast *cast = (Exp_Cast *)data;
if (is_member(cast->exp->type)) member_fptr(emit);
fptr_instr(emit, cast->exp->type->info->func, 1);
return GW_OK;
}
-
+*/
static OP_CHECK(opck_fptr_impl) {
struct Implicit *impl = (struct Implicit *)data;
struct FptrInfo info = {impl->e->type->info->func, impl->t->info->func,
GWI_BB(gwi_oper_add(gwi, opck_fptr_at))
GWI_BB(gwi_oper_emi(gwi, opem_func_assign))
GWI_BB(gwi_oper_end(gwi, "@=>", NULL))
- GWI_BB(gwi_oper_add(gwi, opck_fptr_cast))
- GWI_BB(gwi_oper_emi(gwi, opem_fptr_cast))
- GWI_BB(gwi_oper_end(gwi, "$", NULL))
+ // GWI_BB(gwi_oper_add(gwi, opck_fptr_cast))
+ // GWI_BB(gwi_oper_emi(gwi, opem_fptr_cast))
+ // GWI_BB(gwi_oper_end(gwi, "$", NULL))
GWI_BB(gwi_oper_add(gwi, opck_fptr_impl))
GWI_BB(gwi_oper_emi(gwi, opem_fptr_impl))
GWI_BB(gwi_oper_end(gwi, "@implicit", NULL))
static OP_CHECK(opck_struct_scan) {
struct TemplateScan *ts = (struct TemplateScan *)data;
+ CHECK_OO(ts->td);
return opck_object_scan(env, ts);
}
const m_uint size = v->type->size;
const Instr instr = emit_dotmember(emit, size, emit_addr);
instr->m_val = v->from->offset;
- instr->m_val2 = size;
}
ANN static inline void emit_struct_data(const Emitter emit, const Value v,
const Exp_Dot *member = (Exp_Dot *)data;
const Type t_base = actual_type(emit->gwion, member->base->type);
const Value value = find_value(t_base, member->xid);
+ if (is_class(emit->gwion, value->type)) {
+ const Instr instr = emit_add_instr(emit, RegPushImm);
+ instr->m_val = (m_uint)value->type;
+ return GW_OK;
+ }
if (!is_class(emit->gwion, member->base->type) &&
(vflag(value, vflag_member) ||
(isa(exp_self(member)->type, emit->gwion->type[et_function]) > 0 &&
!is_fptr(emit->gwion, exp_self(member)->type)))) {
- if (!tflag(t_base, tflag_struct)) CHECK_BB(emit_exp(emit, member->base));
+ if (!tflag(t_base, tflag_struct) && vflag(value, vflag_member))
+ CHECK_BB(emit_exp(emit, member->base));
}
if (isa(exp_self(member)->type, emit->gwion->type[et_function]) > 0 &&
!is_fptr(emit->gwion, exp_self(member)->type))
static OP_CHECK(opck_##ntype##_##name) { \
/*const*/ Exp_Unary *unary = (Exp_Unary *)data; \
const Type t = env->gwion->type[TYPE]; \
- if (!exp_self(unary)->pos.first.line || !func(unary->exp)) return t; \
CHECK_NN(opck_unary_meta(env, data)); \
+ if (!func(unary->exp)) return t; \
const ctype num = OP unary->exp->d.prim.d.member; \
exp_self(unary)->exp_type = ae_exp_primary; \
exp_self(unary)->d.prim.prim_type = exptype; \
is_prim_float, m_float, ae_prim_float, num, fnum, fnum)
#define BINARY_INT_FLOAT_FOLD2(name, TYPE, OP, pre, post) \
BINARY_FOLD(int_float, name, TYPE, OP, pre, post, is_prim_int, \
- is_prim_float, m_float, ae_prim_float, num, fnum, num)
+ is_prim_float, m_float, ae_prim_num, num, fnum, num)
BINARY_INT_FLOAT_FOLD(add, et_float, +, , )
BINARY_INT_FLOAT_FOLD(sub, et_float, -, , )
}
}
}
- *(m_uint *)RETURN = 0;
+ handle(shred, "InvalidShredRequest");
}
static MFUN(shred_args) {
const m_str str = (m_str)vector_at(&s->info->args, *(m_uint *)MEM(SZ_INT));
*(M_Object *)RETURN = str ? new_string(shred->info->mp, shred, str) : NULL;
} else
- *(m_uint *)RETURN = 0;
+ handle(shred, "InvalidShredArgumentRequest");
}
#ifndef BUILD_ON_WINDOWS
break;
}
if (len - start - end <= 0) {
- *(m_uint *)RETURN = 0;
+ handle(shred, "InvalidStringTrimRequest");
return;
}
char c[len - start - end + 1];
strcpy(str, STRING(o));
m_int i, len_insert = 0, index = *(m_int *)MEM(SZ_INT);
const M_Object arg = *(M_Object *)MEM(SZ_INT * 2);
-
- if (!arg) {
- *(M_Object *)RETURN = NULL;
- return;
- }
- char insert[strlen(STRING(arg)) + 1];
+ char insert[strlen(STRING(arg)) + 1];
strcpy(insert, STRING(arg));
const m_uint len = strlen(str);
len_insert = strlen(insert);
const m_uint len = strlen(str);
len_insert = strlen(insert);
if (index >= (m_int)len || index < 0 || (index + len_insert + 1) <= 0) {
- *(M_Object *)RETURN = NULL;
+ handle(shred, "InvalidStringReplace");
return;
}
char c[index + len_insert + 1];
const m_int _len = *(m_int *)MEM(SZ_INT * 2);
if (!arg || index > (m_int)strlen(STRING(o)) ||
_len > (m_int)strlen(STRING(arg))) {
- *(M_Object *)RETURN = NULL;
+ handle(shred, "InvalidStringReplace");
return;
}
char insert[strlen(STRING(arg)) + 1];
const m_int len = strlen(str);
const m_int size = len - rem + 1;
if (start >= len || size <= 0) {
- *(M_Object *)RETURN = NULL;
+ handle(shred, "InvalidStringErase");
return;
}
char c[size];
const m_int i = *(m_int *)MEM(SZ_INT);
if (!UGEN(o)->multi)
*(M_Object *)RETURN = !i ? o : NULL;
- else if (i < 0 || (m_uint)i >= UGEN(o)->connect.multi->n_chan)
- *(M_Object *)RETURN = NULL;
- else
+ else if (i > 0 || (m_uint)i < UGEN(o)->connect.multi->n_chan)
*(M_Object *)RETURN = UGEN(o)->connect.multi->channel[i];
+ else
+ handle(shred, "InvalidChannelRequest");
}
static MFUN(ugen_get_op) { *(m_uint *)RETURN = UGEN(o)->op + 1; }
#ifdef __AFL_HAVE_MANUAL_CONTROL
+#include "compile.h"
+
static void afl_run(const Gwion gwion) {
gw_seed(gwion->vm->rand, 0);
__AFL_INIT();
}
ANN2(1) static inline bool curried(const Env env, Exp exp) {
- while(exp) {
- if (is_hole(env, exp))
- return true;
+ while (exp) {
+ if (is_hole(env, exp)) return true;
exp = exp->next;
}
return false;
}
ANN static Type check_exp_call(const Env env, Exp_Call *exp) {
- if(curried(env, exp->args))
- return env->gwion->type[et_curry];
+ if (curried(env, exp->args)) return env->gwion->type[et_curry];
if (exp->tmpl) {
DECL_BO(const m_bool, ret, = func_check(env, exp));
if (!ret) return exp_self(exp)->type;
#define check_flow(emit, b) _flow(emit, b, 1)
ANN static Type check_exp_if(const Env env, Exp_If *const exp_if) {
- if(!exp_if->if_exp) {
+ if (!exp_if->if_exp) {
const Exp e = exp_if->if_exp = cpy_exp(env->gwion->mp, exp_if->cond);
scan1_exp(env, e);
scan2_exp(env, e);
DECL_OO(const Type, if_exp, = check_exp(env, exp_if->if_exp));
DECL_OO(const Type, else_exp, = check_exp(env, exp_if->else_exp));
- const uint meta = exp_getmeta(exp_if->if_exp) || exp_getmeta(exp_if->else_exp);
+ const uint meta =
+ exp_getmeta(exp_if->if_exp) || exp_getmeta(exp_if->else_exp);
exp_setmeta(exp_self(exp_if), meta);
const Type ret = find_common_anc(if_exp, else_exp);
if (!ret)
ANN static Type check_exp_td(const Env env, Type_Decl **td) {
DECL_OO(const Type, t, = known_type(env, *td));
- if(isa(t, env->gwion->type[et_function]) > 0 && !is_fptr(env->gwion, t))
+ if (isa(t, env->gwion->type[et_function]) > 0 && !is_fptr(env->gwion, t))
return type_class(env->gwion, t);
return t;
}
ID_List list = edef->list;
do {
CHECK_BB(already_defined(env, list->xid, edef->pos));
- if(nspc_lookup_value1(edef->t->info->value->from->owner, list->xid))
+ if (nspc_lookup_value1(edef->t->info->value->from->owner, list->xid))
ERR_B(edef->pos, "'%s' already defined", s_name(list->xid));
const Value v = new_value(env->gwion->mp, edef->t, s_name(list->xid));
valuefrom(env, v->from, edef->pos);
ANN m_bool scan1_class_def(const Env env, const Class_Def cdef) {
if (tmpl_base(cdef->base.tmpl)) return GW_OK;
- const Type t = cdef->base.type;
+ const Type t = cdef->base.type;
const Class_Def c = t->info->cdef;
if (tflag(t, tflag_scan1)) return GW_OK;
set_tflag(t, tflag_scan1);
value_addref(v);
nspc_add_value_front(env->curr, f->def->base->xid, v);
- const Type newt = type_copy(env->gwion->mp, t);
- t->info->parent = newt;
- newt->name = s_name(f->def->base->xid);
- newt->info->func = f;
+ const Type newt = type_copy(env->gwion->mp, t);
+ t->info->parent = newt;
+ newt->name = s_name(f->def->base->xid);
+ newt->info->func = f;
nspc_add_type_front(env->curr, f->def->base->xid, newt);
newt->info->value = v;
}
ANN m_bool scan2_class_def(const Env env, const Class_Def cdef) {
if (tmpl_base(cdef->base.tmpl)) return GW_OK;
- const Type t = cdef->base.type;
+ const Type t = cdef->base.type;
const Class_Def c = t->info->cdef;
if (tflag(t, tflag_scan2)) return GW_OK;
if (t->info->value->from->owner_class)
#include "object.h"
#include "import.h"
-ANN static m_bool push_types(const Env env, const Tmpl *tmpl) {
+ANN static m_bool _push_types(const Env env, const Nspc nspc,
+ const Tmpl *tmpl) {
Specialized_List list = tmpl->list;
Type_List call = tmpl->call;
do {
if (!call) break;
const Type t = known_type(env, call->td);
- if (!t) return 1;
- nspc_add_type(env->curr, list->xid, t);
+ if (!t) return GW_OK;
+ nspc_add_type(nspc, list->xid, t);
call = call->next;
} while ((list = list->next));
- return !call;
+ return !call ? GW_OK : GW_ERROR;
+}
+
+ANN static m_bool push_types(const Env env, const Nspc nspc, const Tmpl *tmpl) {
+ if (nspc->parent) env->curr = env->curr->parent;
+ const Type t = env->class_def;
+ if (t) env->class_def = t->info->value->from->owner_class;
+ const m_bool ret = _push_types(env, nspc, tmpl);
+ if (nspc->parent) env->curr = nspc;
+ env->class_def = t;
+ return ret;
}
ANN static m_bool _template_push(const Env env, const Type t) {
if (t->info->value->from->owner_class)
CHECK_BB(template_push(env, t->info->value->from->owner_class));
if (tflag(t, tflag_tmpl))
- return push_types(env, t->info->cdef->base.tmpl); // incorrect
+ return push_types(env, t->nspc, t->info->cdef->base.tmpl); // incorrect
return GW_OK;
}
ANN m_bool template_push_types(const Env env, const Tmpl *tmpl) {
nspc_push_type(env->gwion->mp, env->curr);
- if (push_types(env, tmpl)) return GW_OK;
+ if (push_types(env, env->curr, tmpl) > 0) return GW_OK;
POP_RET(GW_ERROR);
}