ANN void free_emitter(MemPool, Emitter);
ANEW ANN VM_Code emit_code(const Emitter);
ANN VM_Code emit_ast(const Emitter emit, Ast ast);
-ANN m_bool emit_exp_call1(const Emitter, const Func);
+ANN Instr emit_exp_call1(const Emitter, const Func);
ANN2(1) Instr emit_add_instr(const Emitter, const f_instr) __attribute__((returns_nonnull));
ANN Code* emit_class_code(const Emitter, const m_str);
ANN m_bool emit_array_extend(const Emitter, const Type, const Exp);
Symbol op;
m_str ret, lhs, rhs;
Type (*ck)(Env, void*, m_bool*);
- m_bool (*em)(Emitter, void*);
+ Instr (*em)(Emitter, void*);
} DL_Oper;
typedef struct {
#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 OP_CHECK(a) ANN Type a(const Env env NUSED, void* data NUSED, m_bool* mut NUSED)
-#define OP_EMIT(a) ANN m_bool a(const Emitter emit NUSED, void* data NUSED)
+#define OP_EMIT(a) ANN Instr a(const Emitter emit NUSED, void* data NUSED)
#ifdef GWION_BUILTIN
#define GWI_BB(a) (void)(a);
#define GWI_OB(a) (void)(a);
ANN m_int gwi_func_end(const Gwi gwi, const ae_flag flag);
ANN2(1) m_int gwi_oper_ini(const Gwi gwi, const m_str l, const m_str r, const m_str t);
-ANN m_int gwi_oper_add(const Gwi gwi, opck);
-ANN m_int gwi_oper_emi(const Gwi gwi, opem);
+ANN m_int gwi_oper_add(const Gwi gwi, const opck);
+ANN m_int gwi_oper_emi(const Gwi gwi, const opem);
ANN2(1) m_int gwi_oper_end(const Gwi gwi, const m_str op, const f_instr f);
-
+ANN m_int gwi_oper_cond(const Gwi, const m_str, const f_instr, const f_instr);
ANN Type_Decl* str2decl(const Env, const m_str, m_uint* depth);
OP_CHECK(opck_const_rhs);
#define ERR_N(a, b, ...) { env_err(env, (a), (b), ## __VA_ARGS__); return t_null; }
typedef Type (*opck)(const Env, void*, m_bool*);
-typedef m_bool (*opem)(const Emitter, void*);
+typedef struct Instr_* (*opem)(const Emitter, void*);
struct Op_Import {
Type lhs, rhs, ret;
};
ANN m_bool add_op(const Gwion gwion, const struct Op_Import*);
ANN Type op_check(const Env, struct Op_Import*);
-ANN m_bool op_emit(const Emitter, const struct Op_Import*);
+ANN struct Instr_* op_emit(const Emitter, const struct Op_Import*);
ANN m_bool operator_set_func(const struct Op_Import*);
ANN void free_op_map(Map map, struct Gwion_* gwion);
#endif
ANN static m_bool emit_exp_call(const Emitter emit, const Exp_Call* exp_call) {
CHECK_BB(prepare_call(emit, exp_call))
- return emit_exp_call1(emit, exp_call->m_func);
+ return emit_exp_call1(emit, exp_call->m_func) ? GW_OK : GW_ERROR;
}
ANN static m_uint get_decl_size(Var_Decl_List a) {
struct Op_Import opi = { .op=bin->op, .lhs=lhs->type, .rhs=rhs->type, .pos=exp_self(bin)->pos, .data = (uintptr_t)bin };
CHECK_BB(emit_exp_pop_next(emit, lhs, 1))
CHECK_BB(emit_exp_pop_next(emit, rhs, 1))
- return op_emit(emit, &opi);
+ return op_emit(emit, &opi) ? GW_OK : GW_ERROR;
}
ANN static m_bool emit_exp_cast(const Emitter emit, const Exp_Cast* cast) {
ANN static m_bool emit_exp_post(const Emitter emit, const Exp_Postfix* post) {
struct Op_Import opi = { .op=post->op, .lhs=post->exp->type, .data=(uintptr_t)post };
CHECK_BB(emit_exp(emit, post->exp, 1))
- return op_emit(emit, &opi);
+ return op_emit(emit, &opi) ? GW_OK : GW_ERROR;
}
ANN static m_bool is_special(const Type t) {
return emit_add_instr(emit, Overflow);
}
-ANN m_bool emit_exp_call1(const Emitter emit, const Func f) {
+ANN Instr emit_exp_call1(const Emitter emit, const Func f) {
if(!f->code || (GET_FLAG(f, ref) && !GET_FLAG(f, builtin))) {
if(GET_FLAG(f, template) && !is_fptr(f->value_ref->type)) {
if(emit->env->func != f)
- CHECK_BB(emit_template_code(emit, f))
+ CHECK_BO(emit_template_code(emit, f))
else {
const Instr back = (Instr)vector_back(&emit->code->instr);
back->opcode = ePushStaticCode;
const Instr instr = emit_call(emit, f);
instr->m_val = f->def->base->ret_type->size;
instr->m_val2 = offset;
- return GW_OK;
+ return instr;
}
ANN static void emit_exp_spork_finish(const Emitter emit, const m_uint depth) {
ANN static m_bool spork_func(const Emitter emit, const Exp_Call* exp) {
if(GET_FLAG(exp->m_func, member))
SET_FLAG(emit->code, member);
- return emit_exp_call1(emit, exp->m_func);
+ return emit_exp_call1(emit, exp->m_func) ? GW_OK : GW_ERROR;
}
-ANN m_bool emit_exp_spork(const Emitter emit, const Exp_Unary* unary) {
+// TODO header
+ANN Instr emit_exp_spork(const Emitter emit, const Exp_Unary* unary) {
const m_bool is_spork = unary->op == insert_symbol("spork");
const Func f = !unary->code ? unary->exp->d.exp_call.m_func : NULL;
if(unary->code) {
push_spork_code(emit, is_spork ? SPORK_CODE_PREFIX : FORK_CODE_PREFIX, unary->code->pos);
if(!SAFE_FLAG(emit->env->func, member))
stack_alloc_this(emit);
- CHECK_BB(scoped_stmt(emit, unary->code, 0))
+ CHECK_BO(scoped_stmt(emit, unary->code, 0))
} else {
- CHECK_BB(prepare_call(emit, &unary->exp->d.exp_call))
+ CHECK_BO(prepare_call(emit, &unary->exp->d.exp_call))
push_spork_code(emit, is_spork ? SPORK_FUNC_PREFIX : FORK_CODE_PREFIX, unary->exp->pos);
- CHECK_BB(spork_func(emit, &unary->exp->d.exp_call))
+ CHECK_BO(spork_func(emit, &unary->exp->d.exp_call))
}
const VM_Code code = finalyze(emit);
const Instr ini = emit_add_instr(emit, unary->op == insert_symbol("spork") ? SporkIni : ForkIni);
const Instr end = emit_add_instr(emit, is_spork ? SporkEnd : ForkEnd);
end->m_val2 = f->def->base->ret_type->size;
}
- return GW_OK;
+ return ini;
}
ANN static m_bool emit_exp_unary(const Emitter emit, const Exp_Unary* unary) {
CHECK_BB(emit_exp_pop_next(emit, unary->exp, 1))
opi.rhs = unary->exp->type;
}
- return op_emit(emit, &opi);
+ return op_emit(emit, &opi) ? GW_OK : GW_ERROR;
}
ANN static m_bool emit_implicit_cast(const Emitter emit,
const restrict Exp from, const restrict Type to) {
const struct Implicit imp = { from, to, from->pos };
struct Op_Import opi = { .op=insert_symbol("@implicit"), .lhs=from->type, .rhs=to, .data=(m_uint)&imp };
- return op_emit(emit, &opi);
+ return op_emit(emit, &opi) ? GW_OK : GW_ERROR;
}
-ANN static Instr emit_flow(const Emitter emit, const Type type,
- const f_instr f1, const f_instr f2) {
- if(isa(type, t_float) > 0 || isa(type, t_dur) > 0 || isa(type, t_time) > 0)
- return emit_add_instr(emit, f2);
- return emit_add_instr(emit, f1);
+ANN static Instr _flow(const Emitter emit, const Exp e, const m_bool b) {
+ CHECK_BO(emit_exp_pop_next(emit, e, 0))
+ struct Op_Import opi = { .op=insert_symbol(b ? "@conditionnal" : "@unconditionnal"), .rhs=e->type, .pos=e->pos };
+ return op_emit(emit, &opi);
}
+#define emit_flow(emit,b) _flow(emit, b, 1)
ANN static m_bool emit_exp_if(const Emitter emit, const Exp_If* exp_if) {
- CHECK_BB(emit_exp(emit, exp_if->cond, 0))
- const Instr op = emit_flow(emit, exp_if->cond->type, BranchEqInt, BranchEqFloat);
+ const Instr op = emit_flow(emit, exp_if->cond);
CHECK_BB(emit_exp(emit, exp_if->if_exp ?: exp_if->cond, 0))
const Instr op2 = emit_add_instr(emit, Goto);
op->m_val = emit_code_size(emit);
ANN static m_bool emit_stmt_if(const Emitter emit, const Stmt_If stmt) {
emit_push_scope(emit);
- CHECK_BB(emit_exp_pop_next(emit, stmt->cond, 0))
- DECL_OB(const Instr, op, = emit_flow(emit, isa(stmt->cond->type, t_object) > 0 ?
- t_int : stmt->cond->type, BranchEqInt, BranchEqFloat))
+ DECL_OB(const Instr, op, = emit_flow(emit, stmt->cond))
CHECK_BB(scoped_stmt(emit, stmt->if_body, 1))
const Instr op2 = emit_add_instr(emit, Goto);
op->m_val = emit_code_size(emit);
emit_pop_scope(emit);
}
-ANN static Instr _flow(const Emitter emit, const Exp e, const m_bool b) {
- CHECK_BO(emit_exp_pop_next(emit, e, 0))
- const f_instr instr_i = b ? BranchEqInt : BranchNeqInt;
- const f_instr instr_f = b ? BranchEqFloat : BranchNeqFloat;
- return emit_flow(emit, e->type, instr_i, instr_f);
-}
-
ANN static m_bool emit_stmt_flow(const Emitter emit, const Stmt_Flow stmt) {
const m_uint index = emit_code_size(emit);
Instr op = NULL;
emit_push_stack(emit);
CHECK_BB(emit_stmt(emit, stmt->c1, 1))
const m_uint index = emit_code_size(emit);
- if(stmt->c2->stmt_type == ae_stmt_exp)
- emit_exp_pop_next(emit, stmt->c2->d.stmt_exp.val, 0);
- else
- CHECK_BB(emit_stmt(emit, stmt->c2, 0))
- const Instr op = emit_flow(emit, stmt->c2->d.stmt_exp.val->type,
- BranchEqInt, BranchEqFloat);
+ const Instr op = emit_flow(emit, stmt->c2->d.stmt_exp.val);
CHECK_BB(scoped_stmt(emit, stmt->body, 1))
const m_uint action_index = emit_code_size(emit);
if(stmt->c3) {
return exp->val ? emit_exp(emit, exp->val, 0) : 1;
}
-ANN static Instr emit_when(const Emitter emit, const Exp when) {
- CHECK_BO(emit_exp(emit, when, 1))
- return emit_add_instr(emit, BranchEqInt);
-}
-
ANN static m_bool emit_case_head(const Emitter emit, const Exp base, const Exp e, const Symbol op) {
CHECK_BB(emit_exp(emit, base, 1))
CHECK_BB(emit_exp(emit, e, 1))
Exp_Binary bin = { .lhs=base, .rhs=e, .op=op, .nspc=emit->env->curr };
struct Op_Import opi = { .op=op, .lhs=base->type, .rhs=e->type, .data=(uintptr_t)&bin, .pos=e->pos };
- CHECK_BB(op_emit(emit, &opi))
+ CHECK_OB(op_emit(emit, &opi))
regpop(emit, base->type->size);
return GW_OK;
}
ANN static m_bool emit_case_body(const Emitter emit, const struct Stmt_Match_* stmt) {
- const Instr when = stmt->when ? emit_when(emit, stmt->when) : NULL;
+ const Instr when = stmt->when ? emit_flow(emit, stmt->when) : NULL;
if(stmt->when)
CHECK_OB(when)
CHECK_BB(emit_stmt_list(emit, stmt->list))
pop->m_val = type->size;
if(!GET_FLAG(bin->lhs->type, nonnull))
emit_add_instr(emit, GWOP_EXCEPT);
- emit_add_instr(emit, ArrayAppend);
- return GW_OK;
+ return emit_add_instr(emit, ArrayAppend);
}
// check me. use common ancestor maybe
#include "parse.h"
ANN Type check_exp_call1(const Env env, const Exp_Call *exp);
-ANN m_bool emit_exp_spork(const Emitter, const Exp_Unary*);
+ANN Instr emit_exp_spork(const Emitter, const Exp_Unary*);
static INSTR(LambdaAssign) {
POP_REG(shred, SZ_INT)
Exp_Binary* bin = (Exp_Binary*)data;
if(bin->rhs->type->e->d.func->def->base->tmpl)
fptr_instr(emit, bin->lhs->type->e->d.func, 2);
- emit_add_instr(emit, int_r_assign);
+ const Instr instr = emit_add_instr(emit, int_r_assign);
if(isa(bin->lhs->type, t_fptr) < 0 && GET_FLAG(bin->rhs->type->e->d.func, member)) {
- const Instr instr = emit_add_instr(emit, LambdaAssign);
- instr->m_val = SZ_INT;
+ const Instr pop = emit_add_instr(emit, LambdaAssign);
+ pop->m_val = SZ_INT;
}
- return GW_OK;
+ return instr;
}
struct FptrInfo {
}
static OP_EMIT(opem_fptr_cast) {
- CHECK_BB(opem_basic_cast(emit, data))
+ CHECK_OO(opem_basic_cast(emit, data))
Exp_Cast* cast = (Exp_Cast*)data;
if(exp_self(cast)->type->e->d.func->def->base->tmpl)
fptr_instr(emit, cast->exp->type->e->d.func, 1);
if(GET_FLAG(cast->exp->type->e->d.func, member) &&
!(GET_FLAG(cast->exp->type, nonnull) || GET_FLAG(exp_self(cast)->type, nonnull)))
member_fptr(emit);
- return GW_OK;
+ return (Instr)GW_OK;// ???
}
static OP_CHECK(opck_fptr_impl) {
member_fptr(emit);
if(impl->t->e->d.func->def->base->tmpl)
fptr_instr(emit, ((Exp)impl->e)->type->e->d.func, 1);
- return GW_OK;
+ return (Instr)GW_OK;
}
ANN Type check_exp_unary_spork(const Env env, const Stmt code);
}
GWION_IMPORT(func) {
+ GWI_BB(gwi_oper_cond(gwi, "@func_ptr", BranchEqInt, BranchNeqInt))
GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "@function", NULL))
GWI_BB(gwi_oper_add(gwi, opck_func_call))
GWI_BB(gwi_oper_end(gwi, "=>", NULL))
+ GWI_BB(gwi_oper_ini(gwi, NULL, "@func_ptr", "int"))
+ GWI_BB(gwi_oper_end(gwi, "!", IntNot))
GWI_BB(gwi_oper_ini(gwi, "@function", "@func_ptr", NULL))
GWI_BB(gwi_oper_add(gwi, opck_fptr_at))
GWI_BB(gwi_oper_emi(gwi, opem_func_assign))
return GW_OK;
}
-ANN m_int gwi_oper_emi(const Gwi gwi, m_bool (*em)(Emitter, void*)) {
+ANN m_int gwi_oper_emi(const Gwi gwi, const opem em) {
gwi->oper.em = em;
return GW_OK;
}
return ret;
}
+ANN m_int gwi_oper_cond(const Gwi gwi, const m_str type,
+ const f_instr f1, const f_instr f2) {
+ GWI_BB(gwi_oper_ini(gwi, NULL, type, "int"))
+ GWI_BB(gwi_oper_end(gwi, "@conditionnal", f1))
+ GWI_BB(gwi_oper_end(gwi, "@unconditionnal", f2))
+ return GW_OK;
+}
+
ANN m_int gwi_fptr_ini(const Gwi gwi, const restrict m_str type, const restrict m_str name) {
dl_func_init(&gwi->func, type, name, 0);
return GW_OK;
const Instr instr = emit_add_instr(emit, GWOP_EXCEPT);
instr->m_val = SZ_INT;
}
- emit_add_instr(emit, ObjectAssign);
- return GW_OK;
+ return emit_add_instr(emit, ObjectAssign);
}
#define STR_FORCE ":force"
const Type r = exp_self(cast)->type;
if(nonnull_check(l, r))
emit_add_instr(emit, GWOP_EXCEPT);
- return GW_OK;
+ return (Instr)GW_OK;
}
static OP_CHECK(opck_implicit_null2obj) {
const Type r = imp->t;
if(nonnull_check(l, r))
emit_add_instr(emit, GWOP_EXCEPT);
- return GW_OK;
+ return (Instr)GW_OK;
}
GWION_IMPORT(object) {
t_object = gwi_mk_type(gwi, "Object", SZ_INT, NULL);
GWI_BB(gwi_class_ini(gwi, t_object, NULL, NULL))
GWI_BB(gwi_class_end(gwi))
+ GWI_BB(gwi_oper_cond(gwi, "Object", BranchEqInt, BranchNeqInt))
GWI_BB(gwi_oper_ini(gwi, "@null", "Object", "Object"))
GWI_BB(gwi_oper_add(gwi, at_object))
GWI_BB(gwi_oper_end(gwi, "@=>", ObjectAssign))
}
OP_EMIT(opem_basic_cast) {
- return GW_OK;
+ return (Instr)GW_OK;
}
OP_CHECK(opck_const_rhs) {
OP_EMIT(opem_new) {
const Exp_Unary* unary = (Exp_Unary*)data;
- CHECK_BB(emit_instantiate_object(emit, exp_self(unary)->type,
+ CHECK_BO(emit_instantiate_object(emit, exp_self(unary)->type,
unary->td->array, GET_FLAG(unary->td, ref)))
- CHECK_OB(emit_add_instr(emit, GcAdd))
- return GW_OK;
+ return emit_add_instr(emit, GcAdd);
}
}
static GWION_IMPORT(int) {
+ GWI_BB(gwi_oper_cond(gwi, "int", BranchEqInt, BranchNeqInt))
GWI_BB(gwi_oper_ini(gwi, "int", "int", "int"))
GWI_BB(import_int_op(gwi))
GWI_BB(import_int_logical(gwi))
return t_float;
}
+// can't it be just declared?
static OP_EMIT(opem_i2f) {
- emit_add_instr(emit, CastI2F);
- return GW_OK;
+ return emit_add_instr(emit, CastI2F);
}
static OP_EMIT(opem_f2i) {
- emit_add_instr(emit, CastF2I);
- return GW_OK;
+ return emit_add_instr(emit, CastF2I);
}
#define CHECK_FF(op, check, func) _CHECK_OP(op, check, float_##func)
}
static GWION_IMPORT(dur) {
+ GWI_BB(gwi_oper_cond(gwi, "dur", BranchEqFloat, BranchNeqFloat))
GWI_BB(gwi_oper_ini(gwi, "dur", "dur", "dur"))
CHECK_FF("=>", rassign, r_assign)
GWI_BB(gwi_oper_end(gwi, "+", FloatPlus))
}
static GWION_IMPORT(time) {
+ GWI_BB(gwi_oper_cond(gwi, "time", BranchEqFloat, BranchNeqFloat))
GWI_BB(gwi_oper_ini(gwi, "time", "time", "time"))
CHECK_FF("=>", rassign, r_assign)
GWI_BB(gwi_oper_ini(gwi, "time", "dur", "time"))
}
static GWION_IMPORT(float) {
+ GWI_BB(gwi_oper_cond(gwi, "float", BranchEqFloat, BranchNeqFloat))
GWI_BB(gwi_oper_ini(gwi, "float", "float", "float"))
GWI_BB(gwi_oper_end(gwi, "+", FloatPlus))
GWI_BB(gwi_oper_end(gwi, "-", FloatMinus))
static OP_EMIT(opem_ptr_assign) {
emit_add_instr(emit, GWOP_EXCEPT);
- emit_add_instr(emit, instr_ptr_assign);
- return GW_OK;
+ return emit_add_instr(emit, instr_ptr_assign);
}
static OP_CHECK(opck_ptr_deref) {
const Instr instr = emit_add_instr(emit, instr_ptr_deref);
instr->m_val = exp_self(unary)->type->size;
instr->m_val2 = exp_self(unary)->emit_var;
- return GW_OK;
+ return instr;
}
GWION_IMPORT(ptr) {
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) : "")
describe_string(Object, M_Object, SZ_INT,
- 16 + (rhs ? strlen(STRING(rhs)) : 0), release(lhs, shred),
+ 17 + (rhs ? strlen(STRING(rhs)) : 0), /*release(lhs, shred)*/,
"%p%s", (void*)lhs, rhs ? STRING(rhs) : "")
const type exp = (type)data; \
const Instr instr = emit_add_instr(emit, Tuple2Object); \
instr->m_val = (m_uint)rhs; \
- emit_add_instr(emit, ObjectAssign); \
- return 1; \
+ return emit_add_instr(emit, ObjectAssign); \
}
mk_opem_tuple2object(at, Exp_Binary *, exp->rhs->type)
mk_opem_tuple2object(cast, Exp_Cast *, exp_self(exp)->type)
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)) {
- emit_add_instr(emit, ObjectAssign);
- return GW_OK;
+ 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;
struct TupleEmit te = { .e=e, .v=v };
emit_unpack_instr(emit, &te);
- return GW_OK;
+ return (Instr)GW_OK;
}
ANN void tuple_info(const Env env, Type_Decl *base, const Var_Decl var) {
return op_check(env, &opi);
}
+ANN static m_bool check_flow(const Env env, const Exp exp) {
+ struct Op_Import opi = { .op=insert_symbol("@conditionnal"), .rhs=exp->type, .pos=exp->pos };
+ return op_check(env, &opi) ? GW_OK : GW_ERROR;
+}
+
ANN static Type check_exp_if(const Env env, const Exp_If* exp_if) {
DECL_OO(const Type, cond, = check_exp(env, exp_if->cond))
DECL_OO(const Type, if_exp, = (exp_if->if_exp ? check_exp(env, exp_if->if_exp) : cond))
DECL_OO(const Type, else_exp, = check_exp(env, exp_if->else_exp))
- if(isa(cond, t_int) < 0 && isa(cond, t_float) < 0 && isa(cond, t_object) < 0)
- ERR_O(exp_self(exp_if)->pos,
- _("Invalid type '%s' in if expression condition."), cond->name)
+ CHECK_BO(check_flow(env, exp_if->cond))
const Type ret = find_common_anc(if_exp, else_exp);
if(!ret)
ERR_O(exp_self(exp_if)->pos,
return GW_OK;
}
-ANN static m_bool check_flow(const Env env, const Exp exp, const m_str orig) {
- if(isa(exp->type, t_object) > 0 || isa(exp->type, t_int) > 0 || isa(exp->type, t_float) > 0 ||
- isa(exp->type, t_dur) > 0 || isa(exp->type, t_time) > 0)
- return GW_OK;
- ERR_B(exp->pos, _("invalid type '%s' (in '%s' condition)"), exp->type->name, orig)
-}
-
ANN static m_bool check_breaks(const Env env, const Stmt a, const Stmt b) {
vector_add(&env->scope->breaks, (vtype)a);
RET_NSPC(check_stmt(env, b))
}
#define stmt_func_xxx(name, type, prolog, exp) describe_stmt_func(check, name, type, prolog, exp)
stmt_func_xxx(if, Stmt_If,, !(!check_exp(env, stmt->cond) ||
- check_flow(env, stmt->cond, "if") < 0 ||
+ check_flow(env, stmt->cond) < 0 ||
check_stmt(env, stmt->if_body) < 0 ||
(stmt->else_body && check_stmt(env, stmt->else_body) < 0)) ? 1 : -1)
stmt_func_xxx(flow, Stmt_Flow,,
!(!check_exp(env, stmt->cond) ||
- check_flow(env, stmt->cond, stmt_self(stmt)->stmt_type == ae_stmt_while ? "while" : "until") < 0 ||
+ check_flow(env, stmt->cond) < 0 ||
check_conts(env, stmt_self(stmt), stmt->body) < 0) ? 1 : -1)
stmt_func_xxx(for, Stmt_For,, !(
for_empty(env, stmt) < 0 ||
check_stmt(env, stmt->c1) < 0 ||
check_stmt(env, stmt->c2) < 0 ||
- check_flow(env, stmt->c2->d.stmt_exp.val, "for") < 0 ||
+ check_flow(env, stmt->c2->d.stmt_exp.val) < 0 ||
(stmt->c3 && !check_exp(env, stmt->c3)) ||
check_conts(env, stmt_self(stmt), stmt->body) < 0) ? 1 : -1)
stmt_func_xxx(loop, Stmt_Loop,, !(!check_exp(env, stmt->cond) ||
ANN static void set_nspc(struct OpChecker* ock, const Nspc nspc) {
if(ock->opi->op == insert_symbol(ock->env->gwion->st, "@implicit"))return;
+ if(ock->opi->op == insert_symbol(ock->env->gwion->st, "@conditionnal"))return;
if(ock->opi->op == insert_symbol(ock->env->gwion->st, "$"))
((Exp_Cast*)ock->opi->data)->nspc = nspc;
if(ock->opi->lhs) {
return GW_OK;
}
-ANN static m_bool handle_instr(const Emitter emit, const M_Operator* mo) {
+ANN static Instr handle_instr(const Emitter emit, const M_Operator* mo) {
if(mo->func) {
const Instr instr = emit_add_instr(emit, mo->func->code ? RegPushImm : PushStaticCode);
instr->m_val = ((m_uint)mo->func->code ?:(m_uint)mo->func);
return emit_exp_call1(emit, mo->func);
}
- emit_add_instr(emit, mo->instr);
- return GW_OK;
+ return emit_add_instr(emit, mo->instr);
}
ANN static Nspc get_nspc(SymTable *st, const struct Op_Import* opi) {
- if(opi->op == insert_symbol(st, "@implicit"))
+ if(opi->op == insert_symbol(st, "@implicit") ||
+ opi->op == insert_symbol(st, "@conditionnal") ||
+ opi->op == insert_symbol(st, "@unconditionnal"))
return opi->rhs->e->owner;
if(opi->op == insert_symbol(st, "$"))
return ((Exp_Cast*)opi->data)->nspc;
return nspc;
}
-ANN m_bool op_emit(const Emitter emit, const struct Op_Import* opi) {
- Nspc nspc = ensure_nspc(emit->gwion->st, opi);
- if(!nspc)
- return GW_OK;
+ANN Instr op_emit(const Emitter emit, const struct Op_Import* opi) {
+ DECL_OO(Nspc, nspc, = ensure_nspc(emit->gwion->st, opi))
Type l = opi->lhs;
do {
Type r = opi->rhs;
}
} while(r && (r = op_parent(emit->env, r)));
} while(l && (l = op_parent(emit->env, l)));
- return GW_ERROR;
+ return NULL;
}
+++ /dev/null
-#! [contains] Invalid type
-null ? <<< 1 >>> : <<< 2 >>>;
+++ /dev/null
-#! [contains] in 'for' condition
-for(;null;);
+++ /dev/null
-#! [contains] in 'until' condition
-until(null);
+++ /dev/null
-#! [contains] in 'while' condition
-while(null);