*/
#include <string.h>
#include <math.h>
+
#include "parser.h"
+#include "platform.h"
#define PARSER_HT_LOCALS 2
#define PARSER_HT_SIZE 512
if (ast_istype(expr, ast_value)) {
ast_value *val = (ast_value*)expr;
if (val->cvq == CV_CONST) {
- if (val->name[0] == '#')
+ if (val->name[0] == '#') {
compile_error(ctx, "invalid assignment to a literal constant");
- else
+ return false;
+ }
+ /*
+ * To work around quakeworld we must elide the error and make it
+ * a warning instead.
+ */
+ if (OPTS_OPTION_U32(OPTION_STANDARD) != COMPILER_QCC)
compile_error(ctx, "assignment to constant `%s`", val->name);
+ else
+ (void)!compile_warning(ctx, WARN_CONST_OVERWRITE, "assignment to constant `%s`", val->name);
return false;
}
}
out = exprs[0];
break;
case opid2('-','P'):
- if (!(out = fold_op(parser->fold, op, exprs))) {
- switch (exprs[0]->vtype) {
- case TYPE_FLOAT:
- out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F,
- (ast_expression*)parser->fold->imm_float[0],
- exprs[0]);
- break;
- case TYPE_VECTOR:
- out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_V,
- (ast_expression*)parser->fold->imm_vector[0],
- exprs[0]);
- break;
- default:
- compile_error(ctx, "invalid types used in expression: cannot negate type %s",
+ if ((out = fold_op(parser->fold, op, exprs)))
+ break;
+ if (exprs[0]->vtype != TYPE_FLOAT &&
+ exprs[0]->vtype != TYPE_VECTOR) {
+ compile_error(ctx, "invalid types used in unary expression: cannot negate type %s",
type_name[exprs[0]->vtype]);
- return false;
- }
+ return false;
}
+ out = (ast_expression*)ast_unary_new(ctx, (VINSTR_NEG_F-TYPE_FLOAT) + exprs[0]->vtype, exprs[0]);
break;
case opid2('!','P'):
else
{
(void)!parsewarning(parser, WARN_UNKNOWN_PRAGMAS, "ignoring #pragma %s", parser_tokval(parser));
- return false;
+
+ /* skip to eol */
+ while (!parse_eol(parser)) {
+ parser_next(parser);
+ }
+
+ return true;
}
return true;
varargs->expression.flags |= AST_FLAG_IS_VARARG;
varargs->expression.next = (ast_expression*)ast_value_new(ast_ctx(var), NULL, TYPE_VECTOR);
varargs->expression.count = 0;
- util_snprintf(name, sizeof(name), "%s##va##SET", var->name);
+ platform_snprintf(name, sizeof(name), "%s##va##SET", var->name);
if (!parser_create_array_setter_proto(parser, varargs, name)) {
ast_delete(varargs);
ast_block_delete(block);
goto enderrfn;
}
- util_snprintf(name, sizeof(name), "%s##va##GET", var->name);
+ platform_snprintf(name, sizeof(name), "%s##va##GET", var->name);
if (!parser_create_array_getter_proto(parser, varargs, varargs->expression.next, name)) {
ast_delete(varargs);
ast_block_delete(block);
static bool create_array_accessors(parser_t *parser, ast_value *var)
{
char name[1024];
- util_snprintf(name, sizeof(name), "%s##SET", var->name);
+ platform_snprintf(name, sizeof(name), "%s##SET", var->name);
if (!parser_create_array_setter(parser, var, name))
return false;
- util_snprintf(name, sizeof(name), "%s##GET", var->name);
+ platform_snprintf(name, sizeof(name), "%s##GET", var->name);
if (!parser_create_array_getter(parser, var, var->expression.next, name))
return false;
return true;
return false;
}
- if (var->expression.vtype != find->vtype) {
+ if (!ast_compare_type((ast_expression*)var, find)) {
char ty1[1024];
char ty2[1024];
goto cleanup;
}
- util_snprintf(name, sizeof(name), "%s##SETF", var->name);
+ platform_snprintf(name, sizeof(name), "%s##SETF", var->name);
if (!parser_create_array_field_setter(parser, array, name))
goto cleanup;
telem = ast_type_copy(ast_ctx(var), array->expression.next);
tfield = ast_value_new(ast_ctx(var), "<.type>", TYPE_FIELD);
tfield->expression.next = telem;
- util_snprintf(name, sizeof(name), "%s##GETFP", var->name);
+ platform_snprintf(name, sizeof(name), "%s##GETFP", var->name);
if (!parser_create_array_getter(parser, array, (ast_expression*)tfield, name)) {
ast_delete(tfield);
goto cleanup;