}
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 };
+ CHECK_BO(emit_exp_pop_next(emit, e, 1))
+ struct Op_Import opi = { .op=insert_symbol(b ? "@conditionnal" : "@unconditionnal"),
+ .rhs=e->type, .pos=e->pos, .data=(uintptr_t)e};
return op_emit(emit, &opi);
}
#define emit_flow(emit,b) _flow(emit, b, 1)
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 };
+ const Exp_Binary bin = { .lhs=base, .rhs=e, .op=op };
+ struct Exp_ ebin = { .d={.exp_binary=bin}, .nspc=emit->env->curr};
+ struct Op_Import opi = { .op=op, .lhs=base->type, .rhs=e->type, .data=(uintptr_t)&ebin.d.exp_binary, .pos=e->pos };
CHECK_OB(op_emit(emit, &opi))
regpop(emit, base->type->size);
return GW_OK;
return decl->type;
}
-ANN static m_bool prim_array_inner(const Env env, const Type t, Type type, const Exp e) {
- const Type common = find_common_anc(t, type);
+
+ANN static inline void set_cast(const Env env, Type type, const Exp e) {
+ e->cast_to = type;
+ e->nspc = env->curr;
+}
+
+ANN static m_bool prim_array_inner(const Env env, Type type, const Exp e) {
+ const Type common = find_common_anc(e->type, type);
if(common)
return GW_OK;
- else if(isa(t, t_int) > 0 && isa(type, t_float) > 0) {
- e->cast_to = type;
- return GW_OK;
- }
- ERR_B(e->pos, _("array init [...] contains incompatible types ..."))
+ else if(!(isa(e->type, t_int) > 0 && isa(type, t_float) > 0))
+ ERR_B(e->pos, _("array init [...] contains incompatible types ..."))
+ set_cast(env, type, e);
+ return GW_OK;
}
ANN static inline Type prim_array_match(const Env env, Exp e) {
const Type type = e->type;
- do CHECK_BO(prim_array_inner(env, e->type, type, e))
+ do CHECK_BO(prim_array_inner(env, type, e))
while((e = e->next));
return array_type(env, type->array_depth ? array_base(type) : type, type->array_depth + 1);
}
const Type t = e->type;
if(isa(t, t_float) < 0) {
if(isa(t, t_int) > 0)
- e->cast_to = t_float;
+ set_cast(env, t_float, e);
else
ERR_B(e->pos, _("invalid type '%s' in %s value #%d...\n"
" (must be of type 'int' or 'float')"), t->name, s, count)
const struct Implicit imp = { e, t, e->pos };
struct Op_Import opi = { .op=insert_symbol("@implicit"), .lhs=e->type, .rhs=t, .data=(m_uint)&imp, .pos=e->pos };
return op_check(env, &opi) ? GW_OK : GW_ERROR;
- }
+ }
}
return match ? 1 : -1;
}
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 _flow(const Env env, const Exp e, const m_bool b) {
+ DECL_OO(const Type, type, = check_exp(env, e))
+ struct Op_Import opi = { .op=insert_symbol(b ? "@conditionnal" : "@unconditionnal"),
+ .rhs=type, .pos=e->pos, .data=(uintptr_t)e };
+ return op_check(env, &opi);
}
+#define check_flow(emit,b) _flow(emit, b, 1)
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, cond, = check_flow(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))
- 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,
array.depth = depth;
td.array = &array;
}
-// ptr = type_decl_resolve(env, &td); exit(3);
ptr = known_type(env, &td);
if(!GET_FLAG(ptr, checked))
check_class_def(env, ptr->e->def);
return GW_OK;
if(isa(t, t_float) > 0) {
e->cast_to = t_int;
+ e->nspc = env->curr;
return GW_OK;
}
ERR_B(e->pos, _("conditional must be of type 'int'..."))
}
#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) < 0 ||
+stmt_func_xxx(if, Stmt_If,, !(!check_flow(env, stmt->cond) ||
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) < 0 ||
+ !_flow(env, stmt->cond, !stmt->is_do ?
+ stmt_self(stmt)->stmt_type == ae_stmt_while :
+ stmt_self(stmt)->stmt_type != ae_stmt_while) ||
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) < 0 ||
+ !check_flow(env, stmt->c2->d.stmt_exp.val) ||
(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 m_bool _check_stmt_case(const Env env, const Stmt_Match stmt) {
CHECK_BB(match_case_exp(env, stmt->cond))
if(stmt->when)
- CHECK_OB(check_exp(env, stmt->when))
+ CHECK_OB(check_flow(env, stmt->when))
return check_stmt_list(env, stmt->list);
}
return variadic;
}
-ANN static void operator_func(const Func f) {
- const Arg_List a = f->def->base->args;
- const m_bool is_unary = GET_FLAG(f->def, unary);
- const Type l = is_unary ? NULL : a->type;
- const Type r = is_unary ? a->type : a->next ? a->next->type : NULL;
- struct Op_Import opi = { .op=f->def->base->xid, .lhs=l, .rhs=r, .data=(m_uint)f, .pos=f->def->pos };
- operator_set_func(&opi);
-}
-
ANN m_bool check_func_def(const Env env, const Func_Def fdef) {
const Func func = get_func(env, fdef);
m_bool ret = GW_OK;
REM_REF(variadic, env->gwion)
if(GET_FLAG(fdef, builtin))
func->code->stack_depth = fdef->stack_depth;
- else if(GET_FLAG(fdef, op))
- operator_func(func);
}
if(fdef->base->tmpl)
nspc_pop_type(env->gwion->mp, env->curr);
return GW_OK;
}
-ANN /*static inline */void inherit(const Type t) {
+ANN static inline void inherit(const Type t) {
const Nspc nspc = t->nspc, parent = t->e->parent->nspc;
nspc->info->offset = parent->info->offset;
if(parent->info->vtable.ptr)
}
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) {
- if(ock->opi->rhs)
- ((Exp_Binary*)ock->opi->data)->nspc = nspc;
- else
- ((Exp_Postfix*)ock->opi->data)->nspc = nspc;
- } else
- ((Exp_Unary*)ock->opi->data)->nspc = nspc;
+ if(ock->opi->op == insert_symbol(ock->env->gwion->st, "@implicit")) {
+ struct Implicit* imp = (struct Implicit*)ock->opi->data;
+ imp->e->nspc = nspc;
+ return;
+ }
+ if(ock->opi->op == insert_symbol(ock->env->gwion->st, "@conditionnal") ||
+ ock->opi->op == insert_symbol(ock->env->gwion->st, "@unconditionnal")) {
+ ((Exp)ock->opi->data)->nspc = nspc;
+ return;
+ }
+ exp_self((union exp_data*)ock->opi->data)->nspc = nspc;
}
ANN static Type op_check_inner(struct OpChecker* ock) {
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);
+ const Instr push = emit_add_instr(emit, mo->func->code ? RegPushImm : PushStaticCode);
+ push->m_val = ((m_uint)mo->func->code ?:(m_uint)mo->func);
+ const Instr instr = emit_exp_call1(emit, mo->func);
+ if(mo->func->def->base->xid == insert_symbol(emit->gwion->st, "@conditionnal"))
+ return emit_add_instr(emit, BranchEqInt);
+ if(mo->func->def->base->xid == insert_symbol(emit->gwion->st, "@unconditionnal"))
+ return emit_add_instr(emit, BranchNeqInt);
+ return instr;
}
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") ||
- 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;
- if(opi->lhs) {
- if(opi->rhs)
- return ((Exp_Binary*)opi->data)->nspc;
- else
- return ((Exp_Postfix*)opi->data)->nspc;
+ if(opi->op == insert_symbol(st, "@implicit")) {
+ struct Implicit* imp = (struct Implicit*)opi->data;
+ return imp->e->nspc;
}
- return ((Exp_Unary*)opi->data)->nspc;
+ if(opi->op == insert_symbol(st, "@conditionnal") ||
+ opi->op == insert_symbol(st, "@unconditionnal"))
+ return ((Exp)opi->data)->nspc;
+ return exp_self((union exp_data*)opi->data)->nspc;
}
ANN static inline Nspc ensure_nspc(SymTable *st, const struct Op_Import* opi) {