*/
#include <string.h>
#include <math.h>
+
#include "parser.h"
#define PARSER_HT_LOCALS 2
#define NotSameType(T) \
(exprs[0]->vtype != exprs[1]->vtype || \
exprs[0]->vtype != T)
+
switch (op->id)
{
default:
out = exprs[0];
break;
case opid2('-','P'):
- if (!(out = fold_op(parser->fold, op, exprs))) {
- 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;
- }
- /*
- * TYPE_VECTOR = TYPE_FLOAT+1,
- * VINSTR_NEG_V = VINSTR_NEG_F+1,
- * thus (VINSTR_NEG_F-TYPE_FLOAT) + TYPE_* = VINSTR_NEG_*.
- */
- out = (ast_expression*)ast_unary_new(ctx, (VINSTR_NEG_F-TYPE_FLOAT) + exprs[0]->vtype, exprs[0]);
+ 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;
}
+ out = (ast_expression*)ast_unary_new(ctx, (VINSTR_NEG_F-TYPE_FLOAT) + exprs[0]->vtype, exprs[0]);
break;
case opid2('!','P'):
out = (ast_expression*)ast_binary_new(ctx, subop,
out,
(ast_expression*)parser->fold->imm_float[1]);
+
break;
case opid2('+','='):
case opid2('-','='):
* sy->out should I be doing here?
*/
sy->out[fid] = syexp(foldval->node.context, foldval);
- vec_shrinkby(sy->out, 1);
+ vec_shrinkby(sy->out, paramcount);
vec_free(exprs);
return true;
if (parser->tok == TOKEN_IDENT)
typevar = parser_find_typedef(parser, parser_tokval(parser), 0);
- if (typevar || parser->tok == TOKEN_TYPENAME || parser->tok == '.')
+ if (typevar || parser->tok == TOKEN_TYPENAME || parser->tok == '.' || parser->tok == TOKEN_DOTS)
{
/* local variable */
if (!block) {
ctx = parser_ctx(parser);
/* types may start with a dot */
- if (parser->tok == '.') {
+ if (parser->tok == '.' || parser->tok == TOKEN_DOTS) {
isfield = true;
+ if (parser->tok == TOKEN_DOTS)
+ morefields += 2;
/* if we parsed a dot we need a typename now */
if (!parser_next(parser)) {
parseerror(parser, "expected typename for field definition");
/* Further dots are handled seperately because they won't be part of the
* basetype
*/
- while (parser->tok == '.') {
- ++morefields;
+ while (true) {
+ if (parser->tok == '.')
+ ++morefields;
+ else if (parser->tok == TOKEN_DOTS)
+ morefields += 3;
+ else
+ break;
if (!parser_next(parser)) {
parseerror(parser, "expected typename for field definition");
return NULL;
var->expression.flags & AST_FLAG_ALIAS)
var->desc = vstring;
+ if (parser_find_global(parser, var->name) && var->expression.flags & AST_FLAG_ALIAS) {
+ parseerror(parser, "function aliases cannot be forward declared");
+ retval = false;
+ goto cleanup;
+ }
+
+
/* Part 1:
* check for validity: (end_sys_..., multiple-definitions, prototypes, ...)
* Also: if there was a prototype, `var` will be deleted and set to `proto` which
if (parser->tok == TOKEN_IDENT)
istype = parser_find_typedef(parser, parser_tokval(parser), 0);
- if (istype || parser->tok == TOKEN_TYPENAME || parser->tok == '.')
+ if (istype || parser->tok == TOKEN_TYPENAME || parser->tok == '.' || parser->tok == TOKEN_DOTS)
{
return parse_variable(parser, NULL, false, CV_NONE, istype, false, false, 0, NULL);
}
}
}
if (!parser->assign_op) {
- printf("internal error: initializing parser: failed to find assign operator\n");
+ con_err("internal error: initializing parser: failed to find assign operator\n");
mem_d(parser);
return NULL;
}