the opening paren is now an operator - to fix up the precedence rules, now 'anentity.afunction()' compiles

This commit is contained in:
Wolfgang (Blub) Bumiller 2012-08-18 15:25:45 +02:00
parent efc540ceba
commit e2faedcca8
3 changed files with 30 additions and 23 deletions

View file

@ -44,5 +44,5 @@ void() main = {
pawn.fun = funny;
(pawn.fun)();
pawn.fun();
};

View file

@ -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 },

View file

@ -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;