*isfunc = true;
while (true) {
ast_value *param;
+ ast_value *fld;
+ bool isfield = false;
bool dummy;
if (!parser_next(parser))
if (parser->tok == ')')
break;
+ if (parser->tok == '.') {
+ isfield = true;
+ if (!parser_next(parser)) {
+ parseerror(parser, "expected field parameter type");
+ goto on_error;
+ }
+ }
+
temptype = parser_token(parser)->constval.t;
if (!parser_next(parser))
goto on_error;
goto on_error;
}
+ if (isfield) {
+ fld = ast_value_new(ctx, param->name, TYPE_FIELD);
+ fld->expression.next = (ast_expression*)param;
+ param = fld;
+ }
+
if (!paramlist_t_p_add(¶ms, param)) {
parseerror(parser, "Out of memory while parsing typename");
goto on_error;
(CanConstFold1(A) && CanConstFold1(B))
#define ConstV(i) (asvalue[(i)]->constval.vvec)
#define ConstF(i) (asvalue[(i)]->constval.vfloat)
+#define ConstS(i) (asvalue[(i)]->constval.vstring)
switch (op->id)
{
default:
- parseerror(parser, "internal error: unhandled operand");
+ parseerror(parser, "internal error: unhandled operator: %s (%i)", op->op, (int)op->id);
return false;
case opid1('.'):
}
break;
+ 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_unary_new(ctx, INSTR_NOT_F, exprs[0]);
+ break;
+ case TYPE_VECTOR:
+ if (CanConstFold1(exprs[0]))
+ out = (ast_expression*)parser_const_float(parser,
+ (!ConstV(0).x && !ConstV(0).y && !ConstV(0).z));
+ else
+ out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_V, exprs[0]);
+ break;
+ case TYPE_STRING:
+ if (CanConstFold1(exprs[0]))
+ out = (ast_expression*)parser_const_float(parser, !ConstS(0) || !*ConstS(0));
+ else
+ out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_S, exprs[0]);
+ break;
+ /* we don't constant-fold NOT for these types */
+ case TYPE_ENTITY:
+ out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_ENT, exprs[0]);
+ break;
+ case TYPE_FUNCTION:
+ out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_FNC, exprs[0]);
+ break;
+ default:
+ parseerror(parser, "invalid types used in expression: cannot logically 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) )
/* variable */
if (opts_standard == COMPILER_GMQCC)
{
- if (parser->memberof == TYPE_ENTITY)
- var = parser_find_field(parser, parser_tokval(parser));
+ if (parser->memberof == TYPE_ENTITY) {
+ /* still get vars first since there could be a fieldpointer */
+ var = parser_find_var(parser, parser_tokval(parser));
+ if (!var)
+ var = parser_find_field(parser, parser_tokval(parser));
+ }
else if (parser->memberof == TYPE_VECTOR)
{
parseerror(parser, "TODO: implement effective vector member access");
}
}
+ if (isfunc) {
+ ast_value *fval;
+ fval = ast_value_new(ctx, var->name, TYPE_FUNCTION);
+ if (!fval) {
+ ast_value_delete(var);
+ return false;
+ }
+ fval->expression.next = (ast_expression*)var;
+ MEM_VECTOR_MOVE(&var->expression, params, &fval->expression, params);
+ var = fval;
+ }
+
/* turn it into a field */
fld = ast_value_new(ctx, parser_tokval(parser), TYPE_FIELD);
fld->expression.next = (ast_expression*)var;