From 6409bf455f28eae96772556f9a6e5fa9832765c6 Mon Sep 17 00:00:00 2001 From: "Wolfgang (Blub) Bumiller" Date: Sun, 12 Aug 2012 19:24:08 +0200 Subject: [PATCH] -std=gmqcc way to handle fields by 'namespace' --- parser.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/parser.c b/parser.c index 8c4d035..486c327 100644 --- a/parser.c +++ b/parser.c @@ -25,6 +25,12 @@ typedef struct { size_t blocklocal; size_t errors; + + /* TYPE_FIELD -> parser_find_fields is used instead of find_var + * TODO: TYPE_VECTOR -> x, y and z are accepted in the gmqcc standard + * anything else: type error + */ + qcint memberof; } parser_t; MEM_VEC_FUNCTIONS(parser_t, varentry_t, globals) @@ -583,6 +589,7 @@ static ast_expression* parser_expression(parser_t *parser) ast_expression *expr = NULL; shunt sy; bool wantop = false; + bool gotmemberof = false; /* count the parens because an if starts with one, so the * end of a condition is an unmatched closing paren @@ -594,16 +601,37 @@ static ast_expression* parser_expression(parser_t *parser) while (true) { + if (gotmemberof) + gotmemberof = false; + else + parser->memberof = 0; if (!wantop) { bool nextwant = true; if (parser->tok == TOKEN_IDENT) { /* variable */ - ast_expression *var = parser_find_var(parser, parser_tokval(parser)); - /* in the gmqcc standard, fields are in their own namespace */ - if (!var && opts_standard != COMPILER_GMQCC) - var = parser_find_field(parser, parser_tokval(parser)); + ast_expression *var; + if (opts_standard == COMPILER_GMQCC) + { + if (parser->memberof == TYPE_FIELD) + var = parser_find_field(parser, parser_tokval(parser)); + else if (parser->memberof == TYPE_VECTOR) + { + parseerror(parser, "TODO: implement effective vector member access"); + goto onerr; + } + else if (parser->memberof) { + parseerror(parser, "namespace for member not found"); + goto onerr; + } + else + var = parser_find_var(parser, parser_tokval(parser)); + } else { + var = parser_find_var(parser, parser_tokval(parser)); + if (!var) + var = parser_find_field(parser, parser_tokval(parser)); + } if (!var) { parseerror(parser, "unexpected ident: %s", parser_tokval(parser)); goto onerr; @@ -714,6 +742,23 @@ static ast_expression* parser_expression(parser_t *parser) } /* found an operator */ op = &operators[o]; + if (op->id == opid1('.')) { + /* for gmqcc standard: open up the namespace of the previous type */ + ast_expression *prevex = sy.out[sy.out_count-1].out; + if (!prevex) { + parseerror(parser, "unexpected member operator"); + goto onerr; + } + if (prevex->expression.vtype == TYPE_ENTITY) + parser->memberof = TYPE_FIELD; + else if (prevex->expression.vtype == TYPE_VECTOR) + parser->memberof = TYPE_VECTOR; + else { + parseerror(parser, "type error: type has no members"); + goto onerr; + } + gotmemberof = true; + } if (sy.ops_count && !sy.ops[sy.ops_count-1].paren) olast = &operators[sy.ops[sy.ops_count-1].etype-1]; -- 2.39.2