return false;
}
- if (sy->ops[vec_size(sy->ops)-1].paren) {
+ if (vec_last(sy->ops).paren) {
parseerror(parser, "unmatched parenthesis");
return false;
}
- op = &operators[sy->ops[vec_size(sy->ops)-1].etype - 1];
- ctx = sy->ops[vec_size(sy->ops)-1].ctx;
+ op = &operators[vec_last(sy->ops).etype - 1];
+ ctx = vec_last(sy->ops).ctx;
DEBUGSHUNTDO(con_out("apply %s\n", op->op));
(ast_istype((A), ast_value) && ((ast_value*)(A))->isconst)
#define CanConstFold(A, B) \
(CanConstFold1(A) && CanConstFold1(B))
+#define CanConstFold3(A, B, C) \
+ (CanConstFold1(A) && CanConstFold1(B) && CanConstFold1(C))
#define ConstV(i) (asvalue[(i)]->constval.vvec)
#define ConstF(i) (asvalue[(i)]->constval.vfloat)
#define ConstS(i) (asvalue[(i)]->constval.vstring)
type_name[exprs[0]->expression.vtype],
type_name[exprs[1]->expression.vtype]);
parseerror(parser, "TODO: logical ops for arbitrary types using INSTR_NOT");
+ parseerror(parser, "TODO: optional early out");
return false;
}
+ if (opts_standard == COMPILER_GMQCC)
+ con_out("TODO: early out logic\n");
if (CanConstFold(exprs[0], exprs[1]))
out = (ast_expression*)parser_const_float(parser,
(generated_op == INSTR_OR ? (ConstF(0) || ConstF(1)) : (ConstF(0) && ConstF(1))));
out = (ast_expression*)ast_binary_new(ctx, generated_op, exprs[0], exprs[1]);
break;
+ case opid2('?',':'):
+ if (exprs[1]->expression.vtype != exprs[2]->expression.vtype) {
+ ast_type_to_string(exprs[1], ty1, sizeof(ty1));
+ ast_type_to_string(exprs[2], ty2, sizeof(ty2));
+ parseerror(parser, "iperands of ternary expression must have the same type, got %s and %s", ty1, ty2);
+ return false;
+ }
+ if (CanConstFold1(exprs[0]))
+ out = (ConstF(0) ? exprs[1] : exprs[2]);
+ else
+ out = (ast_expression*)ast_ternary_new(ctx, exprs[0], exprs[1], exprs[2]);
+ break;
+
case opid1('>'):
generated_op += 1; /* INSTR_GT */
case opid1('<'):
}
/* a colon without a pervious question mark cannot be a ternary */
- if (op->id == opid2(':','?')) {
+ if (!ternaries && op->id == opid2(':','?')) {
parser->tok = ':';
break;
}
ir_builder_delete(ir);
return false;
}
+ }
+ if (opts_dump)
+ ir_builder_dump(ir, con_out);
+ for (i = 0; i < vec_size(parser->functions); ++i) {
if (!ir_function_finalize(parser->functions[i]->ir_func)) {
con_out("failed to finalize function %s\n", parser->functions[i]->name);
ir_builder_delete(ir);
}
if (retval) {
- if (opts_dump)
+ if (opts_dumpfin)
ir_builder_dump(ir, con_out);
generate_checksum(parser);