}
*/
while (vec_size(sy->ops)) {
- if (sy->ops[vec_size(sy->ops)-1].paren == SY_PAREN_FUNC) {
+ if (vec_last(sy->ops).paren == SY_PAREN_FUNC) {
if (!parser_close_call(parser, sy))
return false;
break;
}
- if (sy->ops[vec_size(sy->ops)-1].paren == SY_PAREN_EXPR) {
+ if (vec_last(sy->ops).paren == SY_PAREN_EXPR) {
+ if (!vec_size(sy->out)) {
+ compile_error(vec_last(sy->ops).ctx, "empty paren expression");
+ vec_shrinkby(sy->ops, 1);
+ return false;
+ }
vec_shrinkby(sy->ops, 1);
return !functions_only;
}
- if (sy->ops[vec_size(sy->ops)-1].paren == SY_PAREN_INDEX) {
+ if (vec_last(sy->ops).paren == SY_PAREN_INDEX) {
if (functions_only)
return false;
/* pop off the parenthesis */
return false;
return true;
}
- if (sy->ops[vec_size(sy->ops)-1].paren == SY_PAREN_TERNARY) {
+ if (vec_last(sy->ops).paren == SY_PAREN_TERNARY) {
if (functions_only)
return false;
if (vec_last(parser->pot) != POT_TERNARY1) {
{
ast_expression *expr = NULL;
shunt sy;
+ size_t i;
bool wantop = false;
/* only warn once about an assignment in a truth value because the current code
* would trigger twice on: if(a = b && ...), once for the if-truth-value, once for the && part
onerr:
parser->lex->flags.noops = true;
+ for (i = 0; i < vec_size(sy.out); ++i) {
+ if (sy.out[i].out)
+ ast_unref(sy.out[i].out);
+ }
vec_free(sy.out);
vec_free(sy.ops);
return NULL;
if (!parser_create_array_setter_proto(parser, varargs, name)) {
ast_delete(varargs);
ast_block_delete(block);
- goto enderr;
+ goto enderrfn;
}
snprintf(name, sizeof(name), "%s##va##GET", var->name);
if (!parser_create_array_getter_proto(parser, varargs, varargs->expression.next, name)) {
ast_delete(varargs);
ast_block_delete(block);
- goto enderr;
+ goto enderrfn;
}
func->varargs = varargs;
}