mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-03-22 18:51:24 +00:00
&& and || op folding
This commit is contained in:
parent
b0460de935
commit
c3da9b237b
1 changed files with 41 additions and 11 deletions
52
fold.c
52
fold.c
|
@ -113,7 +113,6 @@ static GMQCC_INLINE qcfloat_t vec3_mulvv(vec3_t a, vec3_t b) {
|
|||
return (a.x * b.x + a.y * b.y + a.z * b.z);
|
||||
}
|
||||
|
||||
|
||||
static GMQCC_INLINE vec3_t vec3_mulvf(vec3_t a, qcfloat_t b) {
|
||||
vec3_t out;
|
||||
out.x = a.x * b;
|
||||
|
@ -136,6 +135,10 @@ static GMQCC_INLINE vec3_t vec3_create(float x, float y, float z) {
|
|||
return out;
|
||||
}
|
||||
|
||||
static GMQCC_INLINE bool vec3_pbool(vec3_t a) {
|
||||
return (a.x && a.y && a.z);
|
||||
}
|
||||
|
||||
|
||||
static GMQCC_INLINE float fold_immvalue_float(ast_value *expr) {
|
||||
return expr->constval.vfloat;
|
||||
|
@ -357,6 +360,24 @@ static GMQCC_INLINE ast_expression *fold_op_mul(fold_t *fold, ast_value *a, ast_
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static GMQCC_INLINE bool fold_immediate_true(fold_t *fold, ast_value *v) {
|
||||
switch (v->expression.vtype) {
|
||||
case TYPE_FLOAT: return !!v->constval.vfloat;
|
||||
case TYPE_INTEGER: return !!v->constval.vint;
|
||||
case TYPE_VECTOR: return OPTS_FLAG(CORRECT_LOGIC) ? vec3_pbool(v->constval.vvec) : !!v->constval.vvec.x;
|
||||
case TYPE_STRING:
|
||||
if (!v->constval.vstring)
|
||||
return false;
|
||||
if (OPTS_FLAG(TRUE_EMPTY_STRINGS))
|
||||
return true;
|
||||
return !!v->constval.vstring[0];
|
||||
default:
|
||||
compile_error(fold_ctx(fold), "internal error: fold_immediate_true on invalid type");
|
||||
break;
|
||||
}
|
||||
return !!v->constval.vfunc;
|
||||
}
|
||||
|
||||
static GMQCC_INLINE ast_expression *fold_op_div(fold_t *fold, ast_value *a, ast_value *b) {
|
||||
if (isfloatonly(a)) {
|
||||
return (fold_possible(a) && fold_possible(b))
|
||||
|
@ -373,6 +394,21 @@ static GMQCC_INLINE ast_expression *fold_op_div(fold_t *fold, ast_value *a, ast_
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static GMQCC_INLINE ast_expression *fold_op_andor(fold_t *fold, ast_value *a, ast_value *b, bool isor) {
|
||||
if (fold_possible(a) && fold_possible(b)) {
|
||||
if (OPTS_FLAG(PERL_LOGIC)) {
|
||||
if (fold_immediate_true(fold, b))
|
||||
return (ast_expression*)b;
|
||||
} else {
|
||||
return ((isor) ? (fold_immediate_true(fold, a) || fold_immediate_true(fold, b))
|
||||
: (fold_immediate_true(fold, a) && fold_immediate_true(fold, b)))
|
||||
? (ast_expression*)fold->imm_float[1] /* 1.0f */
|
||||
: (ast_expression*)fold->imm_float[0]; /* 0.0f */
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ast_expression *fold_op(fold_t *fold, const oper_info *info, ast_expression **opexprs) {
|
||||
ast_value *a = (ast_value*)opexprs[0];
|
||||
ast_value *b = (ast_value*)opexprs[1];
|
||||
|
@ -438,16 +474,10 @@ ast_expression *fold_op(fold_t *fold, const oper_info *info, ast_expression **op
|
|||
return isfloat(a) ? fold_constgen_float (fold, ~(qcint_t)fold_immvalue_float(a))
|
||||
: NULL;
|
||||
|
||||
case opid1('*'): return fold_op_mul(fold, a, b);
|
||||
case opid1('/'): return fold_op_div(fold, a, b);
|
||||
/* TODO: seperate function for this case */
|
||||
return NULL;
|
||||
case opid2('|','|'):
|
||||
/* TODO: seperate function for this case */
|
||||
return NULL;
|
||||
case opid2('&','&'):
|
||||
/* TODO: seperate function for this case */
|
||||
return NULL;
|
||||
case opid1('*'): return fold_op_mul (fold, a, b);
|
||||
case opid1('/'): return fold_op_div (fold, a, b);
|
||||
case opid2('|','|'): return fold_op_andor(fold, a, b, true);
|
||||
case opid2('&','&'): return fold_op_andor(fold, a, b, false);
|
||||
case opid2('?',':'):
|
||||
/* TODO: seperate function for this case */
|
||||
return NULL;
|
||||
|
|
Loading…
Reference in a new issue