#define SY_PAREN_EXPR '('
#define SY_PAREN_FUNC 'f'
#define SY_PAREN_INDEX '['
+#define SY_PAREN_TERNARY '?'
static sy_elem syexp(lex_ctx ctx, ast_expression *v) {
sy_elem e;
return false;
return true;
}
+ if (sy->ops[vec_size(sy->ops)-1].paren == SY_PAREN_TERNARY) {
+ if (functions_only)
+ return false;
+ /* pop off the parenthesis */
+ vec_shrinkby(sy->ops, 1);
+ return true;
+ }
if (!parser_sy_pop(parser, sy))
return false;
}
} else if (op->id == opid2('?',':')) {
wantop = false;
vec_push(sy.ops, syop(parser_ctx(parser), op));
+ vec_push(sy.ops, syparen(parser_ctx(parser), SY_PAREN_TERNARY, 0));
wantop = false;
--ternaries;
} else if (op->id == opid2(':','?')) {
/* we don't push this operator */
+ if (!parser_close_paren(parser, &sy, false))
+ goto onerr;
wantop = false;
++ternaries;
} else {
{
ast_expression *operand;
ast_value *opval;
+ ast_value *typevar;
ast_switch *switchnode;
ast_switch_case swcase;
return false;
}
+ /* new block; allow some variables to be declared here */
+ parser_enterblock(parser);
+ while (true) {
+ typevar = NULL;
+ if (parser->tok == TOKEN_IDENT)
+ typevar = parser_find_typedef(parser, parser_tokval(parser), 0);
+ if (typevar || parser->tok == TOKEN_TYPENAME) {
+ if (!parse_variable(parser, block, false, CV_NONE, typevar)) {
+ ast_delete(switchnode);
+ return false;
+ }
+ continue;
+ }
+ if (!strcmp(parser_tokval(parser), "var") ||
+ !strcmp(parser_tokval(parser), "local"))
+ {
+ if (!parser_next(parser)) {
+ parseerror(parser, "expected variable declaration");
+ ast_delete(switchnode);
+ return false;
+ }
+ if (!parse_variable(parser, block, false, CV_VAR, NULL)) {
+ ast_delete(switchnode);
+ return false;
+ }
+ continue;
+ }
+ if (!strcmp(parser_tokval(parser), "const")) {
+ if (!parser_next(parser)) {
+ parseerror(parser, "expected variable declaration");
+ ast_delete(switchnode);
+ return false;
+ }
+ if (!strcmp(parser_tokval(parser), "var")) {
+ if (!parser_next(parser)) {
+ parseerror(parser, "expected variable declaration");
+ ast_delete(switchnode);
+ return false;
+ }
+ }
+ if (!parse_variable(parser, block, false, CV_CONST, NULL)) {
+ ast_delete(switchnode);
+ return false;
+ }
+ continue;
+ }
+ break;
+ }
+
/* case list! */
while (parser->tok != '}') {
ast_block *caseblock;
}
}
+ parser_leaveblock(parser);
+
/* closing paren */
if (parser->tok != '}') {
ast_delete(switchnode);