extern Type t_void, t_int, t_bool, t_float, t_dur, t_time, t_now, t_complex, t_polar, t_vec3, t_vec4,
t_null, t_object, t_shred, t_fork, t_event, t_ugen, t_string, t_ptr, t_array, t_gack,
- t_function, t_fptr, t_vararg, t_lambda, t_class, t_union, t_undefined, t_auto, t_tuple;
+ t_function, t_fptr, t_varloop, t_vararg, t_lambda, t_class, t_union, t_undefined, t_auto, t_tuple;
ANN2(1,3) ANEW Type new_type(MemPool, const m_uint xid, const m_str name, const Type);
ANEW ANN Type type_copy(MemPool, const Type type);
}
ANN static inline void emit_notpure(const Emitter emit) {
- ++VPTR(&emit->pure, VLEN(&emit->pure));
+ ++VPTR(&emit->pure, VLEN(&emit->pure) - 1);
}
ANN static Array_Sub instantiate_typedef(MemPool p, const m_uint depth) {
ANN static m_bool prim_gack(const Emitter emit, const Exp_Primary* primary) {
const Exp exp = primary->d.exp;
+ CHECK_BB(emit_exp(emit, exp, 0))
const Vector v = new_vector(emit->gwion->mp);
m_uint offset = 0;
Exp e = exp;
vector_add(v, (vtype)e->type);
offset += e->type->size;
} while((e = e->next));
- if(emit_exp(emit, exp, 0) < 0) {
- free_vector(emit->gwion->mp, v);
- ERR_B(exp->pos, _(" ... in 'gack' expression."))
- }
const Instr instr = emit_add_instr(emit, Gack);
instr->m_val = offset;
instr->m_val2 = (m_uint)v;
back->opcode = ePushStaticCode;
back->m_val = 0;
}
- }else if(emit->env->func != f && !f->value_ref->owner_class && !f->code && !is_fptr(f->value_ref->type)) {
- const Instr back = emit_add_instr(emit, PushStaticCode);
+ } else if(emit->env->func != f && !f->value_ref->owner_class && !f->code && !is_fptr(f->value_ref->type)) {
+ const Instr back = !GET_FLAG(f->def, op) ? emit_add_instr(emit, PushStaticCode) : (Instr)vector_back(&emit->code->instr);
back->m_val = (m_uint)f;
}
} else if((f->value_ref->owner_class && is_special(f->value_ref->owner_class) > 0) ||
!f->value_ref->owner_class || (GET_FLAG(f, template) &&
isa(f->value_ref->type, t_fptr) < 0))
push_func_code(emit, f);
- else if(vector_size(&emit->code->instr)){
+ else if(vector_size(&emit->code->instr)) {
const Instr back = (Instr)vector_back(&emit->code->instr);
if((f_instr)(m_uint)back->opcode == DotFunc || (f_instr)(m_uint)back->opcode == DotStaticFunc)
back->m_val = f->vt_index;
gw_out("%s", f ? f->name : "(nil)");
return;
}
- const VM_Code code = isa(type, t_fptr) > 0 ?
- *(VM_Code*)stack : type->e->d.func->code;
- gw_out("%s %s %p", type->name, (void*)code ? code->name : NULL, code);
+ if(type->e->d.func) {
+ const VM_Code code = isa(type, t_fptr) > 0 ?
+ *(VM_Code*)stack : type->e->d.func->code;
+ gw_out("%s %s %p", type->name, (void*)code ? code->name : NULL, code);
+ } else // uncalled lambda
+ gw_out("%p", NULL);
}
ANN static void print_prim(const Type type, const m_bit* stack) {
struct dottmpl_ *dt = (struct dottmpl_*)instr->m_val;
const m_str name = dt->name;
const M_Object o = *(M_Object*)REG(-SZ_INT);
- Type t = o->type_ref;
+ Type t = !GET_FLAG(o->type_ref, nonnull) ? o->type_ref : o->type_ref->e->parent;
do {
const Emitter emit = shred->info->vm->gwion->emit;
emit->env->name = "runtime";
strcpy(str + instr->m_val2, t->name);
const Func f = nspc_lookup_func0(t->nspc, insert_symbol(emit->env->gwion->st, str));
if(f) {
+ if(!f->code)
+ break;
*(VM_Code*)shred->reg = f->code;
shred->reg += SZ_INT;
return;
if(GET_FLAG(r, nonnull)) {
if(isa(l, t_null) > 0)
ERR_N(pos, _("can't %s '%s' to '%s'"), action, l->name, r->name);
+ if(isa(l, r) < 0)
+ ERR_N(pos, _("can't %s '%s' to '%s'"), action, l->name, r->name);
return r->e->parent;
}
if(nonnull_check(l, r))
num_digit((m_uint)creal(lhs)) + num_digit((m_uint)cimag(lhs) / M_PI) + 16,
"#(%.4f, %.4f)", creal(lhs), cimag(lhs)/M_PI)
describe_string_assign(Vec3_, m_vec3, SZ_VEC3,,
- num_digit((m_uint)lhs.x) + num_digit((m_uint)lhs.y) + num_digit((m_uint)lhs.z) + 23,
+ num_digit((m_uint)lhs.x) + num_digit((m_uint)lhs.y) + num_digit((m_uint)lhs.z) + 25,
"#(%.4f, %.4f, %.4f)", lhs.x, lhs.y, lhs.z)
describe_string_assign(Vec4_, m_vec4, SZ_VEC4,,
- num_digit((m_uint)lhs.x) + num_digit((m_uint)lhs.y) + num_digit((m_uint)lhs.z) + num_digit((m_uint)lhs.w) + 30,
+ num_digit((m_uint)lhs.x) + num_digit((m_uint)lhs.y) + num_digit((m_uint)lhs.z) + num_digit((m_uint)lhs.w) + 40,
"#(%.4f, %.4f, %.4f, %.4f)", lhs.x, lhs.y, lhs.z, lhs.w)
describe_string_assign(Object_, M_Object, SZ_INT, release(lhs, shred),
16,
"#(%.4f, %.4f)%s", creal(lhs), cimag(lhs), rhs ? STRING(rhs) : "")
describe_string(Polar, m_complex, SZ_COMPLEX,
num_digit((m_uint)creal(lhs)) + num_digit((m_uint)cimag(lhs) / M_PI) + (rhs ? strlen(STRING(rhs)) : 0) + 12,,
- "%%(%.4f, %4f*pi)%s", creal(lhs), cimag(lhs) / M_PI, rhs ? STRING(rhs) : "")
+ "%%(%.4f, %.4f*pi)%s", creal(lhs), cimag(lhs) / M_PI, rhs ? STRING(rhs) : "")
describe_string(Vec3, m_vec3, SZ_VEC3,
(rhs ? strlen(STRING(rhs)) : 0) + 23 + num_digit((m_uint)lhs.x) +
num_digit((m_uint)lhs.y) + num_digit((m_uint)lhs.z),,
"@(%.4f, %.4f, %.4f)%s", lhs.x, lhs.y, lhs.z, rhs ? STRING(rhs) : "")
describe_string(Vec4, m_vec4, SZ_VEC4,
- (rhs ? strlen(STRING(rhs)) : 0) + 28 + num_digit((m_uint)lhs.x) +
+ (rhs ? strlen(STRING(rhs)) : 0) + 30 + num_digit((m_uint)lhs.x) +
num_digit((m_uint)lhs.y) + num_digit((m_uint)lhs.z) + num_digit((m_uint)lhs.w),,
- "@(%4f, %4f, %4f, %4f)%s", lhs.x, lhs.y, lhs.z, lhs.w, rhs ? STRING(rhs) : "")
+ "@(%.4f, %.4f, %.4f, %.4f)%s", lhs.x, lhs.y, lhs.z, lhs.w, rhs ? STRING(rhs) : "")
describe_string(Object, M_Object, SZ_INT,
16 + (rhs ? strlen(STRING(rhs)) : 0), release(lhs, shred),
"%p%s", (void*)lhs, rhs ? STRING(rhs) : "")
INSTR(VarargIni) {
struct Vararg_* arg = mp_calloc(shred->info->mp, Vararg);
- POP_REG(shred, instr->m_val - SZ_INT)
+ POP_REG(shred, instr->m_val - SZ_INT)
arg->d = (m_bit*)xmalloc(round2szint(instr->m_val));
for(m_uint i = 0; i < instr->m_val; i += SZ_INT)
*(m_uint*)(arg->d + i) = *(m_uint*)(shred->reg - SZ_INT + i);
GWION_IMPORT(vararg) {
GWI_OB((t_vararg = gwi_mk_type(gwi, "@Vararg", SZ_INT, t_object)))
const Type t_varobj = gwi_mk_type(gwi, "VarObject", SZ_INT, t_vararg);
- GWI_OB(t_varobj)
SET_FLAG(t_varobj, abstract);
- const Type t_varloop = gwi_mk_type(gwi, "@VarLoop", SZ_INT, NULL);
- GWI_OB(t_varloop)
+ t_varloop = gwi_mk_type(gwi, "@VarLoop", SZ_INT, NULL);
GWI_BB(gwi_add_type(gwi, t_varobj))
GWI_BB(gwi_add_type(gwi, t_varloop))
GWI_BB(gwi_class_ini(gwi, t_vararg, NULL, NULL))
if(GET_FLAG(t, empty))
return GW_OK;
if(GET_FLAG(t, typedef) && t->e->def)
- if(t->e->def->base.ext && t->e->def->base.ext->array && !t->e->def->base.ext->array->exp)
- return GW_OK;
+ if(t->e->def->base.ext && t->e->def->base.ext->array) {
+ if(!t->e->def->base.ext->array->exp)
+ return GW_OK;
+ else {
+ const Type type = t->e->parent->e->d.base_type;
+ if(GET_FLAG(type, empty))
+ return GW_OK;
+ }
+ }
} while((t = t->e->parent));
return 0;
}
Type t_void, t_int, t_bool, t_float, t_dur, t_time, t_now, t_complex, t_polar, t_vec3, t_vec4,
t_null, t_object, t_shred, t_fork, t_event, t_ugen, t_string, t_ptr, t_array, t_gack,
- t_function, t_fptr, t_vararg, t_lambda, t_class, t_union, t_undefined, t_auto, t_tuple;
+ t_function, t_fptr, t_varloop, t_vararg, t_lambda, t_class, t_union, t_undefined, t_auto, t_tuple;
return GW_OK;
ERR_B(var->pos, _("can't use non public typedef at global scope."))
}
- if(isa(type, env->class_def) < 0 && !GET_FLAG(func, global))
+ if(type && isa(type, env->class_def) < 0 && !GET_FLAG(func, global))
ERR_B(var->pos, _("can't use non global fptr of other class."))
if(GET_FLAG(func, member) && GET_FLAG(v, static))
ERR_B(var->pos, _("can't use static variables for member function."))
if(implicit) {
const struct Implicit imp = { e, t, e->pos };
struct Op_Import opi = { .op=insert_symbol("@implicit"), .lhs=e->type, .rhs=t, .data=(m_uint)&imp, .pos=e->pos };
- return op_check(env, &opi) ? 1 : -1;
+ return op_check(env, &opi) ? GW_OK : GW_ERROR;
}
}
return match ? 1 : -1;
if(env->func == exists->d.func_ref) {
if(check_call(env, exp) < 0)
continue;
+ CHECK_OO(find_func_match(env, env->func, exp->args))
m_func = env->func;
break;
}
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;
if(tm->call) {
- const Func func = value->d.func_ref ?: predefined_func(env, value, exp, tm);
+ DECL_OO(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))
return check_lambda_call(env, exp);
if(GET_FLAG(exp->func->type->e->d.func, ref)) {
const Value value = exp->func->type->e->d.func->value_ref;
- CHECK_BO(traverse_class_def(env, value->owner_class->e->def))
+ if(value->owner_class)
+ CHECK_BO(traverse_class_def(env, value->owner_class->e->def))
}
if(exp->args)
CHECK_OO(check_exp(env, exp->args))
ANN static Type check_exp_call(const Env env, Exp_Call* exp) {
if(exp->tmpl) {
CHECK_OO(check_exp(env, exp->func))
- const Type t = actual_type(exp->func->type);
+ const Type t = actual_type(!GET_FLAG(exp->func->type, nonnull) ?
+ exp->func->type : exp->func->type->e->parent);
const Value v = nspc_lookup_value1(t->e->owner, insert_symbol(t->name));
- assert(v);
if(!GET_FLAG(v, func) && !GET_FLAG(exp->func->type, func) )
ERR_O(exp_self(exp)->pos, _("template call of non-function value."))
if(!v->d.func_ref || !v->d.func_ref->def->base->tmpl)
};
ANN static inline Type check_exp(const Env env, const Exp exp) {
- Exp curr = exp;
+ Exp curr = exp, next = NULL, prev = NULL;
do {
+ next = curr->next;
CHECK_OO((curr->type = exp_func[curr->exp_type](env, &curr->d)))
+ if(isa(curr->type, t_varloop) > 0 && (prev || next))
+ ERR_O(exp->pos, _("Varloop must be the only expression"))
if(env->func && isa(curr->type, t_lambda) < 0 && isa(curr->type, t_function) > 0 &&
!GET_FLAG(curr->type->e->d.func, pure))
UNSET_FLAG(env->func, pure);
- } while((curr = curr->next));
+ } while((prev = curr) && (curr = next));
return exp->type;
}
ANN m_bool scan0_fptr_def(const Env env, const Fptr_Def fptr) {
CHECK_BB(env_access(env, fptr->base->td->flag, td_pos(fptr->base->td)))
- CHECK_OO(known_type(env, fptr->base->td))
+ CHECK_OB(known_type(env, fptr->base->td))
CHECK_BB(scan0_defined(env, fptr->base->xid, td_pos(fptr->base->td)));
const m_str name = s_name(fptr->base->xid);
const Type t = new_type(env->gwion->mp, t_fptr->xid, name, t_fptr);
ANN m_bool scan2_fptr_def(const Env env, const Fptr_Def fptr) {
- const Func_Def def = fptr->type->e->d.func->def;
if(!tmpl_base(fptr->base->tmpl)) {
+ const Func_Def def = fptr->type->e->d.func->def;
def->base->ret_type = fptr->base->ret_type;
if(fptr->base->args)
CHECK_BB(scan2_args(env, def))
- } else
+ } else {
+ CHECK_OB(fptr->type) // should happen before
SET_FLAG(fptr->type, func);
+ }
return GW_OK;
}
DECL_OO(const Type, t, = scan_type(env, base, td))
const Type ret = !td->array ? t : array_type(env, t, td->array->depth);
if(GET_FLAG(td, nonnull)) {
+ if(isa(ret, t_void) > 0)
+ ERR_O(td_pos(td), _("void types can't be nonnull."))
if(isa(ret, t_object) < 0 && isa(ret, t_function) < 0)
return ret;
char c[strlen(t->name) + 9];
&&newobj, &&addref, &&objassign, &&assign, &&remref,
&&except, &&allocmemberaddr, &&dotmember, &&dotfloat, &&dotother, &&dotaddr,
&&staticint, &&staticfloat, &&staticother,
- &&dotfunc, &&dotstaticfunc, &&eoc, &&pushstr,
+ &&dotfunc, &&dotstaticfunc, &&pushstaticcode, &&pushstr,
&&gcini, &&gcadd, &&gcend,
&&gack, &®pushimm, &&other, &&eoc
};
*(VM_Code*)(reg-SZ_INT) = ((Func)vector_at(a.obj->vtable, VAL))->code;
PRAGMA_POP()
DISPATCH()
+pushstaticcode:
+ *(m_bit*)byte = eRegPushImm;
+ VAL = (*(m_uint*)(reg) = (m_uint)((Func)VAL)->code);
+ reg += SZ_INT;
+ DISPATCH()
pushstr:
*(M_Object*)reg = new_string2(vm->gwion->mp, shred, (m_str)VAL);
reg += SZ_INT;
instr->opcode = eRegPushImm;
instr->m_val = (m_uint)code;
} else {
- instr->opcode = eRegSetImm;
- instr->m_val = (m_uint)((Func)instr->m_val)->code;
- instr->m_val2 = -SZ_INT;
+ const Func f = (Func)instr->m_val;
+ if(f->code) {
+ instr->opcode = eRegSetImm;
+ instr->m_val = (m_uint)((Func)instr->m_val)->code;
+ instr->m_val2 = -SZ_INT;
+ }
}
}
if(instr->opcode < eGack)