mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2024-11-24 04:41:25 +00:00
unary - operator implemented, adding imm_vector_zero and imm_float_zero since those should be accessible quickly
This commit is contained in:
parent
8dfba4db6d
commit
c4730b405b
1 changed files with 56 additions and 3 deletions
59
parser.c
59
parser.c
|
@ -20,6 +20,9 @@ typedef struct {
|
|||
MEM_VECTOR_MAKE(ast_value*, imm_string);
|
||||
MEM_VECTOR_MAKE(ast_value*, imm_vector);
|
||||
|
||||
ast_value *imm_float_zero;
|
||||
ast_value *imm_vector_zero;
|
||||
|
||||
ast_function *function;
|
||||
MEM_VECTOR_MAKE(varentry_t, locals);
|
||||
size_t blocklocal;
|
||||
|
@ -161,6 +164,13 @@ ast_value* parser_const_float(parser_t *parser, double d)
|
|||
return out;
|
||||
}
|
||||
|
||||
ast_value* parser_const_float_0(parser_t *parser)
|
||||
{
|
||||
if (!parser->imm_float_zero)
|
||||
parser->imm_float_zero = parser_const_float(parser, 0);
|
||||
return parser->imm_float_zero;
|
||||
}
|
||||
|
||||
ast_value* parser_const_string(parser_t *parser, const char *str)
|
||||
{
|
||||
size_t i;
|
||||
|
@ -197,6 +207,22 @@ ast_value* parser_const_vector(parser_t *parser, vector v)
|
|||
return out;
|
||||
}
|
||||
|
||||
ast_value* parser_const_vector_f(parser_t *parser, float x, float y, float z)
|
||||
{
|
||||
vector v;
|
||||
v.x = x;
|
||||
v.y = y;
|
||||
v.z = z;
|
||||
return parser_const_vector(parser, v);
|
||||
}
|
||||
|
||||
ast_value* parser_const_vector_0(parser_t *parser)
|
||||
{
|
||||
if (!parser->imm_vector_zero)
|
||||
parser->imm_vector_zero = parser_const_vector_f(parser, 0, 0, 0);
|
||||
return parser->imm_vector_zero;
|
||||
}
|
||||
|
||||
ast_expression* parser_find_field(parser_t *parser, const char *name)
|
||||
{
|
||||
size_t i;
|
||||
|
@ -432,9 +458,10 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
|
|||
#define NotSameType(T) \
|
||||
(exprs[0]->expression.vtype != exprs[1]->expression.vtype || \
|
||||
exprs[0]->expression.vtype != T)
|
||||
#define CanConstFold(A, B) \
|
||||
(ast_istype((A), ast_value) && ast_istype((B), ast_value) && \
|
||||
((ast_value*)(A))->isconst && ((ast_value*)(B))->isconst)
|
||||
#define CanConstFold1(A) \
|
||||
(ast_istype((A), ast_value) && ((ast_value*)(A))->isconst)
|
||||
#define CanConstFold(A, B) \
|
||||
(CanConstFold1(A) && CanConstFold1(B))
|
||||
#define ConstV(i) (asvalue[(i)]->constval.vvec)
|
||||
#define ConstF(i) (asvalue[(i)]->constval.vfloat)
|
||||
switch (op->id)
|
||||
|
@ -479,6 +506,32 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
|
|||
sy->out[sy->out_count++] = syblock(ctx, blocks[0]);
|
||||
return true;
|
||||
|
||||
case opid2('-','P'):
|
||||
switch (exprs[0]->expression.vtype) {
|
||||
case TYPE_FLOAT:
|
||||
if (CanConstFold1(exprs[0]))
|
||||
out = (ast_expression*)parser_const_float(parser, -ConstF(0));
|
||||
else
|
||||
out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F,
|
||||
(ast_expression*)parser_const_float_0(parser),
|
||||
exprs[0]);
|
||||
break;
|
||||
case TYPE_VECTOR:
|
||||
if (CanConstFold1(exprs[0]))
|
||||
out = (ast_expression*)parser_const_vector_f(parser,
|
||||
-ConstV(0).x, -ConstV(0).y, -ConstV(0).z);
|
||||
else
|
||||
out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_V,
|
||||
(ast_expression*)parser_const_vector_0(parser),
|
||||
exprs[0]);
|
||||
break;
|
||||
default:
|
||||
parseerror(parser, "invalid types used in expression: cannot negate type %s",
|
||||
type_name[exprs[0]->expression.vtype]);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case opid1('+'):
|
||||
if (exprs[0]->expression.vtype != exprs[1]->expression.vtype ||
|
||||
(exprs[0]->expression.vtype != TYPE_VECTOR && exprs[0]->expression.vtype != TYPE_FLOAT) )
|
||||
|
|
Loading…
Reference in a new issue