From: Jérémie Astor Date: Sat, 12 Feb 2022 11:37:35 +0000 (+0100) Subject: :art: clean_and_improve X-Git-Tag: nightly~378 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=d2ee7cfafdd6b533062344e139d65801df4ecf37;p=gwion.git :art: clean_and_improve --- diff --git a/include/lang_private.h b/include/lang_private.h index 734ba68e..c60954a6 100644 --- a/include/lang_private.h +++ b/include/lang_private.h @@ -1,5 +1,6 @@ #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); @@ -17,4 +18,5 @@ ANN m_bool import_union(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 diff --git a/src/emit/emit.c b/src/emit/emit.c index d2f528e4..06795e20 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -665,11 +665,12 @@ ANN static inline m_bool emit_exp_pop_next(const Emitter emit, Exp e); 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; @@ -884,7 +885,7 @@ ANN /*static*/ m_bool emit_interp(const Emitter emit, const Exp exp) { 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)); @@ -1938,7 +1939,8 @@ ANN static m_bool emit_implicit_cast(const Emitter emit, } 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)); // ???? @@ -2173,7 +2175,7 @@ ANN static m_bool emit_stmt_return(const Emitter emit, const Stmt_Exp stmt) { 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; diff --git a/src/lib/engine.c b/src/lib/engine.c index 15ee849f..5aafb051 100644 --- a/src/lib/engine.c +++ b/src/lib/engine.c @@ -21,8 +21,6 @@ static GACK(gack_class) { 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) @@ -40,32 +38,9 @@ static GACK(gack_char) { INTERP_PRINTF("%c", *(char *)VALUE); } 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); @@ -98,11 +73,6 @@ ANN static m_bool import_core_libs(const Gwi gwi) { 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)) @@ -198,40 +168,23 @@ ANN static m_bool import_core_libs(const Gwi gwi) { 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"); diff --git a/src/lib/lib_class.c b/src/lib/lib_class.c new file mode 100644 index 00000000..322a683b --- /dev/null +++ b/src/lib/lib_class.c @@ -0,0 +1,63 @@ +#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; +} diff --git a/src/lib/lib_func.c b/src/lib/lib_func.c index fb7291e6..87f923ae 100644 --- a/src/lib/lib_func.c +++ b/src/lib/lib_func.c @@ -47,7 +47,7 @@ ANN static Exp order_curry(const Env env, Exp fn, const Exp _arg) { 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; } @@ -76,9 +76,11 @@ static OP_CHECK(opck_curry) { 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]; } diff --git a/src/lib/lib_gack.c b/src/lib/lib_gack.c new file mode 100644 index 00000000..623b3f7a --- /dev/null +++ b/src/lib/lib_gack.c @@ -0,0 +1,58 @@ +#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; +} diff --git a/src/parse/check.c b/src/parse/check.c index a59b4e8f..3dc5526d 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -413,6 +413,7 @@ ANN static Type check_prim_hack(const Env env, const Exp *data) { 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) \ @@ -500,6 +501,7 @@ static Func find_func_match_actual(const Env env, Func func, const Exp args, 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) { @@ -525,6 +527,7 @@ static Func find_func_match_actual(const Env env, Func func, const Exp args, e1 = e1->next; } if (!e1) return func; +// if (!e && !e1) return func; } while ((func = func->next)); return NULL; } @@ -860,7 +863,8 @@ ANN static Type check_exp_binary(const Env env, const Exp_Binary *bin) { 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, @@ -916,7 +920,8 @@ ANN static m_bool predefined_call(const Env env, const Type t, 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;