-Subproject commit 37f69271d28e0e167e888b1e341b0000ff768641
+Subproject commit bf16ee540da76d94a7d633a1419014a8b597efa1
#ifndef __GACK
#define __GACK
-ANN void gack(const Gwion, const m_bit*, const Instr);
+ANN void gack(const VM_Shred, const Instr);
#endif
#define __IMPORT
#define DLARG_MAX 6
-typedef void (*f_xtor)(const M_Object o, const m_bit*, const VM_Shred);
-typedef void (*f_mfun)(const M_Object o, const m_bit* RETURN, const VM_Shred sh);
-typedef void (*f_sfun)(const m_bit*, const m_bit* RETURN, const VM_Shred sh);
+typedef void (*f_xtor)(const M_Object, const m_bit*, const VM_Shred);
+typedef void (*f_mfun)(const M_Object, const m_bit*, const VM_Shred);
+typedef void (*f_sfun)(const m_bit*, const m_bit*, const VM_Shred);
+typedef void (*f_gack)(const Type, const m_bit*, const VM_Shred);
typedef void (*f_xfun)();
typedef struct Gwi_* Gwi;
#define SFUN(a) ANN void a(const M_Object o NUSED, const m_bit* RETURN NUSED, const VM_Shred shred NUSED)
#define CTOR(a) ANN void a(const M_Object o NUSED, const m_bit* _ NUSED, const VM_Shred shred NUSED)
#define DTOR(a) ANN void a(const M_Object o NUSED, const m_bit* _ NUSED, const VM_Shred shred NUSED)
+#define GACK(a) ANN2(2) void a(const Type t NUSED, const m_bit* VALUE NUSED, const VM_Shred shred NUSED)
#define OP_CHECK(a) ANN Type a(const Env env NUSED, void* data NUSED, m_bool* mut NUSED)
#define OP_EMIT(a) ANN Instr a(const Emitter emit NUSED, void* data NUSED)
#ifdef GWION_BUILTIN
ANN2(1,2) ANEW Type gwi_mk_type(const Gwi, const m_str, const m_uint, const Type);
ANN m_int gwi_add_type(const Gwi gwi, Type type);
ANN m_int gwi_set_global_type(const Gwi gwi, const Type type, const type_enum te);
+ANN m_bool gwi_gack(const Gwi gwi, const Type type, const f_gack d);
ANN2(1,2)m_int gwi_class_ini(const Gwi gwi, const Type type, const f_xtor pre_ctor, const f_xtor dtor);
ANN m_int gwi_class_ext(const Gwi gwi, Type_Decl* td);
ANN m_int gwi_class_end(const Gwi gwi);
eGcAdd,
eGcEnd,
eGack,
+ eGack3,
eDotTmplVal,
eOP_MAX,
eEOC,
#define GcAdd (f_instr)eGcAdd
#define GcEnd (f_instr)eGcEnd
#define Gack (f_instr)eGack
+#define Gack3 (f_instr)eGack3
#define DotTmplVal (f_instr)eDotTmplVal
#define OP_MAX (f_instr)eOP_MAX
#define EOC (f_instr)eEOC
} d;
struct Vector_ contains;
struct TupleForm_* tuple;
+ struct VM_Code_ *gack;
};
struct Type_ {
GcAdd
GcEnd
Gack
+Gack3
DotTmplVal
OP_MAX
EOC
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;
+ Exp e = exp, next = NULL;
do {
- vector_add(v, (vtype)e->type);
- offset += e->type->size;
- } while((e = e->next));
- const Instr instr = emit_add_instr(emit, Gack);
- instr->m_val = offset;
- instr->m_val2 = (m_uint)v;
+ next = e->next;
+ e->next = NULL;
+ CHECK_BB(emit_exp(emit, e, 0))
+ const Instr instr = emit_add_instr(emit, Gack);
+ instr->m_val = (m_uint)e->type;
+ instr->m_val2 = emit_code_offset(emit);
+ } while((e = e->next = next));
+ if(!(emit->env->func && emit->env->func->def->base->xid == insert_symbol("@gack")))
+ emit_add_instr(emit, Gack3);
return GW_OK;
}
if(GET_FLAG(func->def, dtor)) {
emit->env->class_def->nspc->dtor = func->code;
ADD_REF(func->code)
+ } else if(func->def->base->xid == insert_symbol("@gack")) {
+ emit->env->class_def->e->gack = func->code;
+ ADD_REF(func->code)
}
}
#include "lang_private.h"
#include "specialid.h"
-static FREEARG(freearg_gack) {
- free_vector(((Gwion)gwion)->mp, (Vector)instr->m_val2);
+static GACK(gack_class) {
+ printf("class(%p)", (*(Type*)VALUE)->e->d.base_type);
}
+static GACK(gack_function) {
+ printf("%s", t->name);
+}
+
+static GACK(gack_fptr) {
+ const VM_Code code = *(VM_Code*)VALUE;
+ if(code)
+ printf("%s", code ? code->name : NULL);
+ else
+ printf("%s", t->name);
+}
+
+static GACK(gack_void) {
+ printf("(void)");
+}
+
+static GACK(gack_int) {
+ printf("%li", *(m_uint*)VALUE);
+}
+
+static GACK(gack_float) {
+ printf("%.4f", *(m_float*)VALUE);
+}
+
+// we where using m_complex
+static GACK(gack_complex) {
+ printf("#(%.4f, %.4f)", *(m_float*)VALUE, *(m_float*)(VALUE + SZ_FLOAT));
+}
+static GACK(gack_polar) {
+ printf("%%(%.4f, %.4f*pi)", *(m_float*)VALUE, *(m_float*)(VALUE + SZ_FLOAT) / M_PI);
+}
+static GACK(gack_vec3) {
+ printf("%%(%.4f, %.4f, %.4f)", *(m_float*)VALUE, *(m_float*)(VALUE + SZ_FLOAT), *(m_float*)(VALUE + SZ_FLOAT*2));
+}
+static GACK(gack_vec4) {
+ printf("%%(%.4f, %.4f, %.4f, %.4f)", *(m_float*)VALUE, *(m_float*)(VALUE + SZ_FLOAT), *(m_float*)(VALUE + SZ_FLOAT*2), *(m_float*)(VALUE + SZ_FLOAT*3));
+}
#define mk_class_instr(op, arg0, arg1, ...) \
static INSTR(instr_class_##op) { \
mk_class_instr(lt, r, l, && l != r)
ANN static m_bool import_core_libs(const Gwi gwi) {
- const Type t_class = gwi_mk_type(gwi, "Class", SZ_INT, NULL);
+ const Type t_class = gwi_mk_type(gwi, "@Class", SZ_INT, NULL);
gwi->gwion->type[et_class] = t_class;
GWI_BB(gwi_add_type(gwi, t_class))
+ CHECK_BB(gwi_gack(gwi, gwi->gwion->type[et_class], gack_class)) // not working yet
+ gwi->gwion->type[et_class] = t_class;
const Type t_undefined = gwi_mk_type(gwi, "@Undefined", SZ_INT, NULL);
GWI_BB(gwi_set_global_type(gwi, t_undefined, et_undefined))
const Type t_auto = gwi_mk_type(gwi, "auto", SZ_INT, NULL);
GWI_BB(gwi_set_global_type(gwi, t_auto, et_auto))
SET_FLAG(t_class, abstract);
const Type t_void = gwi_mk_type(gwi, "void", 0, NULL);
+ CHECK_BB(gwi_gack(gwi, t_void, gack_void))
GWI_BB(gwi_set_global_type(gwi, t_void, et_void))
const Type t_null = gwi_mk_type(gwi, "@null", SZ_INT, NULL);
GWI_BB(gwi_set_global_type(gwi, t_null, et_null))
const Type t_function = gwi_mk_type(gwi, "@function", SZ_INT, NULL);
+ GWI_BB(gwi_gack(gwi, t_function, gack_function))
GWI_BB(gwi_set_global_type(gwi, t_function, et_function))
const Type t_fptr = gwi_mk_type(gwi, "@func_ptr", SZ_INT, t_function);
+ GWI_BB(gwi_gack(gwi, t_fptr, gack_fptr))
GWI_BB(gwi_set_global_type(gwi, t_fptr, et_fptr))
const Type t_lambda = gwi_mk_type(gwi, "@lambda", SZ_INT, t_function);
GWI_BB(gwi_set_global_type(gwi, t_lambda, et_lambda))
const Type t_gack = gwi_mk_type(gwi, "@Gack", SZ_INT, NULL);
GWI_BB(gwi_set_global_type(gwi, t_gack, et_gack))
const Type t_int = gwi_mk_type(gwi, "int", SZ_INT, NULL);
+ CHECK_BB(gwi_gack(gwi, t_int, gack_int))
GWI_BB(gwi_set_global_type(gwi, t_int, et_int))
const Type t_float = gwi_mk_type(gwi, "float", SZ_FLOAT, NULL);
+ CHECK_BB(gwi_gack(gwi, t_float, gack_float))
GWI_BB(gwi_set_global_type(gwi, t_float, et_float))
const Type t_dur = gwi_mk_type(gwi, "dur", SZ_FLOAT, NULL);
+ CHECK_BB(gwi_gack(gwi, t_dur, gack_float))
GWI_BB(gwi_add_type(gwi, t_dur))
const Type t_time = gwi_mk_type(gwi, "time", SZ_FLOAT, NULL);
+ CHECK_BB(gwi_gack(gwi, t_time, gack_float))
GWI_BB(gwi_add_type(gwi, t_time))
const Type t_now = gwi_mk_type(gwi, "@now", SZ_FLOAT, t_time);
GWI_BB(gwi_add_type(gwi, t_now))
gwi_reserve(gwi, "now");
const Type t_complex = gwi_mk_type(gwi, "complex", SZ_COMPLEX , NULL);
gwi->gwion->type[et_complex] = t_complex;
+ CHECK_BB(gwi_gack(gwi, t_complex, gack_complex))
const Type t_polar = gwi_mk_type(gwi, "polar", SZ_COMPLEX , NULL);
gwi->gwion->type[et_polar] = t_polar;
+ CHECK_BB(gwi_gack(gwi, t_polar, gack_polar))
const Type t_vec3 = gwi_mk_type(gwi, "Vec3", SZ_VEC3, NULL);
gwi->gwion->type[et_vec3] = t_vec3;
+ CHECK_BB(gwi_gack(gwi, t_vec3, gack_vec3))
const Type t_vec4 = gwi_mk_type(gwi, "Vec4", SZ_VEC4, NULL);
gwi->gwion->type[et_vec4] = t_vec4;
+ CHECK_BB(gwi_gack(gwi, t_vec4, gack_vec4))
GWI_BB(import_object(gwi))
const Type t_union = gwi_mk_type(gwi, "@Union", SZ_INT, gwi->gwion->type[et_object]);
gwi->gwion->type[et_union] = t_union;
GWI_BB(gwi_oper_end(gwi, ">", instr_class_gt))
GWI_BB(gwi_oper_end(gwi, "<=", instr_class_le))
GWI_BB(gwi_oper_end(gwi, "<", instr_class_lt))
-
- register_freearg(gwi, Gack, freearg_gack);
return GW_OK;
}
ANN m_bool type_engine_init(VM* vm, const Vector plug_dirs) {
vm->gwion->env->name = "[builtin]";
- struct Gwi_ gwi;
- memset(&gwi, 0, sizeof(struct Gwi_));
- gwi.gwion = vm->gwion;
- gwi.loc = new_loc(vm->gwion->mp, 0);
+ struct YYLTYPE loc = {};
+ struct Gwi_ gwi = { .gwion=vm->gwion, .loc=&loc };
GWI_BB(import_core_libs(&gwi))
vm->gwion->env->name = "[imported]";
for(m_uint i = 0; i < vector_size(plug_dirs); ++i) {
if(import && import(&gwi) < 0)
env_reset(gwi.gwion->env);
}
- free_loc(vm->gwion->mp, gwi.loc);
return GW_OK;
}
#include "object.h"
#include "instr.h"
#include "gwion.h"
+#include "operator.h"
+#include "import.h"
#include "gack.h"
-static void print_type(const Gwion gwion, const Type type) {
- const m_bool is_func = isa(type, gwion->type[et_function]) > 0 && !is_fptr(gwion, type);
- gw_out("(%s) ", is_func ? "@function" : type->name);
- if(GET_FLAG(type, typedef)) {
- gw_out(" aka ");
- print_type(gwion, type->e->parent);
- }
-}
-
-static inline void print_bool(const m_int i) {
- gw_out("%s", i ? "true" : "false");
-}
-
-static inline void print_int(const m_int i) {
- gw_out("%" INT_F "", i);
-}
-
-static inline void print_float(const m_float f) {
- gw_out("%.4f", f);
-}
-
-static inline void print_complex(const m_complex c) {
- gw_out("#(");
- print_float(creal(c));
- gw_out(", ");
- print_float(cimag(c));
- gw_out(")");
-}
-
-static inline void print_polar(const m_complex c) {
- gw_out("%%(");
- print_float(creal(c));
- gw_out(", ");
- print_float((m_float)cimag(c) / (m_float)M_PI);
- gw_out("*pi)");
-}
-
-ANN static inline void print_vec(const m_bit* f, const m_uint size) {
- gw_out("@(");
- for(m_uint i = 0; i < size; i++) {
- print_float(*(m_float*)(f + i * SZ_FLOAT));
- if(i < size - 1)
- gw_out(", ");
- }
- gw_out(")");
-}
-
-static inline void print_string1(const m_str str) {
- gw_out("%s", str);
-}
-
-static inline void print_string(const M_Object obj) {
- print_string1(obj ? STRING(obj) : "(null string)");
-}
-
-ANN2(1) static inline void print_object(const Gwion gwion, const Type type, const M_Object obj) {
- if(isa(type, gwion->type[et_string]) > 0)
- print_string(obj);
- else
- gw_out("%p", (void*)obj);
-}
-
-ANN static inline void print_func(const Gwion gwion,const Type type, const m_bit* stack) {
- if(is_fptr(gwion, type) > 0 && type->e->d.func->def->base->tmpl) {
- const Func f = *(Func*)stack;
- gw_out("%s", f ? f->name : "(nil)");
- return;
- }
- if(type->e->d.func) {
- const VM_Code code = is_fptr(gwion, type) ?
- *(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 Gwion gwion, const Type type, const m_bit* stack) {
- if(isa(type, gwion->type[et_bool]) > 0)
- print_bool(*(m_int*)stack);
- else if(isa(type, gwion->type[et_int]) > 0)
- print_int(*(m_int*)stack);
- else if(isa(type, gwion->type[et_complex]) > 0)
- print_complex(*(m_complex*)stack);
- else if(isa(type, gwion->type[et_polar]) > 0)
- print_polar(*(m_complex*)stack);
- else if(isa(type, gwion->type[et_vec3]) > 0)
- print_vec(stack, 3);
- else if(isa(type, gwion->type[et_vec4]) > 0)
- print_vec(stack, 4);
- else
- print_float(*(m_float*)stack);
-}
-
-ANN void gack(const Gwion gwion, const m_bit* reg, const Instr instr) {
- m_uint offset = instr->m_val;
- const Vector v = (Vector)instr->m_val2;
- const m_uint size = vector_size(v);
- for(m_uint i = size + 1; --i;) {
- const Type type = (Type)vector_at(v, size - i);
- if(size == 1)
- print_type(gwion, type);
- if(isa(type, gwion->type[et_object]) > 0)
- print_object(gwion, type, *(M_Object*)(reg-offset));
- else if(isa(type, gwion->type[et_function]) > 0)
- print_func(gwion, type, (reg-offset));
- else if(type == gwion->type[et_class])
- print_type(gwion, type);
- else if(isa(type, gwion->type[et_class]) > 0)
- print_type(gwion, type->e->d.base_type);
- else if(isa(type, gwion->type[et_void]) > 0)
- print_string1("void");
- else
- print_prim(gwion, type, (reg-offset));
- offset -= type->size;
- }
- gw_out("\n");
+ANN void gack(const VM_Shred shred, const Instr instr) {
+ Type t = (Type)instr->m_val;
+ do {
+ if(t->e->gack) {
+ if(GET_FLAG(t->e->gack, builtin))
+ ((f_gack)t->e->gack->native_func)(t, (shred->reg - t->size), shred);
+ else {
+ shred->mem += instr->m_val2;
+ *(m_uint*)(shred->mem+ SZ_INT) = instr->m_val2 + SZ_INT;
+ *(VM_Code*)(shred->mem+ SZ_INT*2) = shred->code;
+ *(m_uint*)(shred->mem+ SZ_INT*3) = shred->pc;
+ *(m_uint*)(shred->mem+ SZ_INT*4) = SZ_INT;
+ shred->mem += SZ_INT*5;
+ *(M_Object*)(shred->mem)= *(M_Object*)(shred->reg - SZ_INT);
+ shred->code = t->e->gack;
+ shred->pc = 0;
+ }
+ return;
+ }
+ } while((t = t->e->parent));
}
return list;
}
+ANN static m_bool mk_gack(MemPool p, const Type type, const f_gack d) {
+ const VM_Code code = new_vm_code(p, NULL, SZ_INT, ae_flag_member | ae_flag_builtin, "@gack");
+ code->native_func = (m_uint)d;
+ type->e->gack = code;
+ return GW_OK;
+}
+
+ANN m_bool gwi_gack(const Gwi gwi, const Type type, const f_gack d) {
+ return mk_gack(gwi->gwion->mp, type, d);
+}
+
ANN static m_bool mk_xtor(MemPool p, const Type type, const m_uint d, const ae_flag e) {
VM_Code* code = e == ae_flag_ctor ? &type->nspc->pre_ctor : &type->nspc->dtor;
const m_str name = type->name;
return env->class_def;
}
+static GACK(gack_object) {
+ printf("%p", *(M_Object*)VALUE);
+}
+
GWION_IMPORT(object) {
const Type t_object = gwi_mk_type(gwi, "Object", SZ_INT, NULL);
+ GWI_BB(gwi_gack(gwi, t_object, gack_object))
gwi->gwion->type[et_object] = t_object;
GWI_BB(gwi_class_ini(gwi, t_object, NULL, NULL))
GWI_BB(gwi_class_end(gwi))
GWI_BB(gwi_oper_end(gwi, "--", int_post_dec))
return GW_OK;
}
+static GACK(gack_bool) {
+ printf("%s", *(m_uint*)VALUE ? "true" : "false");
+}
static GWION_IMPORT(int_values) {
GWI_BB(gwi_enum_ini(gwi, "bool"))
GWI_BB(gwi_enum_add(gwi, "false", 0))
GWI_BB(gwi_enum_add(gwi, "true", 1))
const Type t_bool = gwi_enum_end(gwi);
+ GWI_BB(gwi_gack(gwi, t_bool, gack_bool))
gwi->gwion->type[et_bool] = t_bool;
GWI_BB(gwi_oper_ini(gwi, NULL, "int", "bool"))
GWI_BB(gwi_oper_end(gwi, "!", IntNot))
return prim_str(env, (Exp_Primary * const)prim);
}
+static GACK(gack_string) {
+ const M_Object obj = *(M_Object*)VALUE;
+ printf("%s", obj ? STRING(obj) : "(null string)");
+}
GWION_IMPORT(string) {
const Type t_string = gwi_mk_type(gwi, "string", SZ_INT, gwi->gwion->type[et_object]);
+ GWI_BB(gwi_gack(gwi, t_string, gack_string))
GWI_BB(gwi_class_ini(gwi, t_string, string_ctor, NULL))
gwi->gwion->type[et_string] = t_string;
gwi_item_ini(gwi, "int", "@data");
te->sz += value->type->size;
sz += value->type->size;
value->offset = emit_local(emit, value->type->size, 0);
+printf("value->offset %lu\n", value->offset);
} else {
sz += ((Type)vector_at(te->v, te->idx))->size;
break;
const Exp_Binary *bin = (Exp_Binary*)data;
if(!(bin->rhs->exp_type == ae_exp_primary &&
bin->rhs->d.exp_primary.primary_type == ae_primary_unpack)) {
- return emit_add_instr(emit, ObjectAssign);
+ return emit_add_instr(emit, ObjectAssign);
}
const Exp e = bin->rhs->d.exp_primary.d.tuple.exp;
const Vector v = &bin->lhs->type->e->tuple->types;
a->e->d.base_type = type->e->d.base_type;
a->array_depth = type->array_depth;
a->e->def = type->e->def;
+ a->e->gack = type->e->gack;
return a;
}
CHECK_BB(env_storage(env, fdef->flag, td_pos(fdef->base->td)))
if(tmpl_base(fdef->base->tmpl))
return GW_OK;
- if(GET_FLAG(fdef, dtor) && !env->class_def)
- ERR_B(td_pos(fdef->base->td), _("dtor must be in class def!!"))
+ if(!env->class_def && (GET_FLAG(fdef, dtor) || fdef->base->xid == insert_symbol("@gack")))
+ ERR_B(td_pos(fdef->base->td), _("'%s' must be in class def!!"), s_name(fdef->base->xid))
if(GET_FLAG(fdef, op) && env->class_def)
SET_FLAG(fdef, static);
struct Func_ fake = { .name=s_name(fdef->base->xid) }, *const former = env->func;
else ADVANCE(); \
IDISPATCH();
+#define VM_OUT shred->code = code; shred->reg = reg; shred->mem = mem; shred->pc = PC;
+
__attribute__ ((hot, optimize("-O2")))
ANN void vm_run(const VM* vm) { // lgtm [cpp/use-of-goto]
static const void* dispatch[] = {
&&staticint, &&staticfloat, &&staticother,
&&dotfunc, &&dotstaticfunc, &&pushstaticcode, &&pushstr,
&&gcini, &&gcadd, &&gcend,
- &&gack, &®pushimm, &&other, &&eoc
+ &&gack, &&gack3, &®pushimm, &&other, &&eoc
};
const Shreduler s = vm->shreduler;
register VM_Shred shred;
reg -= SZ_FLOAT;
shredule(s, shred, *(m_float*)(reg-SZ_FLOAT));
*(m_float*)(reg-SZ_FLOAT) += vm->bbq->pos;
- shred->code = code;
- shred->reg = reg;
- shred->mem = mem;
- shred->pc = PC;
+ VM_OUT
break;
setcode:
a.code = *(VM_Code*)(reg-SZ_INT);
byte = bytecode = (code = a.code)->bytecode;
SDISPATCH();
funcmemberend:
- shred->mem = mem;
- shred->reg = reg;
- shred->pc = PC;
- shred->code = code;
+ VM_OUT
{
register const m_uint val = VAL;
register const m_uint val2 = VAL2;
if(idx < 0 || (m_uint)idx >= m_vector_size(ARRAY(a.obj))) {
gw_err(_(" ... at index [%" INT_F "]\n"), idx);
gw_err(_(" ... at dimension [%" INT_F "]\n"), VAL);
- shred->code = code;
- shred->mem = mem;
- shred->pc = PC;
+ VM_OUT
exception(shred, "ArrayOutofBounds");
- continue;
+ continue; // or break ?
}
DISPATCH()
}
++a.obj->ref;
DISPATCH()
objassign:
-{
+{ // use a.obj ?
register const M_Object tgt = **(M_Object**)(reg -SZ_INT);
if(tgt) {
--tgt->ref;
_release(a.obj, shred);
DISPATCH()
gack:
- gack(vm->gwion, reg, (Instr)VAL);
- DISPATCH()
+ VM_OUT
+ gack(shred, (Instr)VAL);
+ goto in;
+gack3:
+ gw_out("\n");
+ DISPATCH();
other:
-shred->code = code;
-shred->reg = reg;
-shred->mem = mem;
-shred->pc = PC;
- ((f_instr)VAL2)(shred, (Instr)VAL);
-if(!s->curr)break;
+ VM_OUT
+ ((f_instr)VAL2)(shred, (Instr)VAL);
+in:
+ if(!s->curr)
+ break;
bytecode = (code = shred->code)->bytecode;
reg = shred->reg;
mem = shred->mem;
PC_DISPATCH(shred->pc)
eoc:
- shred->code = code;
- shred->mem = mem;
+ VM_OUT
vm_shred_exit(shred);
} while(s->curr);
MUTEX_UNLOCK(s->mutex);
-#! [contains] dtor must be in class def!!
+#! [contains] 'dtor' must be in class def!!
dtor {}