#define BC_PARSE_TOKEN_INST(t) ((char) ((t) -BC_LEX_NEG + BC_INST_NEG))
static BC_STATUS zbc_parse_else(BcParse *p);
-static BcStatus bc_parse_stmt(BcParse *p);
-static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next);
+static BC_STATUS zbc_parse_stmt(BcParse *p);
+static BC_STATUS zbc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next);
static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags, BcParseNext next);
+#if ERRORS_ARE_FATAL
+# define zbc_parse_else(...) (zbc_parse_else(__VA_ARGS__), BC_STATUS_SUCCESS)
+# define zbc_parse_stmt(...) (zbc_parse_stmt(__VA_ARGS__), BC_STATUS_SUCCESS)
+# define zbc_parse_expr(...) (zbc_parse_expr(__VA_ARGS__), BC_STATUS_SUCCESS)
+#endif
static BC_STATUS zbc_parse_operator(BcParse *p, BcLexType type, size_t start,
size_t *nexprs, bool next)
for (nparams = 0; p->l.t.t != BC_LEX_RPAREN; ++nparams) {
flags = (flags & ~(BC_PARSE_PRINT | BC_PARSE_REL)) | BC_PARSE_ARRAY;
- s = bc_parse_expr(p, flags, bc_parse_next_param);
+ s = zbc_parse_expr(p, flags, bc_parse_next_param);
if (s) return s;
comma = p->l.t.t == BC_LEX_COMMA;
*type = BC_INST_ARRAY_ELEM;
flags &= ~(BC_PARSE_PRINT | BC_PARSE_REL);
- s = bc_parse_expr(p, flags, bc_parse_next_elem);
+ s = zbc_parse_expr(p, flags, bc_parse_next_elem);
if (s) goto err;
}
s = zbc_lex_next(&p->l);
if (s) return s;
- s = bc_parse_expr(p, flags, bc_parse_next_rel);
+ s = zbc_parse_expr(p, flags, bc_parse_next_rel);
if (s) return s;
if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token();
s = zbc_lex_next(&p->l);
if (s) return s;
- s = bc_parse_expr(p, flags, bc_parse_next_rel);
+ s = zbc_parse_expr(p, flags, bc_parse_next_rel);
if (s) return s;
if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token();
bc_parse_push(p, BC_INST_SCALE_FUNC);
# define zbc_parse_string(...) (zbc_parse_string(__VA_ARGS__), BC_STATUS_SUCCESS)
#endif
-static BcStatus bc_parse_print(BcParse *p)
+static BC_STATUS zbc_parse_print(BcParse *p)
{
BcStatus s;
BcLexType type;
bool comma;
s = zbc_lex_next(&p->l);
- if (s) return s;
+ if (s) RETURN_STATUS(s);
type = p->l.t.t;
if (type == BC_LEX_SCOLON || type == BC_LEX_NLINE)
- return bc_error("bad print statement");
+ RETURN_STATUS(bc_error("bad print statement"));
comma = false;
while (type != BC_LEX_SCOLON && type != BC_LEX_NLINE) {
-
if (type == BC_LEX_STR) {
s = zbc_parse_string(p, BC_INST_PRINT_POP);
- if (s) return s;
+ if (s) RETURN_STATUS(s);
} else {
- s = bc_parse_expr(p, 0, bc_parse_next_print);
- if (s) return s;
+ s = zbc_parse_expr(p, 0, bc_parse_next_print);
+ if (s) RETURN_STATUS(s);
bc_parse_push(p, BC_INST_PRINT_POP);
}
comma = p->l.t.t == BC_LEX_COMMA;
if (comma) {
s = zbc_lex_next(&p->l);
- if (s) return s;
+ if (s) RETURN_STATUS(s);
}
type = p->l.t.t;
}
- if (comma) return bc_error_bad_token();
+ if (comma) RETURN_STATUS(bc_error_bad_token());
- return zbc_lex_next(&p->l);
+ RETURN_STATUS(zbc_lex_next(&p->l));
}
+#if ERRORS_ARE_FATAL
+# define zbc_parse_print(...) (zbc_parse_print(__VA_ARGS__), BC_STATUS_SUCCESS)
+#endif
-static BcStatus bc_parse_return(BcParse *p)
+static BC_STATUS zbc_parse_return(BcParse *p)
{
BcStatus s;
BcLexType t;
bool paren;
- if (!BC_PARSE_FUNC(p)) return bc_error_bad_token();
+ if (!BC_PARSE_FUNC(p)) RETURN_STATUS(bc_error_bad_token());
s = zbc_lex_next(&p->l);
- if (s) return s;
+ if (s) RETURN_STATUS(s);
t = p->l.t.t;
paren = t == BC_LEX_LPAREN;
if (t == BC_LEX_NLINE || t == BC_LEX_SCOLON)
bc_parse_push(p, BC_INST_RET0);
else {
-
s = bc_parse_expr_empty_ok(p, 0, bc_parse_next_expr);
if (s == BC_STATUS_PARSE_EMPTY_EXP) {
bc_parse_push(p, BC_INST_RET0);
s = zbc_lex_next(&p->l);
}
- if (s) return s;
+ if (s) RETURN_STATUS(s);
if (!paren || p->l.t.last != BC_LEX_RPAREN) {
s = bc_POSIX_requires("parentheses around return expressions");
- ERROR_RETURN(if (s) return s;)
+ ERROR_RETURN(if (s) RETURN_STATUS(s);)
}
bc_parse_push(p, BC_INST_RET);
}
- return s;
+ RETURN_STATUS(s);
}
+#if ERRORS_ARE_FATAL
+# define zbc_parse_return(...) (zbc_parse_return(__VA_ARGS__), BC_STATUS_SUCCESS)
+#endif
static BC_STATUS zbc_parse_endBody(BcParse *p, bool brace)
{
*flag_ptr = (*flag_ptr | BC_PARSE_FLAG_IF_END);
if (p->l.t.t == BC_LEX_KEY_ELSE)
- ERROR_RETURN(s =) zbc_parse_else(p);
+ s = zbc_parse_else(p);
}
else if (BC_PARSE_ELSE(p)) {
BcInstPtr *ip;
bc_vec_pop(&p->exits);
}
-static BcStatus bc_parse_if(BcParse *p)
+static BC_STATUS zbc_parse_if(BcParse *p)
{
BcStatus s;
BcInstPtr ip;
s = zbc_lex_next(&p->l);
- if (s) return s;
- if (p->l.t.t != BC_LEX_LPAREN) return bc_error_bad_token();
+ if (s) RETURN_STATUS(s);
+ if (p->l.t.t != BC_LEX_LPAREN) RETURN_STATUS(bc_error_bad_token());
s = zbc_lex_next(&p->l);
- if (s) return s;
- s = bc_parse_expr(p, BC_PARSE_REL, bc_parse_next_rel);
- if (s) return s;
- if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token();
+ if (s) RETURN_STATUS(s);
+ s = zbc_parse_expr(p, BC_PARSE_REL, bc_parse_next_rel);
+ if (s) RETURN_STATUS(s);
+ if (p->l.t.t != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token());
s = zbc_lex_next(&p->l);
- if (s) return s;
+ if (s) RETURN_STATUS(s);
bc_parse_push(p, BC_INST_JUMP_ZERO);
ip.idx = p->func->labels.len;
bc_vec_push(&p->func->labels, &ip.idx);
bc_parse_startBody(p, BC_PARSE_FLAG_IF);
- return BC_STATUS_SUCCESS;
+ RETURN_STATUS(BC_STATUS_SUCCESS);
}
+#if ERRORS_ARE_FATAL
+# define zbc_parse_if(...) (zbc_parse_if(__VA_ARGS__), BC_STATUS_SUCCESS)
+#endif
+#undef zbc_parse_else
static BC_STATUS zbc_parse_else(BcParse *p)
{
BcInstPtr ip;
# define zbc_parse_else(...) (zbc_parse_else(__VA_ARGS__), BC_STATUS_SUCCESS)
#endif
-static BcStatus bc_parse_while(BcParse *p)
+static BC_STATUS zbc_parse_while(BcParse *p)
{
BcStatus s;
BcInstPtr ip;
s = zbc_lex_next(&p->l);
- if (s) return s;
- if (p->l.t.t != BC_LEX_LPAREN) return bc_error_bad_token();
+ if (s) RETURN_STATUS(s);
+ if (p->l.t.t != BC_LEX_LPAREN) RETURN_STATUS(bc_error_bad_token());
s = zbc_lex_next(&p->l);
- if (s) return s;
+ if (s) RETURN_STATUS(s);
ip.idx = p->func->labels.len;
bc_vec_push(&p->exits, &ip);
bc_vec_push(&p->func->labels, &ip.idx);
- s = bc_parse_expr(p, BC_PARSE_REL, bc_parse_next_rel);
- if (s) return s;
- if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token();
+ s = zbc_parse_expr(p, BC_PARSE_REL, bc_parse_next_rel);
+ if (s) RETURN_STATUS(s);
+ if (p->l.t.t != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token());
s = zbc_lex_next(&p->l);
- if (s) return s;
+ if (s) RETURN_STATUS(s);
bc_parse_push(p, BC_INST_JUMP_ZERO);
bc_parse_pushIndex(p, ip.idx);
bc_parse_startBody(p, BC_PARSE_FLAG_LOOP | BC_PARSE_FLAG_LOOP_INNER);
- return BC_STATUS_SUCCESS;
+ RETURN_STATUS(BC_STATUS_SUCCESS);
}
+#if ERRORS_ARE_FATAL
+# define zbc_parse_while(...) (zbc_parse_while(__VA_ARGS__), BC_STATUS_SUCCESS)
+#endif
-static BcStatus bc_parse_for(BcParse *p)
+static BC_STATUS zbc_parse_for(BcParse *p)
{
BcStatus s;
BcInstPtr ip;
size_t cond_idx, exit_idx, body_idx, update_idx;
s = zbc_lex_next(&p->l);
- if (s) return s;
- if (p->l.t.t != BC_LEX_LPAREN) return bc_error_bad_token();
+ if (s) RETURN_STATUS(s);
+ if (p->l.t.t != BC_LEX_LPAREN) RETURN_STATUS(bc_error_bad_token());
s = zbc_lex_next(&p->l);
- if (s) return s;
+ if (s) RETURN_STATUS(s);
if (p->l.t.t != BC_LEX_SCOLON)
- s = bc_parse_expr(p, 0, bc_parse_next_for);
+ s = zbc_parse_expr(p, 0, bc_parse_next_for);
else
s = bc_POSIX_does_not_allow_empty_X_expression_in_for("init");
- if (s) return s;
- if (p->l.t.t != BC_LEX_SCOLON) return bc_error_bad_token();
+ if (s) RETURN_STATUS(s);
+ if (p->l.t.t != BC_LEX_SCOLON) RETURN_STATUS(bc_error_bad_token());
s = zbc_lex_next(&p->l);
- if (s) return s;
+ if (s) RETURN_STATUS(s);
cond_idx = p->func->labels.len;
update_idx = cond_idx + 1;
bc_vec_push(&p->func->labels, &p->func->code.len);
if (p->l.t.t != BC_LEX_SCOLON)
- s = bc_parse_expr(p, BC_PARSE_REL, bc_parse_next_for);
+ s = zbc_parse_expr(p, BC_PARSE_REL, bc_parse_next_for);
else
s = bc_POSIX_does_not_allow_empty_X_expression_in_for("condition");
- if (s) return s;
- if (p->l.t.t != BC_LEX_SCOLON) return bc_error_bad_token();
+ if (s) RETURN_STATUS(s);
+ if (p->l.t.t != BC_LEX_SCOLON) RETURN_STATUS(bc_error_bad_token());
s = zbc_lex_next(&p->l);
- if (s) return s;
+ if (s) RETURN_STATUS(s);
bc_parse_push(p, BC_INST_JUMP_ZERO);
bc_parse_pushIndex(p, exit_idx);
bc_vec_push(&p->func->labels, &p->func->code.len);
if (p->l.t.t != BC_LEX_RPAREN)
- s = bc_parse_expr(p, 0, bc_parse_next_rel);
+ s = zbc_parse_expr(p, 0, bc_parse_next_rel);
else
s = bc_POSIX_does_not_allow_empty_X_expression_in_for("update");
- if (s) return s;
+ if (s) RETURN_STATUS(s);
- if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token();
+ if (p->l.t.t != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token());
bc_parse_push(p, BC_INST_JUMP);
bc_parse_pushIndex(p, cond_idx);
bc_vec_push(&p->func->labels, &p->func->code.len);
bc_vec_push(&p->exits, &ip);
bc_vec_push(&p->func->labels, &ip.idx);
s = zbc_lex_next(&p->l);
- if (s) return s;
+ if (s) RETURN_STATUS(s);
bc_parse_startBody(p, BC_PARSE_FLAG_LOOP | BC_PARSE_FLAG_LOOP_INNER);
- return BC_STATUS_SUCCESS;
+ RETURN_STATUS(BC_STATUS_SUCCESS);
}
+#if ERRORS_ARE_FATAL
+# define zbc_parse_for(...) (zbc_parse_for(__VA_ARGS__), BC_STATUS_SUCCESS)
+#endif
static BC_STATUS zbc_parse_loopExit(BcParse *p, BcLexType type)
{
if (p->l.t.t == BC_LEX_NLINE) s = zbc_lex_next(&p->l);
}
else {
- s = bc_parse_stmt(p);
+ s = zbc_parse_stmt(p);
if (!s && !brace) s = zbc_parse_endBody(p, false);
}
# define zbc_parse_body(...) (zbc_parse_body(__VA_ARGS__), BC_STATUS_SUCCESS)
#endif
-static BcStatus bc_parse_stmt(BcParse *p)
+#undef zbc_parse_stmt
+static BC_STATUS zbc_parse_stmt(BcParse *p)
{
BcStatus s = BC_STATUS_SUCCESS;
switch (p->l.t.t) {
-
case BC_LEX_NLINE:
- {
- return zbc_lex_next(&p->l);
- }
+ RETURN_STATUS(zbc_lex_next(&p->l));
case BC_LEX_KEY_ELSE:
- {
p->auto_part = false;
break;
- }
case BC_LEX_LBRACE:
- {
- if (!BC_PARSE_BODY(p)) return bc_error_bad_token();
-
+ if (!BC_PARSE_BODY(p)) RETURN_STATUS(bc_error_bad_token());
++p->nbraces;
s = zbc_lex_next(&p->l);
- if (s) return s;
-
- return zbc_parse_body(p, true);
- }
+ if (s) RETURN_STATUS(s);
+ RETURN_STATUS(zbc_parse_body(p, true));
case BC_LEX_KEY_AUTO:
- {
- return zbc_parse_auto(p);
- }
+ RETURN_STATUS(zbc_parse_auto(p));
default:
- {
p->auto_part = false;
-
if (BC_PARSE_IF_END(p)) {
bc_parse_noElse(p);
- return BC_STATUS_SUCCESS;
+ RETURN_STATUS(BC_STATUS_SUCCESS);
}
- else if (BC_PARSE_BODY(p))
- return zbc_parse_body(p, false);
-
+ if (BC_PARSE_BODY(p))
+ RETURN_STATUS(zbc_parse_body(p, false));
break;
- }
}
switch (p->l.t.t) {
-
case BC_LEX_OP_INC:
case BC_LEX_OP_DEC:
case BC_LEX_OP_MINUS:
case BC_LEX_KEY_READ:
case BC_LEX_KEY_SCALE:
case BC_LEX_KEY_SQRT:
- {
- s = bc_parse_expr(p, BC_PARSE_PRINT, bc_parse_next_expr);
+ s = zbc_parse_expr(p, BC_PARSE_PRINT, bc_parse_next_expr);
break;
- }
-
case BC_LEX_KEY_ELSE:
- {
s = zbc_parse_else(p);
break;
- }
-
case BC_LEX_SCOLON:
- {
while (!s && p->l.t.t == BC_LEX_SCOLON) s = zbc_lex_next(&p->l);
break;
- }
-
case BC_LEX_RBRACE:
- {
s = zbc_parse_endBody(p, true);
break;
- }
-
case BC_LEX_STR:
- {
s = zbc_parse_string(p, BC_INST_PRINT_STR);
break;
- }
-
case BC_LEX_KEY_BREAK:
case BC_LEX_KEY_CONTINUE:
- {
s = zbc_parse_loopExit(p, p->l.t.t);
break;
- }
-
case BC_LEX_KEY_FOR:
- {
- s = bc_parse_for(p);
+ s = zbc_parse_for(p);
break;
- }
-
case BC_LEX_KEY_HALT:
- {
bc_parse_push(p, BC_INST_HALT);
s = zbc_lex_next(&p->l);
break;
- }
-
case BC_LEX_KEY_IF:
- {
- s = bc_parse_if(p);
+ s = zbc_parse_if(p);
break;
- }
-
case BC_LEX_KEY_LIMITS:
- {
// "limits" is a compile-time command,
// the output is produced at _parse time_.
s = zbc_lex_next(&p->l);
- if (s) return s;
+ if (s) RETURN_STATUS(s);
printf(
"BC_BASE_MAX = "BC_MAX_OBASE_STR "\n"
"BC_DIM_MAX = "BC_MAX_DIM_STR "\n"
"Number of vars = "BC_MAX_VARS_STR "\n"
);
break;
- }
-
case BC_LEX_KEY_PRINT:
- {
- s = bc_parse_print(p);
+ s = zbc_parse_print(p);
break;
- }
-
case BC_LEX_KEY_QUIT:
- {
// "quit" is a compile-time command. For example,
// "if (0 == 1) quit" terminates when parsing the statement,
// not when it is executed
QUIT_OR_RETURN_TO_MAIN;
- }
-
case BC_LEX_KEY_RETURN:
- {
- s = bc_parse_return(p);
+ s = zbc_parse_return(p);
break;
- }
-
case BC_LEX_KEY_WHILE:
- {
- s = bc_parse_while(p);
+ s = zbc_parse_while(p);
break;
- }
-
default:
- {
s = bc_error_bad_token();
break;
- }
}
- return s;
+ RETURN_STATUS(s);
}
+#if ERRORS_ARE_FATAL
+# define zbc_parse_stmt(...) (zbc_parse_stmt(__VA_ARGS__), BC_STATUS_SUCCESS)
+#endif
static FAST_FUNC BcStatus bc_parse_parse(BcParse *p)
{
s = zbc_parse_func(p);
}
else
- s = bc_parse_stmt(p);
+ s = zbc_parse_stmt(p);
if (s || G_interrupt) {
bc_parse_reset(p);
return s;
}
-static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next)
+#undef zbc_parse_expr
+static BC_STATUS zbc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next)
{
BcStatus s;
s = bc_parse_expr_empty_ok(p, flags, next);
if (s == BC_STATUS_PARSE_EMPTY_EXP)
- return bc_error("empty expression");
- return s;
+ RETURN_STATUS(bc_error("empty expression"));
+ RETURN_STATUS(s);
}
+#if ERRORS_ARE_FATAL
+# define zbc_parse_expr(...) (zbc_parse_expr(__VA_ARGS__), BC_STATUS_SUCCESS)
+#endif
static void bc_parse_init(BcParse *p, size_t func)
{
bc_parse_create(p, func, bc_parse_parse, zbc_lex_token);
}
-static BcStatus bc_parse_expression(BcParse *p, uint8_t flags)
+static BC_STATUS zbc_parse_expression(BcParse *p, uint8_t flags)
{
- return bc_parse_expr(p, flags, bc_parse_next_read);
+ RETURN_STATUS(zbc_parse_expr(p, flags, bc_parse_next_read));
}
+#if ERRORS_ARE_FATAL
+# define zbc_parse_expression(...) (zbc_parse_expression(__VA_ARGS__), BC_STATUS_SUCCESS)
+#endif
#endif // ENABLE_BC
}
}
-static BcStatus common_parse_expr(BcParse *p, uint8_t flags)
+static BC_STATUS zcommon_parse_expr(BcParse *p, uint8_t flags)
{
if (IS_BC) {
- IF_BC(return bc_parse_expression(p, flags);)
+ IF_BC(RETURN_STATUS(zbc_parse_expression(p, flags));)
} else {
- IF_DC(return zdc_parse_expr(p, flags);)
+ IF_DC(RETURN_STATUS(zdc_parse_expr(p, flags));)
}
}
+#if ERRORS_ARE_FATAL
+# define zcommon_parse_expr(...) (zcommon_parse_expr(__VA_ARGS__), BC_STATUS_SUCCESS)
+#endif
static BcVec* bc_program_search(char *id, bool var)
{
s = bc_parse_text(&parse, buf.v);
if (s) goto exec_err;
- s = common_parse_expr(&parse, BC_PARSE_NOREAD);
+ s = zcommon_parse_expr(&parse, BC_PARSE_NOREAD);
if (s) goto exec_err;
if (parse.l.t.t != BC_LEX_NLINE && parse.l.t.t != BC_LEX_EOF) {
common_parse_init(&prs, fidx);
s = bc_parse_text(&prs, *str);
if (s) goto err;
- s = common_parse_expr(&prs, BC_PARSE_NOCALL);
+ s = zcommon_parse_expr(&prs, BC_PARSE_NOCALL);
if (s) goto err;
if (prs.l.t.t != BC_LEX_EOF) {