typedef struct
{
size_t etype; /* 0 = expression, others are operators */
+ int paren;
ast_expression *out;
ast_value *value; /* need to know if we can assign */
lex_ctx ctx;
e.out = v;
e.value = NULL;
e.ctx = ctx;
+ e.paren = 0;
return e;
}
static sy_elem syval(lex_ctx ctx, ast_value *v) {
e.out = (ast_expression*)v;
e.value = v;
e.ctx = ctx;
+ e.paren = 0;
return e;
}
e.out = NULL;
e.value = NULL;
e.ctx = ctx;
+ e.paren = 0;
+ return e;
+}
+
+static sy_elem syparen(lex_ctx ctx, int p) {
+ sy_elem e;
+ e.etype = 0;
+ e.out = NULL;
+ e.value = NULL;
+ e.ctx = ctx;
+ e.paren = p;
return e;
}
return false;
}
+ if (sy->ops[sy->ops_count-1].paren) {
+ parseerror(parser, "unmatched parenthesis");
+ return false;
+ }
+
op = &operators[sy->ops[sy->ops_count-1].etype - 1];
ctx = sy->ops[sy->ops_count-1].ctx;
{
if (!wantop)
{
+ bool nextwant = true;
if (parser->tok == TOKEN_IDENT)
{
/* variable */
goto onerr;
}
printf("Added: %s\n", var->name);
- } else if (parser->tok == TOKEN_FLOATCONST) {
+ }
+ else if (parser->tok == TOKEN_FLOATCONST) {
ast_value *val = parser_const_float(parser, (parser_token(parser)->constval.f));
if (!val)
return false;
parseerror(parser, "out of memory");
goto onerr;
}
- } else if (parser->tok == TOKEN_INTCONST) {
+ }
+ else if (parser->tok == TOKEN_INTCONST) {
ast_value *val = parser_const_float(parser, (double)(parser_token(parser)->constval.i));
if (!val)
return false;
goto onerr;
}
printf("Added: %i\n", parser_token(parser)->constval.i);
- } else {
+ }
+ else if (parser->tok == '(') {
+ nextwant = false; /* not expecting an operator next */
+ if (!shunt_ops_add(&sy, syparen(parser_ctx(parser), 1))) {
+ parseerror(parser, "out of memory");
+ goto onerr;
+ }
+ }
+ else {
/* TODO: prefix operators */
parseerror(parser, "expected statement");
goto onerr;
}
- wantop = true;
- parser->lex->flags.noops = false;
+ wantop = nextwant;
+ parser->lex->flags.noops = !wantop;
} else {
- if (parser->tok != TOKEN_OPERATOR) {
+ if (parser->tok == ')') {
+ /* we do expect an operator next */
+ /* closing an opening paren */
+ printf("Applying closing paren\n");
+ if (!sy.ops_count) {
+ parseerror(parser, "unmatched closing paren");
+ goto onerr;
+ }
+ if (sy.ops[sy.ops_count-1].paren == 1) {
+ parseerror(parser, "empty parenthesis expression");
+ goto onerr;
+ }
+ while (sy.ops_count) {
+ if (sy.ops[sy.ops_count-1].paren == 1) {
+ sy.ops_count--;
+ break;
+ }
+ if (!parser_sy_pop(parser, &sy))
+ goto onerr;
+ }
+ }
+ else if (parser->tok != TOKEN_OPERATOR) {
parseerror(parser, "expected operator or end of statement");
goto onerr;
- } else {
+ }
+ else {
/* classify the operator */
/* TODO: suffix operators */
const oper_info *op;
/* found an operator */
op = &operators[o];
- if (sy.ops_count)
+ if (sy.ops_count && !sy.ops[sy.ops_count-1].paren)
olast = &operators[sy.ops[sy.ops_count-1].etype-1];
while (olast && (
{
if (!parser_sy_pop(parser, &sy))
goto onerr;
- olast = sy.ops_count ? (&operators[sy.ops[sy.ops_count-1].etype-1]) : NULL;
+ if (sy.ops_count && !sy.ops[sy.ops_count-1].paren)
+ olast = &operators[sy.ops[sy.ops_count-1].etype-1];
}
if (!shunt_ops_add(&sy, syop(parser_ctx(parser), op)))