}
parser->lex->flags.noops = true;
- if (!vec_size(sy.out)) {
- parseerror(parser, "empty expression");
+ if (vec_size(sy.out) != 1) {
+ parseerror(parser, "expression with not 1 but %lu output values...", (unsigned long) vec_size(sy.out));
expr = NULL;
} else
expr = sy.out[0].out;
/* closing paren */
if (parser->tok != ')') {
parseerror(parser, "expected closing paren after 'if' condition");
- ast_delete(cond);
+ ast_unref(cond);
return false;
}
/* parse into the 'then' branch */
if (!parser_next(parser)) {
parseerror(parser, "expected statement for on-true branch of 'if'");
- ast_delete(cond);
+ ast_unref(cond);
return false;
}
if (!parse_statement_or_block(parser, &ontrue)) {
- ast_delete(cond);
+ ast_unref(cond);
return false;
}
if (!ontrue)
if (!parser_next(parser)) {
parseerror(parser, "expected on-false branch after 'else'");
ast_delete(ontrue);
- ast_delete(cond);
+ ast_unref(cond);
return false;
}
if (!parse_statement_or_block(parser, &onfalse)) {
ast_delete(ontrue);
- ast_delete(cond);
+ ast_unref(cond);
return false;
}
}
/* closing paren */
if (parser->tok != ')') {
parseerror(parser, "expected closing paren after 'while' condition");
- ast_delete(cond);
+ ast_unref(cond);
return false;
}
/* parse into the 'then' branch */
if (!parser_next(parser)) {
parseerror(parser, "expected while-loop body");
- ast_delete(cond);
+ ast_unref(cond);
return false;
}
if (!parse_statement_or_block(parser, &ontrue)) {
- ast_delete(cond);
+ ast_unref(cond);
return false;
}
cond = process_condition(parser, cond, &ifnot);
if (!cond) {
- ast_delete(ontrue);
+ ast_unref(ontrue);
return false;
}
aloop = ast_loop_new(ctx, NULL, cond, ifnot, NULL, false, NULL, ontrue);
if (parser->tok != ')') {
parseerror(parser, "expected closing paren after 'while' condition");
ast_delete(ontrue);
- ast_delete(cond);
+ ast_unref(cond);
return false;
}
/* parse on */
if (!parser_next(parser) || parser->tok != ';') {
parseerror(parser, "expected semicolon after condition");
ast_delete(ontrue);
- ast_delete(cond);
+ ast_unref(cond);
return false;
}
if (!parser_next(parser)) {
parseerror(parser, "parse error");
ast_delete(ontrue);
- ast_delete(cond);
+ ast_unref(cond);
return false;
}
ast_expression *initexpr, *cond, *increment, *ontrue;
ast_value *typevar;
- bool retval = true;
bool ifnot = false;
lex_ctx ctx = parser_ctx(parser);
aloop = ast_loop_new(ctx, initexpr, cond, ifnot, NULL, false, increment, ontrue);
*out = (ast_expression*)aloop;
- if (!parser_leaveblock(parser))
- retval = false;
- return retval;
+ if (!parser_leaveblock(parser)) {
+ ast_delete(aloop);
+ return false;
+ }
+ return true;
onerr:
- if (initexpr) ast_delete(initexpr);
- if (cond) ast_delete(cond);
- if (increment) ast_delete(increment);
+ if (initexpr) ast_unref(initexpr);
+ if (cond) ast_unref(cond);
+ if (increment) ast_unref(increment);
(void)!parser_leaveblock(parser);
return false;
}
ret = ast_return_new(ctx, exp);
if (!ret) {
- ast_delete(exp);
+ ast_unref(exp);
return false;
}
} else {
break;
}
}
- else if (parser->tok == '{' || parser->tok == '[')
+ else if (var->expression.vtype == TYPE_ARRAY && parser->tok == '{')
+ {
+ if (localblock) {
+ /* Note that fteqcc and most others don't even *have*
+ * local arrays, so this is not a high priority.
+ */
+ parseerror(parser, "TODO: initializers for local arrays");
+ break;
+ }
+ /*
+static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma, bool truthvalue, bool with_labels);
+*/
+ parseerror(parser, "TODO: initializing global arrays is not supported yet!");
+ break;
+ }
+ else if (var->expression.vtype == TYPE_FUNCTION && (parser->tok == '{' || parser->tok == '['))
{
if (localblock) {
parseerror(parser, "cannot declare functions within functions");
mem_d(parser);
return NULL;
}
-
for (i = 0; i < operator_count; ++i) {
if (operators[i].id == opid1('=')) {
intrin_intrinsics_destroy(parser);
+ code_cleanup(parser->code);
+
mem_d(parser);
}