-Subproject commit d7cc060e0fe49405ca5494810c181ef211daf7f2
+Subproject commit c3a97d173da142bccfafb48ab532359ba77bb6aa
-Subproject commit 11f86a1a1aad81ff6dba21605398007898e2fb3f
+Subproject commit d78297aacc14071b97ae22e47f9e1c06054c15de
vflag_direct = 1 << 4,
vflag_builtin = 1 << 5,
vflag_member = 1 << 6,
- vflag_closed = 1 << 7
+ vflag_closed = 1 << 7,
+ vflag_inner = 1 << 8 // value is in a scope
// vflag_used = 1 << 3
} __attribute__((packed));
-Subproject commit 857e0e59f0bb00b6de35ad770814960c3e442d6a
+Subproject commit 37f2a1e20f85c2f455abb85340557b994c294cf0
emit_add_instr(emit, exec);
const VM_Code code = emit->info->emit_code(emit);
free_code(emit->gwion->mp, emit->code);
- emit->code = (Code *)vector_pop(&emit->stack);
+ emit_pop_code(emit);
return code;
}
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;
+ assert(back->execute == SetFunc);
+ if(f->code) {
+ back->opcode = eRegPushImm;
+ back->m_val = f->code;
+ // back->m_val2 = SZ_INT;
+ } else
+ back->m_val = (m_uint)f;
} else {
const Instr instr = emit_add_instr(emit, RegSetImm);
instr->m_val = (m_uint)f->code;
const m_uint val = base->m_val;
const m_uint val2 = base->m_val2;
base->opcode = eReg2Reg;
+// base->m_val = 0;//-SZ_INT;
base->m_val2 = -SZ_INT;
regpush(emit, SZ_INT);
const Instr instr = emit_add_instr(emit, (f_instr)(m_uint)exec);
instr->execute = SetFunc;
instr->m_val = (m_uint)f;
} else {
- const Instr instr = emit_add_instr(emit, SetFunc);
- instr->m_val = (m_uint)f;
+ const Instr back = (Instr)vector_back(&emit->code->instr);
+ if(back->execute != SetFunc) {
+ const Instr instr = emit_add_instr(emit, SetFunc);
+ instr->m_val = (m_uint)f;
+ }
}
}
const m_uint offset = emit_code_offset(emit);
static ANN int fdef_is_file_global(const Emitter emit, const Func_Def fdef) {
return !fbflag(fdef->base, fbflag_lambda) && !emit->env->class_def &&
!GET_FLAG(fdef->base, global) && !fdef->base->tmpl &&
+ !fbflag(fdef->base, fbflag_op) &&
!emit->env->scope->depth;
}
return NULL;
}
-ANN m_bool emit_ast(const Env env, Ast ast) {
- const Emitter emit = env->gwion->emit;
+ANN static inline void emit_clear(const Emitter emit) {
emit->info->memoize = 0;
emit->info->unroll = 0;
emit->info->line = 0;
emit->this_offset = 0;
emit->vararg_offset = 0;
+}
+
+ANN m_bool emit_ast(const Env env, Ast ast) {
+ const Emitter emit = env->gwion->emit;
+ emit_clear(emit);
emit->code = new_code(emit, emit->env->name);
emit_push_scope(emit);
const m_bool ret = emit_ast_inner(emit, ast);
emit->info->code = finalyze(emit, EOC);
else
emit_free_stack(emit);
+ emit_clear(emit);
return ret;
}
free_env_scope(a->scope, a->gwion);
while (pop_global(a->gwion))
;
- xfree(a);
+ mp_free(a->gwion->mp, Env, a);
}
ANN2(1, 3) m_uint env_push(const Env env, const Type type, const Nspc nspc) {
_mp_free(gwion->mp, t->size, a->d.ptr);
else if (is_class(gwion, t))
type_remref(t, gwion);
+ /* else */if (vflag(a, vflag_inner))
+ type_remref(t, gwion);
mp_free(gwion->mp, ValueFrom, a->from);
mp_free(gwion->mp, Value, a);
}
lint_space(gwi->lint);
}
lint(gwi->lint, "{/}%s{0}", op);
+ lint_space(gwi->lint);
lint_lparen(gwi->lint);
if (gwi->oper->lhs && gwi->oper->rhs) {
lint(gwi->lint, "{+}%s{0}",
#include "lang_private.h"
#include "specialid.h"
#include "gack.h"
+#include "traverse.h"
static GACK(gack_class) {
const Type type = actual_type(shred->info->vm->gwion, t) ?: t;
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];
+}
+
static ID_CHECK(idck_predicate) {
set_fflag(env->func, fflag_return);
return exp_self(prim)->type;
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))
+
return GW_OK;
}
// if(GET_FLAG(def->base, global) && !l->owner &&
// def->base->func->value_ref->from->owner_class)
// env_pop(env, scope);
+
if (l->def->base->func) {
if (env->curr->info->value != l->def->base->values) {
free_scope(env->gwion->mp, env->curr->info->value);
*(m_uint *)REG(-SZ_INT) = (lhs op rhs); \
}
-describe_logical(Eq, ==) describe_logical(Neq, !=)
+describe_logical(Eq, ==) describe_logical(Neq, !=);
- static OP_CHECK(opck_object_at) {
+static OP_CHECK(opck_object_at) {
const Exp_Binary *bin = (Exp_Binary *)data;
if (opck_rassign(env, data) == env->gwion->type[et_error])
return env->gwion->type[et_error];
ANN static inline Value get_value(const Env env, const Exp_Dot *member,
const Type t) {
const Value value = find_value(t, member->xid);
- if (value) return value;
+ if (value)
+ return value;
if (env->func && env->func->def->base->values)
return (Value)scope_lookup1(env->func->def->base->values,
(m_uint)member->xid);
const m_bool base_static = is_class(env->gwion, member->base->type);
const Type the_base =
base_static ? _class_base(member->base->type) : member->base->type;
- // if(!the_base->nspc)
- // ERR_N(&member->base->pos,
- // _("type '%s' does not have members - invalid use in dot expression
- // of %s"), the_base->name, str);
+
if (member->xid == insert_symbol(env->gwion->st, "this") && base_static)
ERR_N(exp_self(member)->pos,
_("keyword 'this' must be associated with object instance..."));
const Value value = get_value(env, member, the_base);
if (!value) {
const Value v = nspc_lookup_value1(env->curr, member->xid);
- if (v && is_func(env->gwion, v->type)) return v->type;
+ if (v && member->is_call && is_func(env->gwion, v->type))
+ return v->type;
env_err(env, exp_self(member)->pos, _("class '%s' has no member '%s'"),
the_base->name, str);
if (member->base->type->nspc) did_you_mean_type(the_base, str);
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;
static MFUN(string_erase) {
const m_str str = STRING(o);
- const m_int start = *(m_int *)MEM(SZ_INT);
+ const m_int _start = *(m_int *)MEM(SZ_INT);
const m_int rem = *(m_int *)MEM(SZ_INT * 2);
const m_int len = strlen(str);
const m_int size = len - rem + 1;
+ const m_int start = _start >= 0 ? _start : len - _start;
if (start >= len || size <= 0) {
handle(shred, "InvalidStringErase");
return;
#include "compile.h"
static void afl_run(const Gwion gwion) {
- gw_seed(gwion->vm->rand, 0);
__AFL_INIT();
- while (__AFL_LOOP(256)) {
- FILE *f = fdopen(0, "r");
+ while (__AFL_LOOP(128)) {
push_global(gwion, "[afl]");
+ FILE *f = fdopen(0, "r");
if (compile_file(gwion, "afl", f)) gwion_run(gwion);
pop_global(gwion);
}
}
-#define gwion_run(a) \
- { \
- afl_run(a); \
- return 0; \
- }
-#endif
+int main(int argc, char **argv) {
+ Arg arg = {};
+ struct Gwion_ gwion = {};
+ gwion_ini(&gwion, &arg);
+ arg_release(&arg);
+ afl_run(&gwion);
+ return EXIT_SUCCESS;
+}
+
+#else
int main(int argc, char **argv) {
Arg arg = {.arg = {.argc = argc, .argv = argv}, .loop = false};
#endif
return EXIT_SUCCESS;
}
+
+#endif
return op_check(env, &opi);
}
+// get the type of the function
+// without the mangling
+ANN static inline Type type_list_base_func(const Type type) {
+ const Nspc owner = type->info->value->from->owner;
+ const Symbol xid = type->info->func->def->base->xid;
+ return nspc_lookup_type0(owner, xid);
+}
+
+ANN static inline Type type_list_base(const Gwion gwion, const Type type) {
+ return !(is_func(gwion, type) && !is_fptr(gwion, type)) ?
+ type : type_list_base_func(type);
+}
+
ANN static Type_List mk_type_list(const Env env, const Arg_List arg,
const Type type, const loc_t pos) {
- const Type t =
- !arg->td->array ? type : array_type(env, type, arg->td->array->depth);
- Type_Decl *td = type2td(env->gwion, t, pos);
+ const Type base = type_list_base(env->gwion, type);
+ const Type t = !arg->td->array ?
+ base : array_type(env, base, arg->td->array->depth);
+ Type_Decl *td = type2td(env->gwion, t, pos);
return new_type_list(env->gwion->mp, td, NULL);
}
call->func->d.prim.d.var = call->func->d.exp_dot.xid;
call->func->exp_type = ae_exp_primary;
call->func->d.prim.prim_type = ae_prim_id;
- call->args = this;
CHECK_OO(check_exp_call(env, call));
return call->func->type->info->func;
}
ANN Func ufcs(const Env env, const Func up, Exp_Call *const call) {
const Value v = nspc_lookup_value1(env->curr, up->def->base->xid);
- if (v && is_func(env->gwion, v->type) && !vflag(v, vflag_member))
+ if (v && is_func(env->gwion, v->type) && !v->from->owner_class)
return call2ufcs(env, call, v);
return NULL;
}
Exp template_arg = exp->args;
while (arg && template_arg) {
if (list->xid == arg->td->xid) {
+ if (isa(template_arg->type, env->gwion->type[et_lambda]) > 0 &&
+ !template_arg->type->info->func)
+ break;
tl[args_number] =
mk_type_list(env, arg, template_arg->type, fdef->base->pos);
if (args_number) tl[args_number - 1]->next = tl[args_number];
}
list = list->next;
}
- if (args_number < type_number)
+ if (args_number < type_number) // TODO: free type_list
ERR_O(exp->func->pos, _("not able to guess types for template call."))
return tl[0];
}
Exp e = exp->args;
while (arg && e) {
arg->type = e->type;
+ if(is_class(env->gwion, arg->type))
+ type_addref(arg->type);
arg = arg->next;
e = e->next;
}
}
ANN m_bool func_check(const Env env, Exp_Call *const exp) {
+ if(exp->func->exp_type == ae_exp_dot)
+ exp->func->d.exp_dot.is_call = true;
CHECK_OB(check_exp(env, exp->func));
if (exp->func->exp_type == ae_exp_decl)
ERR_B(exp->func->pos, _("Can't call late function pointer at declaration "
if (!ret) return exp_self(exp)->type;
const Type t = actual_type(env->gwion, exp->func->type);
if (!is_func(env->gwion, t)) return check_exp_call1(env, exp);
+ if(isa(t, env->gwion->type[et_lambda]) > 0)
+ if (!t->info->func)
+ ERR_O(exp->func->pos, _("invalid lambda use."))
if (exp->args) CHECK_OO(check_exp(env, exp->args));
if (!t->info->func->def->base->tmpl)
ERR_O(exp_self(exp)->pos, _("template call of non-template function."))
if (tmpl_base(f->base->tmpl) && fbflag(f->base, fbflag_op)) return GW_OK;
const Func func = f->base->func;
const Func_Def fdef = func->def;
+ if(fflag(func, fflag_valid))return GW_OK;
+ set_fflag(fdef->base->func, fflag_valid);
assert(func == fdef->base->func);
if (env->class_def) // tmpl ?
CHECK_BB(check_parent_match(env, fdef));
--env->scope->depth;
env->func = former;
if (ret > 0) {
- set_fflag(fdef->base->func, fflag_valid);
if (env->class_def && fdef->base->effects.ptr &&
(override &&
!check_effect_overload(&fdef->base->effects, override->d.func_ref)))
env->class_def->size += t->size;
}
}
- }
- set_vflag(v, vflag_fglobal); // file global
+ } else
+ set_vflag(v, vflag_fglobal); // file global
} else if (GET_FLAG(decl->td, global))
SET_FLAG(v, global);
+ else if(v->type != env->gwion->type[et_auto] && v->type != env->class_def) {
+ type_addref(v->type);
+ set_vflag(v, vflag_inner); // file global
+ }
} while ((list = list->next));
((Exp_Decl *)decl)->type = decl->list->self->value->type;
return GW_OK;
const uint16_t pc = shred->pc;
for (m_uint i = 0; i < m_vector_size(&code->live_values); i++) {
VMValue *vmval = (VMValue *)m_vector_addr(&code->live_values, i);
- if (pc < vmval->start) break;
- if (pc > vmval->end) continue;
+ if (pc <= vmval->start) break;
+ if (pc >= vmval->end) continue;
m_bit *const data = &*(m_bit *)(shred->mem + vmval->offset);
compound_release(shred, vmval->t, data);
}