return GW_OK;
}
+ANN static m_bool emit_if_const(const Emitter emit, const Stmt_If stmt) {
+ if(stmt->cond->d.prim.d.num)
+ return emit_stmt(emit, stmt->if_body, 1);
+ return stmt->else_body ? emit_stmt(emit, stmt->else_body, 1) : GW_OK;
+}
+
ANN static m_bool emit_if(const Emitter emit, const Stmt_If stmt) {
+ if(stmt->cond->exp_type == ae_exp_primary && stmt->cond->d.prim.prim_type == ae_prim_num)
+ return emit_if_const(emit, stmt);
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);
ANN static m_bool _emit_stmt_flow(const Emitter emit, const Stmt_Flow stmt, const m_uint index) {
Instr op = NULL;
- if(!stmt->is_do)
- op = _flow(emit, stmt->cond, stmt_self(stmt)->stmt_type == ae_stmt_while);
+ const ae_stmt_t is_while = stmt_self(stmt)->stmt_type == ae_stmt_while;
+ const uint is_const = stmt->cond->exp_type == ae_exp_primary && stmt->cond->d.prim.prim_type == ae_prim_num;
+ if(!stmt->is_do) {
+ if(!is_const)
+ op = _flow(emit, stmt->cond, is_while);
+ else if((!is_while && stmt->cond->d.prim.d.num) ||
+ (is_while && !stmt->cond->d.prim.d.num))
+ return GW_OK;
+ }
CHECK_BB(scoped_stmt(emit, stmt->body, 1))
if(stmt->is_do) {
- CHECK_OB((op = _flow(emit, stmt->cond, stmt_self(stmt)->stmt_type != ae_stmt_while)))
- op->m_val = index;
+ if(!is_const) {
+ CHECK_OB((op = _flow(emit, stmt->cond, !is_while)))
+ op->m_val = index;
+ } else if((is_while && stmt->cond->d.prim.d.num) ||
+ (!is_while && !stmt->cond->d.prim.d.num)) {
+ const Instr goto_ = emit_add_instr(emit, Goto);
+ goto_->m_val = index;
+ }
} else {
const Instr goto_ = emit_add_instr(emit, Goto);
goto_->m_val = index;
- op->m_val = emit_code_size(emit);
+ if(op)
+ op->m_val = emit_code_size(emit);
}
return GW_OK;
}
describe_string_logical(eq, (!strcmp(STRING(lhs), STRING(rhs))))
describe_string_logical(neq, (strcmp(STRING(lhs), STRING(rhs))))
+static inline uint is_const_str(const Exp exp) {
+ return exp->exp_type == ae_exp_primary &&
+ exp->d.prim.prim_type == ae_prim_str;
+}
+
+#define opck_str(name, __exp__) \
+OP_CHECK(opck_string_##name) { \
+ Exp_Binary *bin = (Exp_Binary*)data; \
+ if(!is_const_str(bin->lhs) || !is_const_str(bin->rhs)) \
+ return env->gwion->type[et_bool]; \
+ const int ret = __exp__; \
+ free_exp(env->gwion->mp, bin->lhs); \
+ free_exp(env->gwion->mp, bin->rhs); \
+ const Exp e = exp_self(bin); \
+ e->exp_type = ae_exp_primary; \
+ e->d.prim.prim_type = ae_prim_num; \
+ e->d.prim.d.num = ret; \
+ return env->gwion->type[et_bool]; \
+}
+
+opck_str(eq, !strcmp(bin->lhs->d.prim.d.str, bin->rhs->d.prim.d.str))
+opck_str(neq, strcmp(bin->lhs->d.prim.d.str, bin->rhs->d.prim.d.str))
+
static CTOR(string_ctor) {
STRING(o) = _mp_calloc(shred->info->vm->gwion->mp, 1);
}
GWI_BB(gwi_class_end(gwi))
GWI_BB(gwi_oper_ini(gwi, "string", "string", "bool"))
+ GWI_BB(gwi_oper_add(gwi, opck_string_eq))
GWI_BB(gwi_oper_end(gwi, "==", String_eq))
+ GWI_BB(gwi_oper_add(gwi, opck_string_neq))
GWI_BB(gwi_oper_end(gwi, "!=", String_neq))
GWI_BB(gwi_oper_ini(gwi, "int", "string", "string"))