#ifndef __LANG_PRIVATE
#define __LANG_PRIVATE
+ANN m_bool import_class(const Gwi gwi);
ANN m_bool import_prim(const Gwi gwi);
ANN m_bool import_object(const Gwi gwi);
ANN m_bool import_vararg(const Gwi gwi);
ANN m_bool import_ref(const Gwi gwi);
ANN m_bool import_deep_equal(const Gwi gwi);
ANN m_bool import_dict(const Gwi gwi);
+ANN m_bool import_gack(const Gwi gwi);
#endif
ANN static m_bool emit_range(const Emitter emit, Range *range) {
if (range->start)
- CHECK_BB(emit_exp_pop_next(emit, range->start));
+// CHECK_BB(emit_exp_pop_next(emit, range->start));
+ CHECK_BB(emit_exp(emit, range->start));
else
regpushi(emit, 0);
if (range->end)
- CHECK_BB(emit_exp_pop_next(emit, range->end));
+ CHECK_BB(emit_exp(emit, range->end));
else
regpushi(emit, -1);
return GW_OK;
regseti(emit, (m_uint)e->type);
interp_size(emit, e->type);
const m_bool isobj = isa(e->type, emit->gwion->type[et_object]) > 0;
- if (isobj && e->exp_type != ae_exp_cast) emit_add_instr(emit, GackType);
+ if (isobj && e->exp_type != ae_exp_cast && !GET_FLAG(e->type, final)) emit_add_instr(emit, GackType);
const Instr instr = emit_add_instr(emit, Gack);
instr->m_val = emit_code_offset(emit);
} while ((e = e->next = next));
}
ANN2(1,2) static Instr _flow(const Emitter emit, const Exp e, Instr *const instr, const bool b) {
- CHECK_BO(emit_exp_pop_next(emit, e));
+// CHECK_BO(emit_exp_pop_next(emit, e));
+ CHECK_BO(emit_exp(emit, e));
if(instr)
*instr = emit_add_instr(emit, NoOp);
// emit_exp_addref1(emit, e, -exp_size(e)); // ????
if (stmt->val->exp_type == ae_exp_call && emit->env->func == f)
return optimize_tail_call(emit, &stmt->val->d.exp_call);
}
- CHECK_BB(emit_exp_pop_next(emit, stmt->val));
+ CHECK_BB(emit_exp(emit, stmt->val));
}
vector_add(&emit->code->stack_return, (vtype)emit_add_instr(emit, Goto));
return GW_OK;
static GACK(gack_function) { INTERP_PRINTF("%s", t->name) }
-static GACK(gack_gack) { INTERP_PRINTF("%s", *(m_str *)VALUE) }
-
static GACK(gack_fptr) {
const VM_Code code = *(VM_Code *)VALUE;
if (code)
static GACK(gack_float) { INTERP_PRINTF("%.4f", *(m_float *)VALUE); }
static GACK(gack_compound) { INTERP_PRINTF("%p", *(void **)VALUE); }
-#define mk_class_instr(op, arg0, arg1, ...) \
- static INSTR(instr_class_##op) { \
- POP_REG(shred, SZ_INT); \
- const Type l = *(Type *)(shred->reg - SZ_INT); \
- const Type r = *(Type *)(shred->reg); \
- *(m_uint *)(shred->reg - SZ_INT) = isa(arg0, arg1) > 0 __VA_ARGS__; \
- }
-mk_class_instr(ge, l, r) mk_class_instr(gt, l, r, &&l != r)
- mk_class_instr(le, r, l) mk_class_instr(lt, r, l, &&l != r)
-
- OP_CHECK(opck_object_dot);
-OP_EMIT(opem_object_dot);
-
-static OP_CHECK(opck_basic_ctor) {
- const Exp_Call *call = (Exp_Call *)data;
- ERR_N(exp_self(call)->pos, _("can't call a non-callable value"));
-}
-static OP_CHECK(opck_class_call) {
- const Exp_Binary *bin = (Exp_Binary *)data;
- Exp_Call call = {.func = bin->rhs, .args = bin->lhs};
- Exp e = exp_self(bin);
- e->exp_type = ae_exp_call;
- memcpy(&e->d.exp_call, &call, sizeof(Exp_Call));
- return check_exp_call1(env, &e->d.exp_call) ?: env->gwion->type[et_error];
-}
+OP_CHECK(opck_object_dot);
+OP_EMIT(opem_object_dot);
static ID_CHECK(idck_predicate) {
set_fflag(env->func, fflag_return);
GWI_BB(gwi_gack(gwi, t_void, gack_void))
GWI_BB(gwi_set_global_type(gwi, t_void, et_void))
- gwidoc(gwi, "a type for *pretty print*.");
- const Type t_gack = gwi_mk_type(gwi, "@Gack", SZ_INT, NULL);
- GWI_BB(gwi_gack(gwi, t_gack, gack_gack))
- GWI_BB(gwi_set_global_type(gwi, t_gack, et_gack))
-
gwidoc(gwi, "integer type.");
const Type t_int = gwi_mk_type(gwi, "int", SZ_INT, NULL);
GWI_BB(gwi_gack(gwi, t_int, gack_int))
GWI_BB(import_modules(gwi))
GWI_BB(import_ref(gwi))
- gwidoc(gwi, "Operators class types.");
- GWI_BB(gwi_oper_ini(gwi, "Class", "Class", "bool"))
- GWI_BB(gwi_oper_end(gwi, "==", int_eq))
- GWI_BB(gwi_oper_end(gwi, "!=", int_neq))
- GWI_BB(gwi_oper_end(gwi, ">=", instr_class_ge))
- 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))
-
- gwidoc(gwi, "internal constructor operator.");
- GWI_BB(gwi_oper_ini(gwi, NULL, (m_str)OP_ANY_TYPE, NULL))
- GWI_BB(gwi_oper_add(gwi, opck_basic_ctor))
- GWI_BB(gwi_oper_end(gwi, "@ctor", NULL))
-
gwidoc(gwi, "allow member access.");
GWI_BB(gwi_oper_ini(gwi, "@Compound", (m_str)OP_ANY_TYPE, NULL))
GWI_BB(gwi_oper_add(gwi, opck_object_dot))
GWI_BB(gwi_oper_emi(gwi, opem_object_dot))
GWI_BB(gwi_oper_end(gwi, "@dot", NULL))
+ GWI_BB(import_class(gwi))
+
gwidoc(gwi, "allow static access.");
GWI_BB(gwi_oper_ini(gwi, "Class", (m_str)OP_ANY_TYPE, NULL))
GWI_BB(gwi_oper_add(gwi, opck_object_dot))
GWI_BB(gwi_oper_emi(gwi, opem_object_dot))
GWI_BB(gwi_oper_end(gwi, "@dot", NULL))
-
- gwidoc(gwi, "Allow binary call to constructors.");
- GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "Class", NULL))
- GWI_BB(gwi_oper_add(gwi, opck_class_call))
- GWI_BB(gwi_oper_end(gwi, "=>", NULL))
-
GWI_BB(import_deep_equal(gwi));
GWI_BB(import_dict(gwi));
+ GWI_BB(import_gack(gwi));
// seemed need at a point to ease liking
gwi_enum_ini(gwi, "@hidden_enum");
--- /dev/null
+#include "gwion_util.h"
+#include "gwion_ast.h"
+#include "gwion_env.h"
+#include "vm.h"
+#include "instr.h"
+#include "emit.h"
+#include "gwion.h"
+#include "object.h"
+#include "operator.h"
+#include "import.h"
+#include "gwi.h"
+#include "gack.h"
+#include "traverse.h"
+
+#define mk_class_instr(op, arg0, arg1, ...) \
+ static INSTR(instr_class_##op) { \
+ POP_REG(shred, SZ_INT); \
+ const Type l = *(Type *)(shred->reg - SZ_INT); \
+ const Type r = *(Type *)(shred->reg); \
+ *(m_uint *)(shred->reg - SZ_INT) = isa(arg0, arg1) > 0 __VA_ARGS__; \
+ }
+mk_class_instr(ge, l, r) mk_class_instr(gt, l, r, &&l != r)
+mk_class_instr(le, r, l) mk_class_instr(lt, r, l, &&l != r)
+
+
+static OP_CHECK(opck_class_call) {
+ const Exp_Binary *bin = (Exp_Binary *)data;
+ Exp_Call call = {.func = bin->rhs, .args = bin->lhs};
+ Exp e = exp_self(bin);
+ e->exp_type = ae_exp_call;
+ memcpy(&e->d.exp_call, &call, sizeof(Exp_Call));
+ return check_exp_call1(env, &e->d.exp_call) ?: env->gwion->type[et_error];
+}
+
+static OP_CHECK(opck_basic_ctor) {
+ const Exp_Call *call = (Exp_Call *)data;
+// change to *no know constructor for {+G}%s{0}*?
+ ERR_N(exp_self(call)->pos, _("can't call a non-callable value"));
+}
+
+GWION_IMPORT(class) {
+
+ gwidoc(gwi, "Operators class types.");
+ GWI_BB(gwi_oper_ini(gwi, "Class", "Class", "bool"))
+ GWI_BB(gwi_oper_end(gwi, "==", int_eq))
+ GWI_BB(gwi_oper_end(gwi, "!=", int_neq))
+ GWI_BB(gwi_oper_end(gwi, ">=", instr_class_ge))
+ 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))
+
+ gwidoc(gwi, "Allow binary call to constructors.");
+ GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "Class", NULL))
+ GWI_BB(gwi_oper_add(gwi, opck_class_call))
+ GWI_BB(gwi_oper_end(gwi, "=>", NULL))
+
+ gwidoc(gwi, "internal constructor operator.");
+ GWI_BB(gwi_oper_ini(gwi, NULL, (m_str)OP_ANY_TYPE, NULL))
+ GWI_BB(gwi_oper_add(gwi, opck_basic_ctor))
+ GWI_BB(gwi_oper_end(gwi, "@ctor", NULL))
+
+ return GW_OK;
+}
if (hole) {
if (!arg) {
if (base) free_exp(mp, base);
- ERR_O(fn->pos, "no enough arguments for holes");
+ ERR_O(fn->pos, "not enough arguments for holes");
}
arg = arg->next;
}
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);
+
return check_exp_call1(env, &e->d.exp_call) ?: env->gwion->type[et_error];
}
--- /dev/null
+#include "gwion_util.h"
+#include "gwion_ast.h"
+#include "gwion_env.h"
+#include "vm.h"
+#include "instr.h"
+#include "emit.h"
+#include "gwion.h"
+#include "object.h"
+#include "operator.h"
+#include "import.h"
+#include "gwi.h"
+#include "gack.h"
+
+static GACK(gack_gack) { INTERP_PRINTF("%s", *(m_str *)VALUE) }
+
+static OP_CHECK(opck_gack_implicit) {
+ const struct Implicit *imp = (struct Implicit *)data;
+ return imp->t;
+}
+
+static OP_EMIT(opem_gack_implicit) {
+ const struct Implicit *imp = (struct Implicit *)data;
+ const Type t = imp->e->d.prim.d.exp->cast_to ?: imp->e->d.prim.d.exp->type;
+ if(t == imp->t) {
+ const Instr cpy = emit_add_instr(emit, Reg2RegOther2); // kind
+ cpy->m_val2 = SZ_INT;
+ const Instr instr = emit_add_instr(emit, RegMove);
+ instr->m_val = imp->t->size - SZ_INT;
+ } else {
+ const Instr push = emit_add_instr(emit, RegMove);
+ push->m_val = SZ_INT;
+ struct Op_Import opi = {.lhs = t,
+ .op = insert_symbol(emit->gwion->st, "@implicit"),
+ .rhs = imp->t};
+ CHECK_BB(op_emit(emit, &opi));
+ const Instr pop = emit_add_instr(emit, RegMove);
+ pop->m_val = -SZ_INT;
+ const Instr cpy = emit_add_instr(emit, Reg2RegOther2); // kind
+ cpy->m_val = cpy->m_val2 = imp->t->size;
+ }
+ return GW_OK;
+}
+
+GWION_IMPORT(gack) {
+
+ gwidoc(gwi, "a type for *pretty print*.");
+ const Type t_gack = gwi_mk_type(gwi, "@Gack", SZ_INT, NULL);
+ GWI_BB(gwi_gack(gwi, t_gack, gack_gack))
+ GWI_BB(gwi_set_global_type(gwi, t_gack, et_gack));
+
+ gwidoc(gwi, "@Gack implicit cast");
+ GWI_BB(gwi_oper_ini(gwi, "@Gack", (m_str)OP_ANY_TYPE, NULL))
+ GWI_BB(gwi_oper_add(gwi, opck_gack_implicit))
+ GWI_BB(gwi_oper_emi(gwi, opem_gack_implicit))
+ GWI_BB(gwi_oper_end(gwi, "@implicit", NULL))
+
+ return GW_OK;
+}
CHECK_OO(check_prim_interp(env, data));
env_weight(env, 1);
return env->gwion->type[et_gack];
+// return (*data)->type;
}
#define describe_prim_xxx(name, type) \
Exp e = args;
Arg_List e1 = func->def->base->args;
while (e) {
+ e->cast_to = NULL;
if (!e->type) // investigate
return NULL;
if (tflag(e->type, tflag_ref) && isa(e->type, e1->type) > 0) {
e1 = e1->next;
}
if (!e1) return func;
+// if (!e && !e1) return func;
} while ((func = func->next));
return NULL;
}
if (is_auto) bin->rhs->d.exp_decl.type = bin->lhs->type;
CHECK_OO(check_exp(env, bin->rhs));
if (is_auto) {
- bin->rhs->type = bin->lhs->type;
+ assert(bin->rhs->type == bin->lhs->type);
+// bin->rhs->type = bin->lhs->type;
set_vflag(bin->rhs->d.exp_decl.list->self->value, vflag_assigned);
}
struct Op_Import opi = {.op = bin->op,
ANN2(1) static inline bool curried(const Env env, Exp exp) {
while (exp) {
- if (is_hole(env, exp)) return true;
+ if (is_hole(env, exp))
+ return true;
exp = exp->next;
}
return false;