X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=parser.c;fp=parser.c;h=1adab691326b9ea844e2d0cf82b65a8355ea0a08;hp=25c9c8c6fd279a6a40d8df6397c076cafd36f6d2;hb=8e87082e1df9b2860284aa383801bfd4f3d0ce8c;hpb=f860759758cd1a80b8f52b1ae8d76f0bc80282d0 diff --git a/parser.c b/parser.c index 25c9c8c..1adab69 100644 --- a/parser.c +++ b/parser.c @@ -1068,6 +1068,51 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy) out = (ast_expression*)ast_ternary_new(ctx, exprs[0], exprs[1], exprs[2]); break; + case opid3('<', '=', '>'): /* -1, 0, or 1 */ + if (NotSameType(TYPE_FLOAT)) { + ast_type_to_string(exprs[0], ty1, sizeof(ty1)); + ast_type_to_string(exprs[1], ty2, sizeof(ty2)); + compile_error(ctx, "invalid types used in comparision: %s and %s", + ty1, ty2); + + return false; + } + + if (CanConstFold(exprs[0], exprs[1])) { + if (ConstF(0) < ConstF(1)) + out = (ast_expression*)parser_const_float_neg1(parser); + else if (ConstF(0) == ConstF(1)) + out = (ast_expression*)parser_const_float_0(parser); + else if (ConstF(0) > ConstF(1)) + out = (ast_expression*)parser_const_float_1(parser); + } else { + /* if (lt) { */ + out = (ast_expression*)ast_ternary_new(ctx, + (ast_expression*)ast_binary_new(ctx, INSTR_LT, exprs[0], exprs[1]), + + /* out = -1 */ + (ast_expression*)parser_const_float_neg1(parser), + + /* } else { */ + /* if (eq) { */ + (ast_expression*)ast_ternary_new(ctx, + (ast_expression*)ast_binary_new(ctx, INSTR_EQ_F, exprs[0], exprs[1]), + + /* out = 0 */ + (ast_expression*)parser_const_float_0(parser), + + /* } else { */ + + /* out = 1 */ + (ast_expression*)parser_const_float_1(parser) + /* } */ + ) + /* } */ + ); + + } + break; + case opid1('>'): generated_op += 1; /* INSTR_GT */ case opid1('<'): @@ -1372,7 +1417,6 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy) else out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F, (ast_expression*)parser_const_float_neg1(parser), exprs[0]); break; - } #undef NotSameType @@ -1900,11 +1944,6 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma if (o == operator_count) { compile_error(parser_ctx(parser), "unknown operator: %s", parser_tokval(parser)); goto onerr; -#if 0 -/* Are there any expressions which actually end with an operator? */ - /* no operator found... must be the end of the statement */ - break; -#endif } /* found an operator */ op = &operators[o];