From e2faedcca8d0cc6b2099cb5ff47da029efd7a2a6 Mon Sep 17 00:00:00 2001 From: "Wolfgang (Blub) Bumiller" Date: Sat, 18 Aug 2012 15:25:45 +0200 Subject: [PATCH] the opening paren is now an operator - to fix up the precedence rules, now 'anentity.afunction()' compiles --- data/fields.qc | 2 +- lexer.h | 4 +++- parser.c | 47 ++++++++++++++++++++++++++--------------------- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/data/fields.qc b/data/fields.qc index 19d9cc7..82b19ec 100644 --- a/data/fields.qc +++ b/data/fields.qc @@ -44,5 +44,5 @@ void() main = { pawn.fun = funny; - (pawn.fun)(); + pawn.fun(); }; diff --git a/lexer.h b/lexer.h index 5bd15f6..5e0d18c 100644 --- a/lexer.h +++ b/lexer.h @@ -138,11 +138,13 @@ typedef struct { #define opid3(a,b,c) ((a<<16)|(b<<8)|c) static const oper_info operators[] = { + { "(", 0, opid1('('), ASSOC_LEFT, 99, OP_PREFIX}, /* paren expression - non function call */ + { "++", 1, opid3('S','+','+'), ASSOC_LEFT, 16, OP_SUFFIX}, { "--", 1, opid3('S','-','-'), ASSOC_LEFT, 16, OP_SUFFIX}, { ".", 2, opid1('.'), ASSOC_LEFT, 15, 0 }, - { "(", 0, opid1('('), ASSOC_LEFT, 15, OP_SUFFIX }, + { "(", 0, opid1('('), ASSOC_LEFT, 15, 0 }, /* function call */ { "!", 1, opid2('!', 'P'), ASSOC_RIGHT, 14, OP_PREFIX }, { "~", 1, opid2('~', 'P'), ASSOC_RIGHT, 14, OP_PREFIX }, diff --git a/parser.c b/parser.c index 769f0da..1530d39 100644 --- a/parser.c +++ b/parser.c @@ -1110,23 +1110,8 @@ static ast_expression* parser_expression_leave(parser_t *parser, bool stopatcomm parser_token(parser)->constval.v.z)); } else if (parser->tok == '(') { - if (wantop) { - DEBUGSHUNTDO(printf("push (\n")); - ++parens; - /* we expected an operator, this is the function-call operator */ - if (!shunt_ops_add(&sy, syparen(parser_ctx(parser), 'f', sy.out_count-1))) { - parseerror(parser, "out of memory"); - goto onerr; - } - } else { - ++parens; - if (!shunt_ops_add(&sy, syparen(parser_ctx(parser), 1, 0))) { - parseerror(parser, "out of memory"); - goto onerr; - } - DEBUGSHUNTDO(printf("push (\n")); - } - wantop = false; + parseerror(parser, "internal error: '(' should be classified as operator"); + goto onerr; } else if (parser->tok == ')') { if (wantop) { @@ -1171,7 +1156,6 @@ static ast_expression* parser_expression_leave(parser_t *parser, bool stopatcomm break; } } - wantop = false; if (o == operator_count) { /* no operator found... must be the end of the statement */ break; @@ -1216,9 +1200,30 @@ static ast_expression* parser_expression_leave(parser_t *parser, bool stopatcomm olast = NULL; } - DEBUGSHUNTDO(printf("push operator %s\n", op->op)); - if (!shunt_ops_add(&sy, syop(parser_ctx(parser), op))) - goto onerr; + if (op->id == opid1('(')) { + if (wantop) { + DEBUGSHUNTDO(printf("push (\n")); + ++parens; + /* we expected an operator, this is the function-call operator */ + if (!shunt_ops_add(&sy, syparen(parser_ctx(parser), 'f', sy.out_count-1))) { + parseerror(parser, "out of memory"); + goto onerr; + } + } else { + ++parens; + if (!shunt_ops_add(&sy, syparen(parser_ctx(parser), 1, 0))) { + parseerror(parser, "out of memory"); + goto onerr; + } + DEBUGSHUNTDO(printf("push (\n")); + } + wantop = false; + } else { + DEBUGSHUNTDO(printf("push operator %s\n", op->op)); + if (!shunt_ops_add(&sy, syop(parser_ctx(parser), op))) + goto onerr; + wantop = false; + } } if (!parser_next(parser)) { goto onerr; -- 2.39.2