aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-12-25 20:40:55 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-12-25 20:40:55 +0100
commita2e62e3e505aad4af81018f385d86d35e6485641 (patch)
treeac442a36d273090e34ee8e9f99c519a7d9d04419
parent1fbe35a7d8579d53df0f4f70b31ba8b272099b7c (diff)
downloadbusybox-w32-a2e62e3e505aad4af81018f385d86d35e6485641.tar.gz
busybox-w32-a2e62e3e505aad4af81018f385d86d35e6485641.tar.bz2
busybox-w32-a2e62e3e505aad4af81018f385d86d35e6485641.zip
bc: stop passing a pointer to G.prs down the call chain
function old new delta rewrite_label_to_current 19 26 +7 bc_lex_assign 28 35 +7 zbc_lex_skip_if_at_NLINE 14 19 +5 bc_parse_push 11 16 +5 bc_parse_operator 147 152 +5 bc_parse_create 92 97 +5 bc_lex_whitespace 38 43 +5 bc_lex_name 66 71 +5 bc_lex_lineComment 33 38 +5 zbc_lex_number 174 178 +4 zbc_parse_text_init 53 56 +3 zdc_parse_register 43 45 +2 zdc_parse_exprs_until_eof 26 28 +2 bc_parse_free 38 40 +2 bc_lex_file 28 27 -1 zbc_parse_pushSTR 65 63 -2 bc_parse_expr_empty_ok 1778 1776 -2 zbc_vm_execute_FILE 55 52 -3 bc_vm_init 678 675 -3 zbc_parse_stmt_allow_NLINE_before 59 55 -4 bc_parse_pushNUM 80 74 -6 bc_parse_pushJUMP_ZERO 27 21 -6 bc_parse_pushJUMP 27 21 -6 bc_vm_run 112 104 -8 bc_parse_pushName 39 31 -8 bc_parse_pushIndex 60 52 -8 zbc_parse_name 468 453 -15 zdc_program_execStr 524 501 -23 zdc_parse_mem 93 70 -23 zbc_program_exec 4003 3967 -36 zdc_parse_expr 518 476 -42 zbc_vm_process 923 878 -45 zbc_lex_next 2158 2070 -88 zbc_parse_stmt_possibly_auto 1560 1451 -109 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 14/20 up/down: 62/-438) Total: -376 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--miscutils/bc.c701
1 files changed, 374 insertions, 327 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c
index 0fdb2963c..75201f5f0 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -2748,8 +2748,9 @@ static BC_STATUS zbc_num_parse(BcNum *n, const char *val, unsigned base_t)
2748} 2748}
2749#define zbc_num_parse(...) (zbc_num_parse(__VA_ARGS__) COMMA_SUCCESS) 2749#define zbc_num_parse(...) (zbc_num_parse(__VA_ARGS__) COMMA_SUCCESS)
2750 2750
2751static void bc_lex_lineComment(BcLex *l) 2751static void bc_lex_lineComment(void)
2752{ 2752{
2753 BcLex *l = &G.prs.l;
2753 // Try: echo -n '#foo' | bc 2754 // Try: echo -n '#foo' | bc
2754 size_t i; 2755 size_t i;
2755 l->lex = XC_LEX_WHITESPACE; 2756 l->lex = XC_LEX_WHITESPACE;
@@ -2759,8 +2760,9 @@ static void bc_lex_lineComment(BcLex *l)
2759 l->i = i; 2760 l->i = i;
2760} 2761}
2761 2762
2762static void bc_lex_whitespace(BcLex *l) 2763static void bc_lex_whitespace(void)
2763{ 2764{
2765 BcLex *l = &G.prs.l;
2764 l->lex = XC_LEX_WHITESPACE; 2766 l->lex = XC_LEX_WHITESPACE;
2765 for (;;) { 2767 for (;;) {
2766 char c = l->buf[l->i]; 2768 char c = l->buf[l->i];
@@ -2772,8 +2774,9 @@ static void bc_lex_whitespace(BcLex *l)
2772 } 2774 }
2773} 2775}
2774 2776
2775static BC_STATUS zbc_lex_number(BcLex *l, char start) 2777static BC_STATUS zbc_lex_number(char start)
2776{ 2778{
2779 BcLex *l = &G.prs.l;
2777 const char *buf = l->buf + l->i; 2780 const char *buf = l->buf + l->i;
2778 size_t len, i, ccnt; 2781 size_t len, i, ccnt;
2779 bool pt; 2782 bool pt;
@@ -2842,8 +2845,9 @@ static BC_STATUS zbc_lex_number(BcLex *l, char start)
2842} 2845}
2843#define zbc_lex_number(...) (zbc_lex_number(__VA_ARGS__) COMMA_SUCCESS) 2846#define zbc_lex_number(...) (zbc_lex_number(__VA_ARGS__) COMMA_SUCCESS)
2844 2847
2845static void bc_lex_name(BcLex *l) 2848static void bc_lex_name(void)
2846{ 2849{
2850 BcLex *l = &G.prs.l;
2847 size_t i; 2851 size_t i;
2848 const char *buf; 2852 const char *buf;
2849 2853
@@ -2872,24 +2876,25 @@ static void bc_lex_name(BcLex *l)
2872 //return BC_STATUS_SUCCESS; 2876 //return BC_STATUS_SUCCESS;
2873} 2877}
2874 2878
2875static void bc_lex_init(BcLex *l) 2879static void bc_lex_init(void)
2876{ 2880{
2877 bc_char_vec_init(&l->lex_buf); 2881 bc_char_vec_init(&G.prs.l.lex_buf);
2878} 2882}
2879 2883
2880static void bc_lex_free(BcLex *l) 2884static void bc_lex_free(void)
2881{ 2885{
2882 bc_vec_free(&l->lex_buf); 2886 bc_vec_free(&G.prs.l.lex_buf);
2883} 2887}
2884 2888
2885static void bc_lex_file(BcLex *l) 2889static void bc_lex_file(void)
2886{ 2890{
2887 G.err_line = l->line = 1; 2891 G.err_line = G.prs.l.line = 1;
2888 l->newline = false; 2892 G.prs.l.newline = false;
2889} 2893}
2890 2894
2891static bool bc_lex_more_input(BcLex *l) 2895static bool bc_lex_more_input(void)
2892{ 2896{
2897 BcLex *l = &G.prs.l;
2893 size_t str; 2898 size_t str;
2894 bool comment; 2899 bool comment;
2895 2900
@@ -2960,13 +2965,14 @@ static bool bc_lex_more_input(BcLex *l)
2960 return l->len != 0; 2965 return l->len != 0;
2961} 2966}
2962 2967
2963IF_BC(static BC_STATUS zbc_lex_token(BcLex *l);) 2968IF_BC(static BC_STATUS zbc_lex_token(void);)
2964IF_DC(static BC_STATUS zdc_lex_token(BcLex *l);) 2969IF_DC(static BC_STATUS zdc_lex_token(void);)
2965#define zbc_lex_token(...) (zbc_lex_token(__VA_ARGS__) COMMA_SUCCESS) 2970#define zbc_lex_token(...) (zbc_lex_token(__VA_ARGS__) COMMA_SUCCESS)
2966#define zdc_lex_token(...) (zdc_lex_token(__VA_ARGS__) COMMA_SUCCESS) 2971#define zdc_lex_token(...) (zdc_lex_token(__VA_ARGS__) COMMA_SUCCESS)
2967 2972
2968static BC_STATUS zbc_lex_next(BcLex *l) 2973static BC_STATUS zbc_lex_next(void)
2969{ 2974{
2975 BcLex *l = &G.prs.l;
2970 BcStatus s; 2976 BcStatus s;
2971 2977
2972 l->lex_last = l->lex; 2978 l->lex_last = l->lex;
@@ -2985,7 +2991,7 @@ static BC_STATUS zbc_lex_next(BcLex *l)
2985 l->lex = XC_LEX_EOF; 2991 l->lex = XC_LEX_EOF;
2986 if (!G.prs.input_fp) 2992 if (!G.prs.input_fp)
2987 RETURN_STATUS(BC_STATUS_SUCCESS); 2993 RETURN_STATUS(BC_STATUS_SUCCESS);
2988 if (!bc_lex_more_input(l)) { 2994 if (!bc_lex_more_input()) {
2989 G.prs.input_fp = NULL; 2995 G.prs.input_fp = NULL;
2990 RETURN_STATUS(BC_STATUS_SUCCESS); 2996 RETURN_STATUS(BC_STATUS_SUCCESS);
2991 } 2997 }
@@ -2997,9 +3003,9 @@ static BC_STATUS zbc_lex_next(BcLex *l)
2997 l->lex_next_at 3003 l->lex_next_at
2998 ); 3004 );
2999 if (IS_BC) { 3005 if (IS_BC) {
3000 IF_BC(s = zbc_lex_token(l)); 3006 IF_BC(s = zbc_lex_token());
3001 } else { 3007 } else {
3002 IF_DC(s = zdc_lex_token(l)); 3008 IF_DC(s = zdc_lex_token());
3003 } 3009 }
3004 } while (!s && l->lex == XC_LEX_WHITESPACE); 3010 } while (!s && l->lex == XC_LEX_WHITESPACE);
3005 dbg_lex("l->lex from string:%d", l->lex); 3011 dbg_lex("l->lex from string:%d", l->lex);
@@ -3009,39 +3015,40 @@ static BC_STATUS zbc_lex_next(BcLex *l)
3009#define zbc_lex_next(...) (zbc_lex_next(__VA_ARGS__) COMMA_SUCCESS) 3015#define zbc_lex_next(...) (zbc_lex_next(__VA_ARGS__) COMMA_SUCCESS)
3010 3016
3011#if ENABLE_BC 3017#if ENABLE_BC
3012static BC_STATUS zbc_lex_skip_if_at_NLINE(BcLex *l) 3018static BC_STATUS zbc_lex_skip_if_at_NLINE(void)
3013{ 3019{
3014 if (l->lex == XC_LEX_NLINE) 3020 if (G.prs.l.lex == XC_LEX_NLINE)
3015 RETURN_STATUS(zbc_lex_next(l)); 3021 RETURN_STATUS(zbc_lex_next());
3016 RETURN_STATUS(BC_STATUS_SUCCESS); 3022 RETURN_STATUS(BC_STATUS_SUCCESS);
3017} 3023}
3018#define zbc_lex_skip_if_at_NLINE(...) (zbc_lex_skip_if_at_NLINE(__VA_ARGS__) COMMA_SUCCESS) 3024#define zbc_lex_skip_if_at_NLINE(...) (zbc_lex_skip_if_at_NLINE(__VA_ARGS__) COMMA_SUCCESS)
3019 3025
3020static BC_STATUS zbc_lex_next_and_skip_NLINE(BcLex *l) 3026static BC_STATUS zbc_lex_next_and_skip_NLINE(void)
3021{ 3027{
3022 BcStatus s; 3028 BcStatus s;
3023 s = zbc_lex_next(l); 3029 s = zbc_lex_next();
3024 if (s) RETURN_STATUS(s); 3030 if (s) RETURN_STATUS(s);
3025 // if(cond)<newline>stmt is accepted too (but not 2+ newlines) 3031 // if(cond)<newline>stmt is accepted too (but not 2+ newlines)
3026 s = zbc_lex_skip_if_at_NLINE(l); 3032 s = zbc_lex_skip_if_at_NLINE();
3027 RETURN_STATUS(s); 3033 RETURN_STATUS(s);
3028} 3034}
3029#define zbc_lex_next_and_skip_NLINE(...) (zbc_lex_next_and_skip_NLINE(__VA_ARGS__) COMMA_SUCCESS) 3035#define zbc_lex_next_and_skip_NLINE(...) (zbc_lex_next_and_skip_NLINE(__VA_ARGS__) COMMA_SUCCESS)
3030#endif 3036#endif
3031 3037
3032static BC_STATUS zbc_lex_text_init(BcLex *l, const char *text) 3038static BC_STATUS zbc_lex_text_init(const char *text)
3033{ 3039{
3034 l->buf = text; 3040 G.prs.l.buf = text;
3035 l->i = 0; 3041 G.prs.l.i = 0;
3036 l->len = strlen(text); 3042 G.prs.l.len = strlen(text);
3037 l->lex = l->lex_last = XC_LEX_INVALID; 3043 G.prs.l.lex = G.prs.l.lex_last = XC_LEX_INVALID;
3038 RETURN_STATUS(zbc_lex_next(l)); 3044 RETURN_STATUS(zbc_lex_next());
3039} 3045}
3040#define zbc_lex_text_init(...) (zbc_lex_text_init(__VA_ARGS__) COMMA_SUCCESS) 3046#define zbc_lex_text_init(...) (zbc_lex_text_init(__VA_ARGS__) COMMA_SUCCESS)
3041 3047
3042#if ENABLE_BC 3048#if ENABLE_BC
3043static BC_STATUS zbc_lex_identifier(BcLex *l) 3049static BC_STATUS zbc_lex_identifier(void)
3044{ 3050{
3051 BcLex *l = &G.prs.l;
3045 BcStatus s; 3052 BcStatus s;
3046 unsigned i; 3053 unsigned i;
3047 const char *buf = l->buf + l->i - 1; 3054 const char *buf = l->buf + l->i - 1;
@@ -3070,7 +3077,7 @@ static BC_STATUS zbc_lex_identifier(BcLex *l)
3070 RETURN_STATUS(BC_STATUS_SUCCESS); 3077 RETURN_STATUS(BC_STATUS_SUCCESS);
3071 } 3078 }
3072 3079
3073 bc_lex_name(l); 3080 bc_lex_name();
3074 s = BC_STATUS_SUCCESS; 3081 s = BC_STATUS_SUCCESS;
3075 3082
3076 if (l->lex_buf.len > 2) { 3083 if (l->lex_buf.len > 2) {
@@ -3086,8 +3093,9 @@ static BC_STATUS zbc_lex_identifier(BcLex *l)
3086} 3093}
3087#define zbc_lex_identifier(...) (zbc_lex_identifier(__VA_ARGS__) COMMA_SUCCESS) 3094#define zbc_lex_identifier(...) (zbc_lex_identifier(__VA_ARGS__) COMMA_SUCCESS)
3088 3095
3089static BC_STATUS zbc_lex_string(BcLex *l) 3096static BC_STATUS zbc_lex_string(void)
3090{ 3097{
3098 BcLex *l = &G.prs.l;
3091 size_t len, nls, i; 3099 size_t len, nls, i;
3092 3100
3093 l->lex = XC_LEX_STR; 3101 l->lex = XC_LEX_STR;
@@ -3122,19 +3130,21 @@ static BC_STATUS zbc_lex_string(BcLex *l)
3122} 3130}
3123#define zbc_lex_string(...) (zbc_lex_string(__VA_ARGS__) COMMA_SUCCESS) 3131#define zbc_lex_string(...) (zbc_lex_string(__VA_ARGS__) COMMA_SUCCESS)
3124 3132
3125static void bc_lex_assign(BcLex *l, unsigned with_and_without) 3133static void bc_lex_assign(unsigned with_and_without)
3126{ 3134{
3135 BcLex *l = &G.prs.l;
3127 if (l->buf[l->i] == '=') { 3136 if (l->buf[l->i] == '=') {
3128 ++l->i; 3137 ++l->i;
3129 with_and_without >>= 8; // store "with" value 3138 with_and_without >>= 8; // store "with" value
3130 } // else store "without" value 3139 } // else store "without" value
3131 l->lex = (with_and_without & 0xff); 3140 l->lex = (with_and_without & 0xff);
3132} 3141}
3133#define bc_lex_assign(l, with, without) \ 3142#define bc_lex_assign(with, without) \
3134 bc_lex_assign(l, ((with)<<8)|(without)) 3143 bc_lex_assign(((with)<<8)|(without))
3135 3144
3136static BC_STATUS zbc_lex_comment(BcLex *l) 3145static BC_STATUS zbc_lex_comment(void)
3137{ 3146{
3147 BcLex *l = &G.prs.l;
3138 size_t i, nls = 0; 3148 size_t i, nls = 0;
3139 const char *buf = l->buf; 3149 const char *buf = l->buf;
3140 3150
@@ -3165,8 +3175,9 @@ static BC_STATUS zbc_lex_comment(BcLex *l)
3165#define zbc_lex_comment(...) (zbc_lex_comment(__VA_ARGS__) COMMA_SUCCESS) 3175#define zbc_lex_comment(...) (zbc_lex_comment(__VA_ARGS__) COMMA_SUCCESS)
3166 3176
3167#undef zbc_lex_token 3177#undef zbc_lex_token
3168static BC_STATUS zbc_lex_token(BcLex *l) 3178static BC_STATUS zbc_lex_token(void)
3169{ 3179{
3180 BcLex *l = &G.prs.l;
3170 BcStatus s = BC_STATUS_SUCCESS; 3181 BcStatus s = BC_STATUS_SUCCESS;
3171 char c = l->buf[l->i++], c2; 3182 char c = l->buf[l->i++], c2;
3172 3183
@@ -3186,25 +3197,25 @@ static BC_STATUS zbc_lex_token(BcLex *l)
3186 case '\f': 3197 case '\f':
3187 case '\r': 3198 case '\r':
3188 case ' ': 3199 case ' ':
3189 bc_lex_whitespace(l); 3200 bc_lex_whitespace();
3190 break; 3201 break;
3191 case '!': 3202 case '!':
3192 bc_lex_assign(l, XC_LEX_OP_REL_NE, BC_LEX_OP_BOOL_NOT); 3203 bc_lex_assign(XC_LEX_OP_REL_NE, BC_LEX_OP_BOOL_NOT);
3193 if (l->lex == BC_LEX_OP_BOOL_NOT) { 3204 if (l->lex == BC_LEX_OP_BOOL_NOT) {
3194 s = zbc_POSIX_does_not_allow_bool_ops_this_is_bad("!"); 3205 s = zbc_POSIX_does_not_allow_bool_ops_this_is_bad("!");
3195 if (s) RETURN_STATUS(s); 3206 if (s) RETURN_STATUS(s);
3196 } 3207 }
3197 break; 3208 break;
3198 case '"': 3209 case '"':
3199 s = zbc_lex_string(l); 3210 s = zbc_lex_string();
3200 break; 3211 break;
3201 case '#': 3212 case '#':
3202 s = zbc_POSIX_does_not_allow("'#' script comments"); 3213 s = zbc_POSIX_does_not_allow("'#' script comments");
3203 if (s) RETURN_STATUS(s); 3214 if (s) RETURN_STATUS(s);
3204 bc_lex_lineComment(l); 3215 bc_lex_lineComment();
3205 break; 3216 break;
3206 case '%': 3217 case '%':
3207 bc_lex_assign(l, BC_LEX_OP_ASSIGN_MODULUS, XC_LEX_OP_MODULUS); 3218 bc_lex_assign(BC_LEX_OP_ASSIGN_MODULUS, XC_LEX_OP_MODULUS);
3208 break; 3219 break;
3209 case '&': 3220 case '&':
3210 c2 = l->buf[l->i]; 3221 c2 = l->buf[l->i];
@@ -3223,7 +3234,7 @@ static BC_STATUS zbc_lex_token(BcLex *l)
3223 l->lex = (BcLexType)(c - '(' + BC_LEX_LPAREN); 3234 l->lex = (BcLexType)(c - '(' + BC_LEX_LPAREN);
3224 break; 3235 break;
3225 case '*': 3236 case '*':
3226 bc_lex_assign(l, BC_LEX_OP_ASSIGN_MULTIPLY, XC_LEX_OP_MULTIPLY); 3237 bc_lex_assign(BC_LEX_OP_ASSIGN_MULTIPLY, XC_LEX_OP_MULTIPLY);
3227 break; 3238 break;
3228 case '+': 3239 case '+':
3229 c2 = l->buf[l->i]; 3240 c2 = l->buf[l->i];
@@ -3231,7 +3242,7 @@ static BC_STATUS zbc_lex_token(BcLex *l)
3231 ++l->i; 3242 ++l->i;
3232 l->lex = BC_LEX_OP_INC; 3243 l->lex = BC_LEX_OP_INC;
3233 } else 3244 } else
3234 bc_lex_assign(l, BC_LEX_OP_ASSIGN_PLUS, XC_LEX_OP_PLUS); 3245 bc_lex_assign(BC_LEX_OP_ASSIGN_PLUS, XC_LEX_OP_PLUS);
3235 break; 3246 break;
3236 case ',': 3247 case ',':
3237 l->lex = BC_LEX_COMMA; 3248 l->lex = BC_LEX_COMMA;
@@ -3242,11 +3253,11 @@ static BC_STATUS zbc_lex_token(BcLex *l)
3242 ++l->i; 3253 ++l->i;
3243 l->lex = BC_LEX_OP_DEC; 3254 l->lex = BC_LEX_OP_DEC;
3244 } else 3255 } else
3245 bc_lex_assign(l, BC_LEX_OP_ASSIGN_MINUS, XC_LEX_OP_MINUS); 3256 bc_lex_assign(BC_LEX_OP_ASSIGN_MINUS, XC_LEX_OP_MINUS);
3246 break; 3257 break;
3247 case '.': 3258 case '.':
3248 if (isdigit(l->buf[l->i])) 3259 if (isdigit(l->buf[l->i]))
3249 s = zbc_lex_number(l, c); 3260 s = zbc_lex_number(c);
3250 else { 3261 else {
3251 l->lex = BC_LEX_KEY_LAST; 3262 l->lex = BC_LEX_KEY_LAST;
3252 s = zbc_POSIX_does_not_allow("a period ('.') as a shortcut for the last result"); 3263 s = zbc_POSIX_does_not_allow("a period ('.') as a shortcut for the last result");
@@ -3255,9 +3266,9 @@ static BC_STATUS zbc_lex_token(BcLex *l)
3255 case '/': 3266 case '/':
3256 c2 = l->buf[l->i]; 3267 c2 = l->buf[l->i];
3257 if (c2 == '*') 3268 if (c2 == '*')
3258 s = zbc_lex_comment(l); 3269 s = zbc_lex_comment();
3259 else 3270 else
3260 bc_lex_assign(l, BC_LEX_OP_ASSIGN_DIVIDE, XC_LEX_OP_DIVIDE); 3271 bc_lex_assign(BC_LEX_OP_ASSIGN_DIVIDE, XC_LEX_OP_DIVIDE);
3261 break; 3272 break;
3262 case '0': 3273 case '0':
3263 case '1': 3274 case '1':
@@ -3275,19 +3286,19 @@ static BC_STATUS zbc_lex_token(BcLex *l)
3275 case 'D': 3286 case 'D':
3276 case 'E': 3287 case 'E':
3277 case 'F': 3288 case 'F':
3278 s = zbc_lex_number(l, c); 3289 s = zbc_lex_number(c);
3279 break; 3290 break;
3280 case ';': 3291 case ';':
3281 l->lex = BC_LEX_SCOLON; 3292 l->lex = BC_LEX_SCOLON;
3282 break; 3293 break;
3283 case '<': 3294 case '<':
3284 bc_lex_assign(l, XC_LEX_OP_REL_LE, XC_LEX_OP_REL_LT); 3295 bc_lex_assign(XC_LEX_OP_REL_LE, XC_LEX_OP_REL_LT);
3285 break; 3296 break;
3286 case '=': 3297 case '=':
3287 bc_lex_assign(l, XC_LEX_OP_REL_EQ, BC_LEX_OP_ASSIGN); 3298 bc_lex_assign(XC_LEX_OP_REL_EQ, BC_LEX_OP_ASSIGN);
3288 break; 3299 break;
3289 case '>': 3300 case '>':
3290 bc_lex_assign(l, XC_LEX_OP_REL_GE, XC_LEX_OP_REL_GT); 3301 bc_lex_assign(XC_LEX_OP_REL_GE, XC_LEX_OP_REL_GT);
3291 break; 3302 break;
3292 case '[': 3303 case '[':
3293 case ']': 3304 case ']':
@@ -3301,7 +3312,7 @@ static BC_STATUS zbc_lex_token(BcLex *l)
3301 s = bc_error_bad_character(c); 3312 s = bc_error_bad_character(c);
3302 break; 3313 break;
3303 case '^': 3314 case '^':
3304 bc_lex_assign(l, BC_LEX_OP_ASSIGN_POWER, XC_LEX_OP_POWER); 3315 bc_lex_assign(BC_LEX_OP_ASSIGN_POWER, XC_LEX_OP_POWER);
3305 break; 3316 break;
3306 case 'a': 3317 case 'a':
3307 case 'b': 3318 case 'b':
@@ -3329,7 +3340,7 @@ static BC_STATUS zbc_lex_token(BcLex *l)
3329 case 'x': 3340 case 'x':
3330 case 'y': 3341 case 'y':
3331 case 'z': 3342 case 'z':
3332 s = zbc_lex_identifier(l); 3343 s = zbc_lex_identifier();
3333 break; 3344 break;
3334 case '{': 3345 case '{':
3335 case '}': 3346 case '}':
@@ -3359,12 +3370,13 @@ static BC_STATUS zbc_lex_token(BcLex *l)
3359#endif // ENABLE_BC 3370#endif // ENABLE_BC
3360 3371
3361#if ENABLE_DC 3372#if ENABLE_DC
3362static BC_STATUS zdc_lex_register(BcLex *l) 3373static BC_STATUS zdc_lex_register(void)
3363{ 3374{
3375 BcLex *l = &G.prs.l;
3364 if (G_exreg && isspace(l->buf[l->i])) { 3376 if (G_exreg && isspace(l->buf[l->i])) {
3365 bc_lex_whitespace(l); // eats whitespace (but not newline) 3377 bc_lex_whitespace(); // eats whitespace (but not newline)
3366 l->i++; // bc_lex_name() expects this 3378 l->i++; // bc_lex_name() expects this
3367 bc_lex_name(l); 3379 bc_lex_name();
3368 } else { 3380 } else {
3369 bc_vec_pop_all(&l->lex_buf); 3381 bc_vec_pop_all(&l->lex_buf);
3370 bc_vec_push(&l->lex_buf, &l->buf[l->i++]); 3382 bc_vec_push(&l->lex_buf, &l->buf[l->i++]);
@@ -3376,8 +3388,9 @@ static BC_STATUS zdc_lex_register(BcLex *l)
3376} 3388}
3377#define zdc_lex_register(...) (zdc_lex_register(__VA_ARGS__) COMMA_SUCCESS) 3389#define zdc_lex_register(...) (zdc_lex_register(__VA_ARGS__) COMMA_SUCCESS)
3378 3390
3379static BC_STATUS zdc_lex_string(BcLex *l) 3391static BC_STATUS zdc_lex_string(void)
3380{ 3392{
3393 BcLex *l = &G.prs.l;
3381 size_t depth, nls, i; 3394 size_t depth, nls, i;
3382 3395
3383 l->lex = XC_LEX_STR; 3396 l->lex = XC_LEX_STR;
@@ -3420,8 +3433,9 @@ static BC_STATUS zdc_lex_string(BcLex *l)
3420#define zdc_lex_string(...) (zdc_lex_string(__VA_ARGS__) COMMA_SUCCESS) 3433#define zdc_lex_string(...) (zdc_lex_string(__VA_ARGS__) COMMA_SUCCESS)
3421 3434
3422#undef zdc_lex_token 3435#undef zdc_lex_token
3423static BC_STATUS zdc_lex_token(BcLex *l) 3436static BC_STATUS zdc_lex_token(void)
3424{ 3437{
3438 BcLex *l = &G.prs.l;
3425 static const //BcLexType - should be this type, but narrower type saves size: 3439 static const //BcLexType - should be this type, but narrower type saves size:
3426 uint8_t 3440 uint8_t
3427 dc_lex_regs[] = { 3441 dc_lex_regs[] = {
@@ -3437,7 +3451,7 @@ static BC_STATUS zdc_lex_token(BcLex *l)
3437 3451
3438 for (i = 0; i < ARRAY_SIZE(dc_lex_regs); ++i) { 3452 for (i = 0; i < ARRAY_SIZE(dc_lex_regs); ++i) {
3439 if (l->lex_last == dc_lex_regs[i]) 3453 if (l->lex_last == dc_lex_regs[i])
3440 RETURN_STATUS(zdc_lex_register(l)); 3454 RETURN_STATUS(zdc_lex_register());
3441 } 3455 }
3442 3456
3443 s = BC_STATUS_SUCCESS; 3457 s = BC_STATUS_SUCCESS;
@@ -3471,7 +3485,7 @@ static BC_STATUS zdc_lex_token(BcLex *l)
3471 case '\r': 3485 case '\r':
3472 case ' ': 3486 case ' ':
3473 l->newline = 0; // was (c == '\n') 3487 l->newline = 0; // was (c == '\n')
3474 bc_lex_whitespace(l); 3488 bc_lex_whitespace();
3475 break; 3489 break;
3476 case '!': 3490 case '!':
3477 c2 = l->buf[l->i]; 3491 c2 = l->buf[l->i];
@@ -3486,11 +3500,11 @@ static BC_STATUS zdc_lex_token(BcLex *l)
3486 ++l->i; 3500 ++l->i;
3487 break; 3501 break;
3488 case '#': 3502 case '#':
3489 bc_lex_lineComment(l); 3503 bc_lex_lineComment();
3490 break; 3504 break;
3491 case '.': 3505 case '.':
3492 if (isdigit(l->buf[l->i])) 3506 if (isdigit(l->buf[l->i]))
3493 s = zbc_lex_number(l, c); 3507 s = zbc_lex_number(c);
3494 else 3508 else
3495 s = bc_error_bad_character(c); 3509 s = bc_error_bad_character(c);
3496 break; 3510 break;
@@ -3510,10 +3524,10 @@ static BC_STATUS zdc_lex_token(BcLex *l)
3510 case 'D': 3524 case 'D':
3511 case 'E': 3525 case 'E':
3512 case 'F': 3526 case 'F':
3513 s = zbc_lex_number(l, c); 3527 s = zbc_lex_number(c);
3514 break; 3528 break;
3515 case '[': 3529 case '[':
3516 s = zdc_lex_string(l); 3530 s = zdc_lex_string();
3517 break; 3531 break;
3518 default: 3532 default:
3519 l->lex = XC_LEX_INVALID; 3533 l->lex = XC_LEX_INVALID;
@@ -3526,20 +3540,21 @@ static BC_STATUS zdc_lex_token(BcLex *l)
3526#define zdc_lex_token(...) (zdc_lex_token(__VA_ARGS__) COMMA_SUCCESS) 3540#define zdc_lex_token(...) (zdc_lex_token(__VA_ARGS__) COMMA_SUCCESS)
3527#endif // ENABLE_DC 3541#endif // ENABLE_DC
3528 3542
3529static void bc_parse_push(BcParse *p, char i) 3543static void bc_parse_push(char i)
3530{ 3544{
3545 BcParse *p = &G.prs;
3531 dbg_compile("%s:%d pushing bytecode %zd:%d", __func__, __LINE__, p->func->code.len, i); 3546 dbg_compile("%s:%d pushing bytecode %zd:%d", __func__, __LINE__, p->func->code.len, i);
3532 bc_vec_pushByte(&p->func->code, i); 3547 bc_vec_pushByte(&p->func->code, i);
3533} 3548}
3534 3549
3535static void bc_parse_pushName(BcParse *p, char *name) 3550static void bc_parse_pushName(char *name)
3536{ 3551{
3537 while (*name) 3552 while (*name)
3538 bc_parse_push(p, *name++); 3553 bc_parse_push(*name++);
3539 bc_parse_push(p, BC_PARSE_STREND); 3554 bc_parse_push(BC_PARSE_STREND);
3540} 3555}
3541 3556
3542static void bc_parse_pushIndex(BcParse *p, size_t idx) 3557static void bc_parse_pushIndex(size_t idx)
3543{ 3558{
3544 size_t mask; 3559 size_t mask;
3545 unsigned amt; 3560 unsigned amt;
@@ -3553,42 +3568,44 @@ static void bc_parse_pushIndex(BcParse *p, size_t idx)
3553 amt--; 3568 amt--;
3554 } while (amt != 0); 3569 } while (amt != 0);
3555 3570
3556 bc_parse_push(p, amt); 3571 bc_parse_push(amt);
3557 3572
3558 while (idx != 0) { 3573 while (idx != 0) {
3559 bc_parse_push(p, (unsigned char)idx); 3574 bc_parse_push((unsigned char)idx);
3560 idx >>= 8; 3575 idx >>= 8;
3561 } 3576 }
3562} 3577}
3563 3578
3564#if ENABLE_BC 3579#if ENABLE_BC
3565static void bc_parse_pushJUMP(BcParse *p, size_t idx) 3580static void bc_parse_pushJUMP(size_t idx)
3566{ 3581{
3567 bc_parse_push(p, BC_INST_JUMP); 3582 bc_parse_push(BC_INST_JUMP);
3568 bc_parse_pushIndex(p, idx); 3583 bc_parse_pushIndex(idx);
3569} 3584}
3570 3585
3571static void bc_parse_pushJUMP_ZERO(BcParse *p, size_t idx) 3586static void bc_parse_pushJUMP_ZERO(size_t idx)
3572{ 3587{
3573 bc_parse_push(p, BC_INST_JUMP_ZERO); 3588 bc_parse_push(BC_INST_JUMP_ZERO);
3574 bc_parse_pushIndex(p, idx); 3589 bc_parse_pushIndex(idx);
3575} 3590}
3576 3591
3577static BC_STATUS zbc_parse_pushSTR(BcParse *p) 3592static BC_STATUS zbc_parse_pushSTR(void)
3578{ 3593{
3594 BcParse *p = &G.prs;
3579 char *str = xstrdup(p->l.lex_buf.v); 3595 char *str = xstrdup(p->l.lex_buf.v);
3580 3596
3581 bc_parse_push(p, XC_INST_STR); 3597 bc_parse_push(XC_INST_STR);
3582 bc_parse_pushIndex(p, p->func->strs.len); 3598 bc_parse_pushIndex(p->func->strs.len);
3583 bc_vec_push(&p->func->strs, &str); 3599 bc_vec_push(&p->func->strs, &str);
3584 3600
3585 RETURN_STATUS(zbc_lex_next(&p->l)); 3601 RETURN_STATUS(zbc_lex_next());
3586} 3602}
3587#define zbc_parse_pushSTR(...) (zbc_parse_pushSTR(__VA_ARGS__) COMMA_SUCCESS) 3603#define zbc_parse_pushSTR(...) (zbc_parse_pushSTR(__VA_ARGS__) COMMA_SUCCESS)
3588#endif 3604#endif
3589 3605
3590static void bc_parse_pushNUM(BcParse *p) 3606static void bc_parse_pushNUM(void)
3591{ 3607{
3608 BcParse *p = &G.prs;
3592 char *num = xstrdup(p->l.lex_buf.v); 3609 char *num = xstrdup(p->l.lex_buf.v);
3593#if ENABLE_BC && ENABLE_DC 3610#if ENABLE_BC && ENABLE_DC
3594 size_t idx = bc_vec_push(IS_BC ? &p->func->consts : &G.prog.consts, &num); 3611 size_t idx = bc_vec_push(IS_BC ? &p->func->consts : &G.prog.consts, &num);
@@ -3597,15 +3614,16 @@ static void bc_parse_pushNUM(BcParse *p)
3597#else // DC 3614#else // DC
3598 size_t idx = bc_vec_push(&G.prog.consts, &num); 3615 size_t idx = bc_vec_push(&G.prog.consts, &num);
3599#endif 3616#endif
3600 bc_parse_push(p, XC_INST_NUM); 3617 bc_parse_push(XC_INST_NUM);
3601 bc_parse_pushIndex(p, idx); 3618 bc_parse_pushIndex(idx);
3602} 3619}
3603 3620
3604static BC_STATUS zbc_parse_text_init(BcParse *p, const char *text) 3621static BC_STATUS zbc_parse_text_init(const char *text)
3605{ 3622{
3623 BcParse *p = &G.prs;
3606 p->func = bc_program_func(p->fidx); 3624 p->func = bc_program_func(p->fidx);
3607 3625
3608 RETURN_STATUS(zbc_lex_text_init(&p->l, text)); 3626 RETURN_STATUS(zbc_lex_text_init(text));
3609} 3627}
3610#define zbc_parse_text_init(...) (zbc_parse_text_init(__VA_ARGS__) COMMA_SUCCESS) 3628#define zbc_parse_text_init(...) (zbc_parse_text_init(__VA_ARGS__) COMMA_SUCCESS)
3611 3629
@@ -3626,8 +3644,9 @@ static void bc_program_reset(void)
3626 3644
3627// Called when parsing code detects a failure, 3645// Called when parsing code detects a failure,
3628// resets parsing structures. 3646// resets parsing structures.
3629static void bc_parse_reset(BcParse *p) 3647static void bc_parse_reset(void)
3630{ 3648{
3649 BcParse *p = &G.prs;
3631 if (p->fidx != BC_PROG_MAIN) { 3650 if (p->fidx != BC_PROG_MAIN) {
3632 bc_func_free(p->func); 3651 bc_func_free(p->func);
3633 bc_func_init(p->func); 3652 bc_func_init(p->func);
@@ -3646,19 +3665,21 @@ static void bc_parse_reset(BcParse *p)
3646 bc_program_reset(); 3665 bc_program_reset();
3647} 3666}
3648 3667
3649static void bc_parse_free(BcParse *p) 3668static void bc_parse_free(void)
3650{ 3669{
3670 BcParse *p = &G.prs;
3651 IF_BC(bc_vec_free(&p->exits);) 3671 IF_BC(bc_vec_free(&p->exits);)
3652 IF_BC(bc_vec_free(&p->conds);) 3672 IF_BC(bc_vec_free(&p->conds);)
3653 IF_BC(bc_vec_free(&p->ops);) 3673 IF_BC(bc_vec_free(&p->ops);)
3654 bc_lex_free(&p->l); 3674 bc_lex_free();
3655} 3675}
3656 3676
3657static void bc_parse_create(BcParse *p, size_t fidx) 3677static void bc_parse_create(size_t fidx)
3658{ 3678{
3679 BcParse *p = &G.prs;
3659 memset(p, 0, sizeof(BcParse)); 3680 memset(p, 0, sizeof(BcParse));
3660 3681
3661 bc_lex_init(&p->l); 3682 bc_lex_init();
3662 IF_BC(bc_vec_init(&p->exits, sizeof(size_t), NULL);) 3683 IF_BC(bc_vec_init(&p->exits, sizeof(size_t), NULL);)
3663 IF_BC(bc_vec_init(&p->conds, sizeof(size_t), NULL);) 3684 IF_BC(bc_vec_init(&p->conds, sizeof(size_t), NULL);)
3664 IF_BC(bc_vec_init(&p->ops, sizeof(BcLexType), NULL);) 3685 IF_BC(bc_vec_init(&p->ops, sizeof(BcLexType), NULL);)
@@ -3714,44 +3735,45 @@ static size_t bc_program_addFunc(char *name)
3714// first in the expr enum. Note: This only works for binary operators. 3735// first in the expr enum. Note: This only works for binary operators.
3715#define BC_TOKEN_2_INST(t) ((char) ((t) - XC_LEX_OP_POWER + XC_INST_POWER)) 3736#define BC_TOKEN_2_INST(t) ((char) ((t) - XC_LEX_OP_POWER + XC_INST_POWER))
3716 3737
3717static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags); 3738static BcStatus bc_parse_expr_empty_ok(uint8_t flags);
3718 3739
3719static BC_STATUS zbc_parse_expr(BcParse *p, uint8_t flags) 3740static BC_STATUS zbc_parse_expr(uint8_t flags)
3720{ 3741{
3721 BcStatus s; 3742 BcStatus s;
3722 3743
3723 s = bc_parse_expr_empty_ok(p, flags); 3744 s = bc_parse_expr_empty_ok(flags);
3724 if (s == BC_STATUS_PARSE_EMPTY_EXP) 3745 if (s == BC_STATUS_PARSE_EMPTY_EXP)
3725 RETURN_STATUS(bc_error("empty expression")); 3746 RETURN_STATUS(bc_error("empty expression"));
3726 RETURN_STATUS(s); 3747 RETURN_STATUS(s);
3727} 3748}
3728#define zbc_parse_expr(...) (zbc_parse_expr(__VA_ARGS__) COMMA_SUCCESS) 3749#define zbc_parse_expr(...) (zbc_parse_expr(__VA_ARGS__) COMMA_SUCCESS)
3729 3750
3730static BC_STATUS zbc_parse_stmt_possibly_auto(BcParse *p, bool auto_allowed); 3751static BC_STATUS zbc_parse_stmt_possibly_auto(bool auto_allowed);
3731#define zbc_parse_stmt_possibly_auto(...) (zbc_parse_stmt_possibly_auto(__VA_ARGS__) COMMA_SUCCESS) 3752#define zbc_parse_stmt_possibly_auto(...) (zbc_parse_stmt_possibly_auto(__VA_ARGS__) COMMA_SUCCESS)
3732 3753
3733static BC_STATUS zbc_parse_stmt(BcParse *p) 3754static BC_STATUS zbc_parse_stmt(void)
3734{ 3755{
3735 RETURN_STATUS(zbc_parse_stmt_possibly_auto(p, false)); 3756 RETURN_STATUS(zbc_parse_stmt_possibly_auto(false));
3736} 3757}
3737#define zbc_parse_stmt(...) (zbc_parse_stmt(__VA_ARGS__) COMMA_SUCCESS) 3758#define zbc_parse_stmt(...) (zbc_parse_stmt(__VA_ARGS__) COMMA_SUCCESS)
3738 3759
3739static BC_STATUS zbc_parse_stmt_allow_NLINE_before(BcParse *p, const char *after_X) 3760static BC_STATUS zbc_parse_stmt_allow_NLINE_before(const char *after_X)
3740{ 3761{
3762 BcParse *p = &G.prs;
3741 // "if(cond)<newline>stmt" is accepted too, but not 2+ newlines. 3763 // "if(cond)<newline>stmt" is accepted too, but not 2+ newlines.
3742 // Same for "else", "while()", "for()". 3764 // Same for "else", "while()", "for()".
3743 BcStatus s = zbc_lex_next_and_skip_NLINE(&p->l); 3765 BcStatus s = zbc_lex_next_and_skip_NLINE();
3744 if (s) RETURN_STATUS(s); 3766 if (s) RETURN_STATUS(s);
3745 if (p->l.lex == XC_LEX_NLINE) 3767 if (p->l.lex == XC_LEX_NLINE)
3746 RETURN_STATUS(bc_error_fmt("no statement after '%s'", after_X)); 3768 RETURN_STATUS(bc_error_fmt("no statement after '%s'", after_X));
3747 3769
3748 RETURN_STATUS(zbc_parse_stmt(p)); 3770 RETURN_STATUS(zbc_parse_stmt());
3749} 3771}
3750#define zbc_parse_stmt_allow_NLINE_before(...) (zbc_parse_stmt_allow_NLINE_before(__VA_ARGS__) COMMA_SUCCESS) 3772#define zbc_parse_stmt_allow_NLINE_before(...) (zbc_parse_stmt_allow_NLINE_before(__VA_ARGS__) COMMA_SUCCESS)
3751 3773
3752static void bc_parse_operator(BcParse *p, BcLexType type, size_t start, 3774static void bc_parse_operator(BcLexType type, size_t start, size_t *nexprs)
3753 size_t *nexprs)
3754{ 3775{
3776 BcParse *p = &G.prs;
3755 char l, r = bc_parse_op_PREC(type - XC_LEX_1st_op); 3777 char l, r = bc_parse_op_PREC(type - XC_LEX_1st_op);
3756 bool left = bc_parse_op_LEFT(type - XC_LEX_1st_op); 3778 bool left = bc_parse_op_LEFT(type - XC_LEX_1st_op);
3757 3779
@@ -3762,7 +3784,7 @@ static void bc_parse_operator(BcParse *p, BcLexType type, size_t start,
3762 l = bc_parse_op_PREC(t - XC_LEX_1st_op); 3784 l = bc_parse_op_PREC(t - XC_LEX_1st_op);
3763 if (l >= r && (l != r || !left)) break; 3785 if (l >= r && (l != r || !left)) break;
3764 3786
3765 bc_parse_push(p, BC_TOKEN_2_INST(t)); 3787 bc_parse_push(BC_TOKEN_2_INST(t));
3766 bc_vec_pop(&p->ops); 3788 bc_vec_pop(&p->ops);
3767 *nexprs -= (t != BC_LEX_OP_BOOL_NOT && t != XC_LEX_NEG); 3789 *nexprs -= (t != BC_LEX_OP_BOOL_NOT && t != XC_LEX_NEG);
3768 } 3790 }
@@ -3770,8 +3792,9 @@ static void bc_parse_operator(BcParse *p, BcLexType type, size_t start,
3770 bc_vec_push(&p->ops, &type); 3792 bc_vec_push(&p->ops, &type);
3771} 3793}
3772 3794
3773static BC_STATUS zbc_parse_rightParen(BcParse *p, size_t ops_bgn, size_t *nexs) 3795static BC_STATUS zbc_parse_rightParen(size_t ops_bgn, size_t *nexs)
3774{ 3796{
3797 BcParse *p = &G.prs;
3775 BcLexType top; 3798 BcLexType top;
3776 3799
3777 if (p->ops.len <= ops_bgn) 3800 if (p->ops.len <= ops_bgn)
@@ -3779,7 +3802,7 @@ static BC_STATUS zbc_parse_rightParen(BcParse *p, size_t ops_bgn, size_t *nexs)
3779 top = BC_PARSE_TOP_OP(p); 3802 top = BC_PARSE_TOP_OP(p);
3780 3803
3781 while (top != BC_LEX_LPAREN) { 3804 while (top != BC_LEX_LPAREN) {
3782 bc_parse_push(p, BC_TOKEN_2_INST(top)); 3805 bc_parse_push(BC_TOKEN_2_INST(top));
3783 3806
3784 bc_vec_pop(&p->ops); 3807 bc_vec_pop(&p->ops);
3785 *nexs -= (top != BC_LEX_OP_BOOL_NOT && top != XC_LEX_NEG); 3808 *nexs -= (top != BC_LEX_OP_BOOL_NOT && top != XC_LEX_NEG);
@@ -3795,21 +3818,22 @@ static BC_STATUS zbc_parse_rightParen(BcParse *p, size_t ops_bgn, size_t *nexs)
3795} 3818}
3796#define zbc_parse_rightParen(...) (zbc_parse_rightParen(__VA_ARGS__) COMMA_SUCCESS) 3819#define zbc_parse_rightParen(...) (zbc_parse_rightParen(__VA_ARGS__) COMMA_SUCCESS)
3797 3820
3798static BC_STATUS zbc_parse_params(BcParse *p, uint8_t flags) 3821static BC_STATUS zbc_parse_params(uint8_t flags)
3799{ 3822{
3823 BcParse *p = &G.prs;
3800 BcStatus s; 3824 BcStatus s;
3801 size_t nparams; 3825 size_t nparams;
3802 3826
3803 dbg_lex("%s:%d p->l.lex:%d", __func__, __LINE__, p->l.lex); 3827 dbg_lex("%s:%d p->l.lex:%d", __func__, __LINE__, p->l.lex);
3804 flags = (flags & ~(BC_PARSE_PRINT | BC_PARSE_REL)) | BC_PARSE_ARRAY; 3828 flags = (flags & ~(BC_PARSE_PRINT | BC_PARSE_REL)) | BC_PARSE_ARRAY;
3805 3829
3806 s = zbc_lex_next(&p->l); 3830 s = zbc_lex_next();
3807 if (s) RETURN_STATUS(s); 3831 if (s) RETURN_STATUS(s);
3808 3832
3809 nparams = 0; 3833 nparams = 0;
3810 if (p->l.lex != BC_LEX_RPAREN) { 3834 if (p->l.lex != BC_LEX_RPAREN) {
3811 for (;;) { 3835 for (;;) {
3812 s = zbc_parse_expr(p, flags); 3836 s = zbc_parse_expr(flags);
3813 if (s) RETURN_STATUS(s); 3837 if (s) RETURN_STATUS(s);
3814 nparams++; 3838 nparams++;
3815 if (p->l.lex != BC_LEX_COMMA) { 3839 if (p->l.lex != BC_LEX_COMMA) {
@@ -3817,28 +3841,29 @@ static BC_STATUS zbc_parse_params(BcParse *p, uint8_t flags)
3817 break; 3841 break;
3818 RETURN_STATUS(bc_error_bad_token()); 3842 RETURN_STATUS(bc_error_bad_token());
3819 } 3843 }
3820 s = zbc_lex_next(&p->l); 3844 s = zbc_lex_next();
3821 if (s) RETURN_STATUS(s); 3845 if (s) RETURN_STATUS(s);
3822 } 3846 }
3823 } 3847 }
3824 3848
3825 bc_parse_push(p, BC_INST_CALL); 3849 bc_parse_push(BC_INST_CALL);
3826 bc_parse_pushIndex(p, nparams); 3850 bc_parse_pushIndex(nparams);
3827 3851
3828 RETURN_STATUS(BC_STATUS_SUCCESS); 3852 RETURN_STATUS(BC_STATUS_SUCCESS);
3829} 3853}
3830#define zbc_parse_params(...) (zbc_parse_params(__VA_ARGS__) COMMA_SUCCESS) 3854#define zbc_parse_params(...) (zbc_parse_params(__VA_ARGS__) COMMA_SUCCESS)
3831 3855
3832// Note: takes ownership of 'name' (must be malloced) 3856// Note: takes ownership of 'name' (must be malloced)
3833static BC_STATUS zbc_parse_call(BcParse *p, char *name, uint8_t flags) 3857static BC_STATUS zbc_parse_call(char *name, uint8_t flags)
3834{ 3858{
3859 BcParse *p = &G.prs;
3835 BcStatus s; 3860 BcStatus s;
3836 BcId entry, *entry_ptr; 3861 BcId entry, *entry_ptr;
3837 size_t idx; 3862 size_t idx;
3838 3863
3839 entry.name = name; 3864 entry.name = name;
3840 3865
3841 s = zbc_parse_params(p, flags); 3866 s = zbc_parse_params(flags);
3842 if (s) goto err; 3867 if (s) goto err;
3843 3868
3844 if (p->l.lex != BC_LEX_RPAREN) { 3869 if (p->l.lex != BC_LEX_RPAREN) {
@@ -3856,26 +3881,27 @@ static BC_STATUS zbc_parse_call(BcParse *p, char *name, uint8_t flags)
3856 free(name); 3881 free(name);
3857 3882
3858 entry_ptr = bc_vec_item(&G.prog.fn_map, idx); 3883 entry_ptr = bc_vec_item(&G.prog.fn_map, idx);
3859 bc_parse_pushIndex(p, entry_ptr->idx); 3884 bc_parse_pushIndex(entry_ptr->idx);
3860 3885
3861 RETURN_STATUS(zbc_lex_next(&p->l)); 3886 RETURN_STATUS(zbc_lex_next());
3862 err: 3887 err:
3863 free(name); 3888 free(name);
3864 RETURN_STATUS(s); 3889 RETURN_STATUS(s);
3865} 3890}
3866#define zbc_parse_call(...) (zbc_parse_call(__VA_ARGS__) COMMA_SUCCESS) 3891#define zbc_parse_call(...) (zbc_parse_call(__VA_ARGS__) COMMA_SUCCESS)
3867 3892
3868static BC_STATUS zbc_parse_name(BcParse *p, BcInst *type, uint8_t flags) 3893static BC_STATUS zbc_parse_name(BcInst *type, uint8_t flags)
3869{ 3894{
3895 BcParse *p = &G.prs;
3870 BcStatus s; 3896 BcStatus s;
3871 char *name; 3897 char *name;
3872 3898
3873 name = xstrdup(p->l.lex_buf.v); 3899 name = xstrdup(p->l.lex_buf.v);
3874 s = zbc_lex_next(&p->l); 3900 s = zbc_lex_next();
3875 if (s) goto err; 3901 if (s) goto err;
3876 3902
3877 if (p->l.lex == BC_LEX_LBRACKET) { 3903 if (p->l.lex == BC_LEX_LBRACKET) {
3878 s = zbc_lex_next(&p->l); 3904 s = zbc_lex_next();
3879 if (s) goto err; 3905 if (s) goto err;
3880 3906
3881 if (p->l.lex == BC_LEX_RBRACKET) { 3907 if (p->l.lex == BC_LEX_RBRACKET) {
@@ -3887,13 +3913,13 @@ static BC_STATUS zbc_parse_name(BcParse *p, BcInst *type, uint8_t flags)
3887 } else { 3913 } else {
3888 *type = XC_INST_ARRAY_ELEM; 3914 *type = XC_INST_ARRAY_ELEM;
3889 flags &= ~(BC_PARSE_PRINT | BC_PARSE_REL); 3915 flags &= ~(BC_PARSE_PRINT | BC_PARSE_REL);
3890 s = zbc_parse_expr(p, flags); 3916 s = zbc_parse_expr(flags);
3891 if (s) goto err; 3917 if (s) goto err;
3892 } 3918 }
3893 s = zbc_lex_next(&p->l); 3919 s = zbc_lex_next();
3894 if (s) goto err; 3920 if (s) goto err;
3895 bc_parse_push(p, *type); 3921 bc_parse_push(*type);
3896 bc_parse_pushName(p, name); 3922 bc_parse_pushName(name);
3897 free(name); 3923 free(name);
3898 } else if (p->l.lex == BC_LEX_LPAREN) { 3924 } else if (p->l.lex == BC_LEX_LPAREN) {
3899 if (flags & BC_PARSE_NOCALL) { 3925 if (flags & BC_PARSE_NOCALL) {
@@ -3901,11 +3927,11 @@ static BC_STATUS zbc_parse_name(BcParse *p, BcInst *type, uint8_t flags)
3901 goto err; 3927 goto err;
3902 } 3928 }
3903 *type = BC_INST_CALL; 3929 *type = BC_INST_CALL;
3904 s = zbc_parse_call(p, name, flags); 3930 s = zbc_parse_call(name, flags);
3905 } else { 3931 } else {
3906 *type = XC_INST_VAR; 3932 *type = XC_INST_VAR;
3907 bc_parse_push(p, XC_INST_VAR); 3933 bc_parse_push(XC_INST_VAR);
3908 bc_parse_pushName(p, name); 3934 bc_parse_pushName(name);
3909 free(name); 3935 free(name);
3910 } 3936 }
3911 3937
@@ -3916,82 +3942,85 @@ static BC_STATUS zbc_parse_name(BcParse *p, BcInst *type, uint8_t flags)
3916} 3942}
3917#define zbc_parse_name(...) (zbc_parse_name(__VA_ARGS__) COMMA_SUCCESS) 3943#define zbc_parse_name(...) (zbc_parse_name(__VA_ARGS__) COMMA_SUCCESS)
3918 3944
3919static BC_STATUS zbc_parse_read(BcParse *p) 3945static BC_STATUS zbc_parse_read(void)
3920{ 3946{
3947 BcParse *p = &G.prs;
3921 BcStatus s; 3948 BcStatus s;
3922 3949
3923 s = zbc_lex_next(&p->l); 3950 s = zbc_lex_next();
3924 if (s) RETURN_STATUS(s); 3951 if (s) RETURN_STATUS(s);
3925 if (p->l.lex != BC_LEX_LPAREN) RETURN_STATUS(bc_error_bad_token()); 3952 if (p->l.lex != BC_LEX_LPAREN) RETURN_STATUS(bc_error_bad_token());
3926 3953
3927 s = zbc_lex_next(&p->l); 3954 s = zbc_lex_next();
3928 if (s) RETURN_STATUS(s); 3955 if (s) RETURN_STATUS(s);
3929 if (p->l.lex != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token()); 3956 if (p->l.lex != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token());
3930 3957
3931 bc_parse_push(p, XC_INST_READ); 3958 bc_parse_push(XC_INST_READ);
3932 3959
3933 RETURN_STATUS(s); 3960 RETURN_STATUS(s);
3934} 3961}
3935#define zbc_parse_read(...) (zbc_parse_read(__VA_ARGS__) COMMA_SUCCESS) 3962#define zbc_parse_read(...) (zbc_parse_read(__VA_ARGS__) COMMA_SUCCESS)
3936 3963
3937static BC_STATUS zbc_parse_builtin(BcParse *p, BcLexType type, uint8_t flags, 3964static BC_STATUS zbc_parse_builtin(BcLexType type, uint8_t flags, BcInst *prev)
3938 BcInst *prev)
3939{ 3965{
3966 BcParse *p = &G.prs;
3940 BcStatus s; 3967 BcStatus s;
3941 3968
3942 s = zbc_lex_next(&p->l); 3969 s = zbc_lex_next();
3943 if (s) RETURN_STATUS(s); 3970 if (s) RETURN_STATUS(s);
3944 if (p->l.lex != BC_LEX_LPAREN) RETURN_STATUS(bc_error_bad_token()); 3971 if (p->l.lex != BC_LEX_LPAREN) RETURN_STATUS(bc_error_bad_token());
3945 3972
3946 flags = (flags & ~(BC_PARSE_PRINT | BC_PARSE_REL)) | BC_PARSE_ARRAY; 3973 flags = (flags & ~(BC_PARSE_PRINT | BC_PARSE_REL)) | BC_PARSE_ARRAY;
3947 3974
3948 s = zbc_lex_next(&p->l); 3975 s = zbc_lex_next();
3949 if (s) RETURN_STATUS(s); 3976 if (s) RETURN_STATUS(s);
3950 3977
3951 s = zbc_parse_expr(p, flags); 3978 s = zbc_parse_expr(flags);
3952 if (s) RETURN_STATUS(s); 3979 if (s) RETURN_STATUS(s);
3953 3980
3954 if (p->l.lex != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token()); 3981 if (p->l.lex != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token());
3955 3982
3956 *prev = (type == BC_LEX_KEY_LENGTH) ? XC_INST_LENGTH : XC_INST_SQRT; 3983 *prev = (type == BC_LEX_KEY_LENGTH) ? XC_INST_LENGTH : XC_INST_SQRT;
3957 bc_parse_push(p, *prev); 3984 bc_parse_push(*prev);
3958 3985
3959 RETURN_STATUS(s); 3986 RETURN_STATUS(s);
3960} 3987}
3961#define zbc_parse_builtin(...) (zbc_parse_builtin(__VA_ARGS__) COMMA_SUCCESS) 3988#define zbc_parse_builtin(...) (zbc_parse_builtin(__VA_ARGS__) COMMA_SUCCESS)
3962 3989
3963static BC_STATUS zbc_parse_scale(BcParse *p, BcInst *type, uint8_t flags) 3990static BC_STATUS zbc_parse_scale(BcInst *type, uint8_t flags)
3964{ 3991{
3992 BcParse *p = &G.prs;
3965 BcStatus s; 3993 BcStatus s;
3966 3994
3967 s = zbc_lex_next(&p->l); 3995 s = zbc_lex_next();
3968 if (s) RETURN_STATUS(s); 3996 if (s) RETURN_STATUS(s);
3969 3997
3970 if (p->l.lex != BC_LEX_LPAREN) { 3998 if (p->l.lex != BC_LEX_LPAREN) {
3971 *type = XC_INST_SCALE; 3999 *type = XC_INST_SCALE;
3972 bc_parse_push(p, XC_INST_SCALE); 4000 bc_parse_push(XC_INST_SCALE);
3973 RETURN_STATUS(BC_STATUS_SUCCESS); 4001 RETURN_STATUS(BC_STATUS_SUCCESS);
3974 } 4002 }
3975 4003
3976 *type = XC_INST_SCALE_FUNC; 4004 *type = XC_INST_SCALE_FUNC;
3977 flags &= ~(BC_PARSE_PRINT | BC_PARSE_REL); 4005 flags &= ~(BC_PARSE_PRINT | BC_PARSE_REL);
3978 4006
3979 s = zbc_lex_next(&p->l); 4007 s = zbc_lex_next();
3980 if (s) RETURN_STATUS(s); 4008 if (s) RETURN_STATUS(s);
3981 4009
3982 s = zbc_parse_expr(p, flags); 4010 s = zbc_parse_expr(flags);
3983 if (s) RETURN_STATUS(s); 4011 if (s) RETURN_STATUS(s);
3984 if (p->l.lex != BC_LEX_RPAREN) 4012 if (p->l.lex != BC_LEX_RPAREN)
3985 RETURN_STATUS(bc_error_bad_token()); 4013 RETURN_STATUS(bc_error_bad_token());
3986 bc_parse_push(p, XC_INST_SCALE_FUNC); 4014 bc_parse_push(XC_INST_SCALE_FUNC);
3987 4015
3988 RETURN_STATUS(zbc_lex_next(&p->l)); 4016 RETURN_STATUS(zbc_lex_next());
3989} 4017}
3990#define zbc_parse_scale(...) (zbc_parse_scale(__VA_ARGS__) COMMA_SUCCESS) 4018#define zbc_parse_scale(...) (zbc_parse_scale(__VA_ARGS__) COMMA_SUCCESS)
3991 4019
3992static BC_STATUS zbc_parse_incdec(BcParse *p, BcInst *prev, bool *paren_expr, 4020static BC_STATUS zbc_parse_incdec(BcInst *prev, bool *paren_expr,
3993 size_t *nexprs, uint8_t flags) 4021 size_t *nexprs, uint8_t flags)
3994{ 4022{
4023 BcParse *p = &G.prs;
3995 BcStatus s; 4024 BcStatus s;
3996 BcLexType type; 4025 BcLexType type;
3997 char inst; 4026 char inst;
@@ -4002,13 +4031,13 @@ static BC_STATUS zbc_parse_incdec(BcParse *p, BcInst *prev, bool *paren_expr,
4002 || etype == XC_INST_IBASE || etype == XC_INST_OBASE 4031 || etype == XC_INST_IBASE || etype == XC_INST_OBASE
4003 ) { 4032 ) {
4004 *prev = inst = BC_INST_INC_POST + (p->l.lex != BC_LEX_OP_INC); 4033 *prev = inst = BC_INST_INC_POST + (p->l.lex != BC_LEX_OP_INC);
4005 bc_parse_push(p, inst); 4034 bc_parse_push(inst);
4006 s = zbc_lex_next(&p->l); 4035 s = zbc_lex_next();
4007 } else { 4036 } else {
4008 *prev = inst = BC_INST_INC_PRE + (p->l.lex != BC_LEX_OP_INC); 4037 *prev = inst = BC_INST_INC_PRE + (p->l.lex != BC_LEX_OP_INC);
4009 *paren_expr = true; 4038 *paren_expr = true;
4010 4039
4011 s = zbc_lex_next(&p->l); 4040 s = zbc_lex_next();
4012 if (s) RETURN_STATUS(s); 4041 if (s) RETURN_STATUS(s);
4013 type = p->l.lex; 4042 type = p->l.lex;
4014 4043
@@ -4018,28 +4047,28 @@ static BC_STATUS zbc_parse_incdec(BcParse *p, BcInst *prev, bool *paren_expr,
4018 4047
4019 switch (type) { 4048 switch (type) {
4020 case XC_LEX_NAME: 4049 case XC_LEX_NAME:
4021 s = zbc_parse_name(p, prev, flags | BC_PARSE_NOCALL); 4050 s = zbc_parse_name(prev, flags | BC_PARSE_NOCALL);
4022 break; 4051 break;
4023 case BC_LEX_KEY_IBASE: 4052 case BC_LEX_KEY_IBASE:
4024 case BC_LEX_KEY_LAST: 4053 case BC_LEX_KEY_LAST:
4025 case BC_LEX_KEY_OBASE: 4054 case BC_LEX_KEY_OBASE:
4026 bc_parse_push(p, type - BC_LEX_KEY_IBASE + XC_INST_IBASE); 4055 bc_parse_push(type - BC_LEX_KEY_IBASE + XC_INST_IBASE);
4027 s = zbc_lex_next(&p->l); 4056 s = zbc_lex_next();
4028 break; 4057 break;
4029 case BC_LEX_KEY_SCALE: 4058 case BC_LEX_KEY_SCALE:
4030 s = zbc_lex_next(&p->l); 4059 s = zbc_lex_next();
4031 if (s) RETURN_STATUS(s); 4060 if (s) RETURN_STATUS(s);
4032 if (p->l.lex == BC_LEX_LPAREN) 4061 if (p->l.lex == BC_LEX_LPAREN)
4033 s = bc_error_bad_token(); 4062 s = bc_error_bad_token();
4034 else 4063 else
4035 bc_parse_push(p, XC_INST_SCALE); 4064 bc_parse_push(XC_INST_SCALE);
4036 break; 4065 break;
4037 default: 4066 default:
4038 s = bc_error_bad_token(); 4067 s = bc_error_bad_token();
4039 break; 4068 break;
4040 } 4069 }
4041 4070
4042 if (!s) bc_parse_push(p, inst); 4071 if (!s) bc_parse_push(inst);
4043 } 4072 }
4044 4073
4045 RETURN_STATUS(s); 4074 RETURN_STATUS(s);
@@ -4064,14 +4093,15 @@ static int ok_in_expr(BcInst p)
4064#define BC_PARSE_LEAF(p, rparen) ((rparen) || ok_in_expr(p)) 4093#define BC_PARSE_LEAF(p, rparen) ((rparen) || ok_in_expr(p))
4065#endif 4094#endif
4066 4095
4067static BC_STATUS zbc_parse_minus(BcParse *p, BcInst *prev, size_t ops_bgn, 4096static BC_STATUS zbc_parse_minus(BcInst *prev, size_t ops_bgn,
4068 bool rparen, size_t *nexprs) 4097 bool rparen, size_t *nexprs)
4069{ 4098{
4099 BcParse *p = &G.prs;
4070 BcStatus s; 4100 BcStatus s;
4071 BcLexType type; 4101 BcLexType type;
4072 BcInst etype = *prev; 4102 BcInst etype = *prev;
4073 4103
4074 s = zbc_lex_next(&p->l); 4104 s = zbc_lex_next();
4075 if (s) RETURN_STATUS(s); 4105 if (s) RETURN_STATUS(s);
4076 4106
4077 type = BC_PARSE_LEAF(etype, rparen) ? XC_LEX_OP_MINUS : XC_LEX_NEG; 4107 type = BC_PARSE_LEAF(etype, rparen) ? XC_LEX_OP_MINUS : XC_LEX_NEG;
@@ -4082,28 +4112,29 @@ static BC_STATUS zbc_parse_minus(BcParse *p, BcInst *prev, size_t ops_bgn,
4082 if (type != XC_LEX_OP_MINUS) 4112 if (type != XC_LEX_OP_MINUS)
4083 bc_vec_push(&p->ops, &type); 4113 bc_vec_push(&p->ops, &type);
4084 else 4114 else
4085 bc_parse_operator(p, type, ops_bgn, nexprs); 4115 bc_parse_operator(type, ops_bgn, nexprs);
4086 4116
4087 RETURN_STATUS(s); 4117 RETURN_STATUS(s);
4088} 4118}
4089#define zbc_parse_minus(...) (zbc_parse_minus(__VA_ARGS__) COMMA_SUCCESS) 4119#define zbc_parse_minus(...) (zbc_parse_minus(__VA_ARGS__) COMMA_SUCCESS)
4090 4120
4091static BC_STATUS zbc_parse_print(BcParse *p) 4121static BC_STATUS zbc_parse_print(void)
4092{ 4122{
4123 BcParse *p = &G.prs;
4093 BcStatus s; 4124 BcStatus s;
4094 BcLexType type; 4125 BcLexType type;
4095 4126
4096 for (;;) { 4127 for (;;) {
4097 s = zbc_lex_next(&p->l); 4128 s = zbc_lex_next();
4098 if (s) RETURN_STATUS(s); 4129 if (s) RETURN_STATUS(s);
4099 type = p->l.lex; 4130 type = p->l.lex;
4100 if (type == XC_LEX_STR) { 4131 if (type == XC_LEX_STR) {
4101 s = zbc_parse_pushSTR(p); 4132 s = zbc_parse_pushSTR();
4102 } else { 4133 } else {
4103 s = zbc_parse_expr(p, 0); 4134 s = zbc_parse_expr(0);
4104 } 4135 }
4105 if (s) RETURN_STATUS(s); 4136 if (s) RETURN_STATUS(s);
4106 bc_parse_push(p, XC_INST_PRINT_POP); 4137 bc_parse_push(XC_INST_PRINT_POP);
4107 if (p->l.lex != BC_LEX_COMMA) 4138 if (p->l.lex != BC_LEX_COMMA)
4108 break; 4139 break;
4109 } 4140 }
@@ -4112,24 +4143,25 @@ static BC_STATUS zbc_parse_print(BcParse *p)
4112} 4143}
4113#define zbc_parse_print(...) (zbc_parse_print(__VA_ARGS__) COMMA_SUCCESS) 4144#define zbc_parse_print(...) (zbc_parse_print(__VA_ARGS__) COMMA_SUCCESS)
4114 4145
4115static BC_STATUS zbc_parse_return(BcParse *p) 4146static BC_STATUS zbc_parse_return(void)
4116{ 4147{
4148 BcParse *p = &G.prs;
4117 BcStatus s; 4149 BcStatus s;
4118 BcLexType t; 4150 BcLexType t;
4119 4151
4120 dbg_lex_enter("%s:%d entered", __func__, __LINE__); 4152 dbg_lex_enter("%s:%d entered", __func__, __LINE__);
4121 s = zbc_lex_next(&p->l); 4153 s = zbc_lex_next();
4122 if (s) RETURN_STATUS(s); 4154 if (s) RETURN_STATUS(s);
4123 4155
4124 t = p->l.lex; 4156 t = p->l.lex;
4125 if (t == XC_LEX_NLINE || t == BC_LEX_SCOLON) 4157 if (t == XC_LEX_NLINE || t == BC_LEX_SCOLON)
4126 bc_parse_push(p, BC_INST_RET0); 4158 bc_parse_push(BC_INST_RET0);
4127 else { 4159 else {
4128 bool paren = (t == BC_LEX_LPAREN); 4160 bool paren = (t == BC_LEX_LPAREN);
4129 s = bc_parse_expr_empty_ok(p, 0); 4161 s = bc_parse_expr_empty_ok(0);
4130 if (s == BC_STATUS_PARSE_EMPTY_EXP) { 4162 if (s == BC_STATUS_PARSE_EMPTY_EXP) {
4131 bc_parse_push(p, BC_INST_RET0); 4163 bc_parse_push(BC_INST_RET0);
4132 s = zbc_lex_next(&p->l); 4164 s = zbc_lex_next();
4133 } 4165 }
4134 if (s) RETURN_STATUS(s); 4166 if (s) RETURN_STATUS(s);
4135 4167
@@ -4138,7 +4170,7 @@ static BC_STATUS zbc_parse_return(BcParse *p)
4138 if (s) RETURN_STATUS(s); 4170 if (s) RETURN_STATUS(s);
4139 } 4171 }
4140 4172
4141 bc_parse_push(p, XC_INST_RET); 4173 bc_parse_push(XC_INST_RET);
4142 } 4174 }
4143 4175
4144 dbg_lex_done("%s:%d done", __func__, __LINE__); 4176 dbg_lex_done("%s:%d done", __func__, __LINE__);
@@ -4146,25 +4178,27 @@ static BC_STATUS zbc_parse_return(BcParse *p)
4146} 4178}
4147#define zbc_parse_return(...) (zbc_parse_return(__VA_ARGS__) COMMA_SUCCESS) 4179#define zbc_parse_return(...) (zbc_parse_return(__VA_ARGS__) COMMA_SUCCESS)
4148 4180
4149static void rewrite_label_to_current(BcParse *p, size_t idx) 4181static void rewrite_label_to_current(size_t idx)
4150{ 4182{
4183 BcParse *p = &G.prs;
4151 size_t *label = bc_vec_item(&p->func->labels, idx); 4184 size_t *label = bc_vec_item(&p->func->labels, idx);
4152 *label = p->func->code.len; 4185 *label = p->func->code.len;
4153} 4186}
4154 4187
4155static BC_STATUS zbc_parse_if(BcParse *p) 4188static BC_STATUS zbc_parse_if(void)
4156{ 4189{
4190 BcParse *p = &G.prs;
4157 BcStatus s; 4191 BcStatus s;
4158 size_t ip_idx; 4192 size_t ip_idx;
4159 4193
4160 dbg_lex_enter("%s:%d entered", __func__, __LINE__); 4194 dbg_lex_enter("%s:%d entered", __func__, __LINE__);
4161 s = zbc_lex_next(&p->l); 4195 s = zbc_lex_next();
4162 if (s) RETURN_STATUS(s); 4196 if (s) RETURN_STATUS(s);
4163 if (p->l.lex != BC_LEX_LPAREN) RETURN_STATUS(bc_error_bad_token()); 4197 if (p->l.lex != BC_LEX_LPAREN) RETURN_STATUS(bc_error_bad_token());
4164 4198
4165 s = zbc_lex_next(&p->l); 4199 s = zbc_lex_next();
4166 if (s) RETURN_STATUS(s); 4200 if (s) RETURN_STATUS(s);
4167 s = zbc_parse_expr(p, BC_PARSE_REL); 4201 s = zbc_parse_expr(BC_PARSE_REL);
4168 if (s) RETURN_STATUS(s); 4202 if (s) RETURN_STATUS(s);
4169 if (p->l.lex != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token()); 4203 if (p->l.lex != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token());
4170 4204
@@ -4172,9 +4206,9 @@ static BC_STATUS zbc_parse_if(BcParse *p)
4172 // Pushed value (destination of the jump) is uninitialized, 4206 // Pushed value (destination of the jump) is uninitialized,
4173 // will be rewritten to be address of "end of if()" or of "else". 4207 // will be rewritten to be address of "end of if()" or of "else".
4174 ip_idx = bc_vec_push(&p->func->labels, &ip_idx); 4208 ip_idx = bc_vec_push(&p->func->labels, &ip_idx);
4175 bc_parse_pushJUMP_ZERO(p, ip_idx); 4209 bc_parse_pushJUMP_ZERO(ip_idx);
4176 4210
4177 s = zbc_parse_stmt_allow_NLINE_before(p, STRING_if); 4211 s = zbc_parse_stmt_allow_NLINE_before(STRING_if);
4178 if (s) RETURN_STATUS(s); 4212 if (s) RETURN_STATUS(s);
4179 4213
4180 dbg_lex("%s:%d in if after stmt: p->l.lex:%d", __func__, __LINE__, p->l.lex); 4214 dbg_lex("%s:%d in if after stmt: p->l.lex:%d", __func__, __LINE__, p->l.lex);
@@ -4184,35 +4218,36 @@ static BC_STATUS zbc_parse_if(BcParse *p)
4184 // Encode "after then_stmt, jump to end of if()" 4218 // Encode "after then_stmt, jump to end of if()"
4185 ip2_idx = bc_vec_push(&p->func->labels, &ip2_idx); 4219 ip2_idx = bc_vec_push(&p->func->labels, &ip2_idx);
4186 dbg_lex("%s:%d after if() then_stmt: BC_INST_JUMP to %zd", __func__, __LINE__, ip2_idx); 4220 dbg_lex("%s:%d after if() then_stmt: BC_INST_JUMP to %zd", __func__, __LINE__, ip2_idx);
4187 bc_parse_pushJUMP(p, ip2_idx); 4221 bc_parse_pushJUMP(ip2_idx);
4188 4222
4189 dbg_lex("%s:%d rewriting 'if_zero' label to jump to 'else'-> %zd", __func__, __LINE__, p->func->code.len); 4223 dbg_lex("%s:%d rewriting 'if_zero' label to jump to 'else'-> %zd", __func__, __LINE__, p->func->code.len);
4190 rewrite_label_to_current(p, ip_idx); 4224 rewrite_label_to_current(ip_idx);
4191 4225
4192 ip_idx = ip2_idx; 4226 ip_idx = ip2_idx;
4193 4227
4194 s = zbc_parse_stmt_allow_NLINE_before(p, STRING_else); 4228 s = zbc_parse_stmt_allow_NLINE_before(STRING_else);
4195 if (s) RETURN_STATUS(s); 4229 if (s) RETURN_STATUS(s);
4196 } 4230 }
4197 4231
4198 dbg_lex("%s:%d rewriting label to jump after 'if' body-> %zd", __func__, __LINE__, p->func->code.len); 4232 dbg_lex("%s:%d rewriting label to jump after 'if' body-> %zd", __func__, __LINE__, p->func->code.len);
4199 rewrite_label_to_current(p, ip_idx); 4233 rewrite_label_to_current(ip_idx);
4200 4234
4201 dbg_lex_done("%s:%d done", __func__, __LINE__); 4235 dbg_lex_done("%s:%d done", __func__, __LINE__);
4202 RETURN_STATUS(s); 4236 RETURN_STATUS(s);
4203} 4237}
4204#define zbc_parse_if(...) (zbc_parse_if(__VA_ARGS__) COMMA_SUCCESS) 4238#define zbc_parse_if(...) (zbc_parse_if(__VA_ARGS__) COMMA_SUCCESS)
4205 4239
4206static BC_STATUS zbc_parse_while(BcParse *p) 4240static BC_STATUS zbc_parse_while(void)
4207{ 4241{
4242 BcParse *p = &G.prs;
4208 BcStatus s; 4243 BcStatus s;
4209 size_t cond_idx; 4244 size_t cond_idx;
4210 size_t ip_idx; 4245 size_t ip_idx;
4211 4246
4212 s = zbc_lex_next(&p->l); 4247 s = zbc_lex_next();
4213 if (s) RETURN_STATUS(s); 4248 if (s) RETURN_STATUS(s);
4214 if (p->l.lex != BC_LEX_LPAREN) RETURN_STATUS(bc_error_bad_token()); 4249 if (p->l.lex != BC_LEX_LPAREN) RETURN_STATUS(bc_error_bad_token());
4215 s = zbc_lex_next(&p->l); 4250 s = zbc_lex_next();
4216 if (s) RETURN_STATUS(s); 4251 if (s) RETURN_STATUS(s);
4217 4252
4218 cond_idx = bc_vec_push(&p->func->labels, &p->func->code.len); 4253 cond_idx = bc_vec_push(&p->func->labels, &p->func->code.len);
@@ -4222,20 +4257,20 @@ static BC_STATUS zbc_parse_while(BcParse *p)
4222 bc_vec_push(&p->exits, &ip_idx); 4257 bc_vec_push(&p->exits, &ip_idx);
4223 bc_vec_push(&p->func->labels, &ip_idx); 4258 bc_vec_push(&p->func->labels, &ip_idx);
4224 4259
4225 s = zbc_parse_expr(p, BC_PARSE_REL); 4260 s = zbc_parse_expr(BC_PARSE_REL);
4226 if (s) RETURN_STATUS(s); 4261 if (s) RETURN_STATUS(s);
4227 if (p->l.lex != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token()); 4262 if (p->l.lex != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token());
4228 4263
4229 bc_parse_pushJUMP_ZERO(p, ip_idx); 4264 bc_parse_pushJUMP_ZERO(ip_idx);
4230 4265
4231 s = zbc_parse_stmt_allow_NLINE_before(p, STRING_while); 4266 s = zbc_parse_stmt_allow_NLINE_before(STRING_while);
4232 if (s) RETURN_STATUS(s); 4267 if (s) RETURN_STATUS(s);
4233 4268
4234 dbg_lex("%s:%d BC_INST_JUMP to %zd", __func__, __LINE__, cond_idx); 4269 dbg_lex("%s:%d BC_INST_JUMP to %zd", __func__, __LINE__, cond_idx);
4235 bc_parse_pushJUMP(p, cond_idx); 4270 bc_parse_pushJUMP(cond_idx);
4236 4271
4237 dbg_lex("%s:%d rewriting label-> %zd", __func__, __LINE__, p->func->code.len); 4272 dbg_lex("%s:%d rewriting label-> %zd", __func__, __LINE__, p->func->code.len);
4238 rewrite_label_to_current(p, ip_idx); 4273 rewrite_label_to_current(ip_idx);
4239 4274
4240 bc_vec_pop(&p->exits); 4275 bc_vec_pop(&p->exits);
4241 bc_vec_pop(&p->conds); 4276 bc_vec_pop(&p->conds);
@@ -4244,21 +4279,22 @@ static BC_STATUS zbc_parse_while(BcParse *p)
4244} 4279}
4245#define zbc_parse_while(...) (zbc_parse_while(__VA_ARGS__) COMMA_SUCCESS) 4280#define zbc_parse_while(...) (zbc_parse_while(__VA_ARGS__) COMMA_SUCCESS)
4246 4281
4247static BC_STATUS zbc_parse_for(BcParse *p) 4282static BC_STATUS zbc_parse_for(void)
4248{ 4283{
4284 BcParse *p = &G.prs;
4249 BcStatus s; 4285 BcStatus s;
4250 size_t cond_idx, exit_idx, body_idx, update_idx; 4286 size_t cond_idx, exit_idx, body_idx, update_idx;
4251 4287
4252 dbg_lex("%s:%d p->l.lex:%d", __func__, __LINE__, p->l.lex); 4288 dbg_lex("%s:%d p->l.lex:%d", __func__, __LINE__, p->l.lex);
4253 s = zbc_lex_next(&p->l); 4289 s = zbc_lex_next();
4254 if (s) RETURN_STATUS(s); 4290 if (s) RETURN_STATUS(s);
4255 if (p->l.lex != BC_LEX_LPAREN) RETURN_STATUS(bc_error_bad_token()); 4291 if (p->l.lex != BC_LEX_LPAREN) RETURN_STATUS(bc_error_bad_token());
4256 s = zbc_lex_next(&p->l); 4292 s = zbc_lex_next();
4257 if (s) RETURN_STATUS(s); 4293 if (s) RETURN_STATUS(s);
4258 4294
4259 if (p->l.lex != BC_LEX_SCOLON) { 4295 if (p->l.lex != BC_LEX_SCOLON) {
4260 s = zbc_parse_expr(p, 0); 4296 s = zbc_parse_expr(0);
4261 bc_parse_push(p, XC_INST_POP); 4297 bc_parse_push(XC_INST_POP);
4262 if (s) RETURN_STATUS(s); 4298 if (s) RETURN_STATUS(s);
4263 } else { 4299 } else {
4264 s = zbc_POSIX_does_not_allow_empty_X_expression_in_for("init"); 4300 s = zbc_POSIX_does_not_allow_empty_X_expression_in_for("init");
@@ -4266,7 +4302,7 @@ static BC_STATUS zbc_parse_for(BcParse *p)
4266 } 4302 }
4267 4303
4268 if (p->l.lex != BC_LEX_SCOLON) RETURN_STATUS(bc_error_bad_token()); 4304 if (p->l.lex != BC_LEX_SCOLON) RETURN_STATUS(bc_error_bad_token());
4269 s = zbc_lex_next(&p->l); 4305 s = zbc_lex_next();
4270 if (s) RETURN_STATUS(s); 4306 if (s) RETURN_STATUS(s);
4271 4307
4272 cond_idx = bc_vec_push(&p->func->labels, &p->func->code.len); 4308 cond_idx = bc_vec_push(&p->func->labels, &p->func->code.len);
@@ -4275,52 +4311,52 @@ static BC_STATUS zbc_parse_for(BcParse *p)
4275 exit_idx = body_idx + 1; 4311 exit_idx = body_idx + 1;
4276 4312
4277 if (p->l.lex != BC_LEX_SCOLON) 4313 if (p->l.lex != BC_LEX_SCOLON)
4278 s = zbc_parse_expr(p, BC_PARSE_REL); 4314 s = zbc_parse_expr(BC_PARSE_REL);
4279 else { 4315 else {
4280 // Set this for the next call to bc_parse_pushNUM(). 4316 // Set this for the next call to bc_parse_pushNUM().
4281 // This is safe to set because the current token is a semicolon, 4317 // This is safe to set because the current token is a semicolon,
4282 // which has no string requirement. 4318 // which has no string requirement.
4283 bc_vec_string(&p->l.lex_buf, 1, "1"); 4319 bc_vec_string(&p->l.lex_buf, 1, "1");
4284 bc_parse_pushNUM(p); 4320 bc_parse_pushNUM();
4285 s = zbc_POSIX_does_not_allow_empty_X_expression_in_for("condition"); 4321 s = zbc_POSIX_does_not_allow_empty_X_expression_in_for("condition");
4286 } 4322 }
4287 if (s) RETURN_STATUS(s); 4323 if (s) RETURN_STATUS(s);
4288 4324
4289 if (p->l.lex != BC_LEX_SCOLON) RETURN_STATUS(bc_error_bad_token()); 4325 if (p->l.lex != BC_LEX_SCOLON) RETURN_STATUS(bc_error_bad_token());
4290 4326
4291 s = zbc_lex_next(&p->l); 4327 s = zbc_lex_next();
4292 if (s) RETURN_STATUS(s); 4328 if (s) RETURN_STATUS(s);
4293 4329
4294 bc_parse_pushJUMP_ZERO(p, exit_idx); 4330 bc_parse_pushJUMP_ZERO(exit_idx);
4295 bc_parse_pushJUMP(p, body_idx); 4331 bc_parse_pushJUMP(body_idx);
4296 4332
4297 bc_vec_push(&p->conds, &update_idx); 4333 bc_vec_push(&p->conds, &update_idx);
4298 bc_vec_push(&p->func->labels, &p->func->code.len); 4334 bc_vec_push(&p->func->labels, &p->func->code.len);
4299 4335
4300 if (p->l.lex != BC_LEX_RPAREN) { 4336 if (p->l.lex != BC_LEX_RPAREN) {
4301 s = zbc_parse_expr(p, 0); 4337 s = zbc_parse_expr(0);
4302 if (s) RETURN_STATUS(s); 4338 if (s) RETURN_STATUS(s);
4303 if (p->l.lex != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token()); 4339 if (p->l.lex != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token());
4304 bc_parse_push(p, XC_INST_POP); 4340 bc_parse_push(XC_INST_POP);
4305 } else { 4341 } else {
4306 s = zbc_POSIX_does_not_allow_empty_X_expression_in_for("update"); 4342 s = zbc_POSIX_does_not_allow_empty_X_expression_in_for("update");
4307 if (s) RETURN_STATUS(s); 4343 if (s) RETURN_STATUS(s);
4308 } 4344 }
4309 4345
4310 bc_parse_pushJUMP(p, cond_idx); 4346 bc_parse_pushJUMP(cond_idx);
4311 bc_vec_push(&p->func->labels, &p->func->code.len); 4347 bc_vec_push(&p->func->labels, &p->func->code.len);
4312 4348
4313 bc_vec_push(&p->exits, &exit_idx); 4349 bc_vec_push(&p->exits, &exit_idx);
4314 bc_vec_push(&p->func->labels, &exit_idx); 4350 bc_vec_push(&p->func->labels, &exit_idx);
4315 4351
4316 s = zbc_parse_stmt_allow_NLINE_before(p, STRING_for); 4352 s = zbc_parse_stmt_allow_NLINE_before(STRING_for);
4317 if (s) RETURN_STATUS(s); 4353 if (s) RETURN_STATUS(s);
4318 4354
4319 dbg_lex("%s:%d BC_INST_JUMP to %zd", __func__, __LINE__, update_idx); 4355 dbg_lex("%s:%d BC_INST_JUMP to %zd", __func__, __LINE__, update_idx);
4320 bc_parse_pushJUMP(p, update_idx); 4356 bc_parse_pushJUMP(update_idx);
4321 4357
4322 dbg_lex("%s:%d rewriting label-> %zd", __func__, __LINE__, p->func->code.len); 4358 dbg_lex("%s:%d rewriting label-> %zd", __func__, __LINE__, p->func->code.len);
4323 rewrite_label_to_current(p, exit_idx); 4359 rewrite_label_to_current(exit_idx);
4324 4360
4325 bc_vec_pop(&p->exits); 4361 bc_vec_pop(&p->exits);
4326 bc_vec_pop(&p->conds); 4362 bc_vec_pop(&p->conds);
@@ -4329,8 +4365,9 @@ static BC_STATUS zbc_parse_for(BcParse *p)
4329} 4365}
4330#define zbc_parse_for(...) (zbc_parse_for(__VA_ARGS__) COMMA_SUCCESS) 4366#define zbc_parse_for(...) (zbc_parse_for(__VA_ARGS__) COMMA_SUCCESS)
4331 4367
4332static BC_STATUS zbc_parse_break_or_continue(BcParse *p, BcLexType type) 4368static BC_STATUS zbc_parse_break_or_continue(BcLexType type)
4333{ 4369{
4370 BcParse *p = &G.prs;
4334 size_t i; 4371 size_t i;
4335 4372
4336 if (type == BC_LEX_KEY_BREAK) { 4373 if (type == BC_LEX_KEY_BREAK) {
@@ -4340,9 +4377,9 @@ static BC_STATUS zbc_parse_break_or_continue(BcParse *p, BcLexType type)
4340 } else { 4377 } else {
4341 i = *(size_t*)bc_vec_top(&p->conds); 4378 i = *(size_t*)bc_vec_top(&p->conds);
4342 } 4379 }
4343 bc_parse_pushJUMP(p, i); 4380 bc_parse_pushJUMP(i);
4344 4381
4345 RETURN_STATUS(zbc_lex_next(&p->l)); 4382 RETURN_STATUS(zbc_lex_next());
4346} 4383}
4347#define zbc_parse_break_or_continue(...) (zbc_parse_break_or_continue(__VA_ARGS__) COMMA_SUCCESS) 4384#define zbc_parse_break_or_continue(...) (zbc_parse_break_or_continue(__VA_ARGS__) COMMA_SUCCESS)
4348 4385
@@ -4367,14 +4404,15 @@ static BC_STATUS zbc_func_insert(BcFunc *f, char *name, bool var)
4367} 4404}
4368#define zbc_func_insert(...) (zbc_func_insert(__VA_ARGS__) COMMA_SUCCESS) 4405#define zbc_func_insert(...) (zbc_func_insert(__VA_ARGS__) COMMA_SUCCESS)
4369 4406
4370static BC_STATUS zbc_parse_funcdef(BcParse *p) 4407static BC_STATUS zbc_parse_funcdef(void)
4371{ 4408{
4409 BcParse *p = &G.prs;
4372 BcStatus s; 4410 BcStatus s;
4373 bool var, comma = false; 4411 bool var, comma = false;
4374 char *name; 4412 char *name;
4375 4413
4376 dbg_lex_enter("%s:%d entered", __func__, __LINE__); 4414 dbg_lex_enter("%s:%d entered", __func__, __LINE__);
4377 s = zbc_lex_next(&p->l); 4415 s = zbc_lex_next();
4378 if (s) RETURN_STATUS(s); 4416 if (s) RETURN_STATUS(s);
4379 if (p->l.lex != XC_LEX_NAME) 4417 if (p->l.lex != XC_LEX_NAME)
4380 RETURN_STATUS(bc_error("bad function definition")); 4418 RETURN_STATUS(bc_error("bad function definition"));
@@ -4383,11 +4421,11 @@ static BC_STATUS zbc_parse_funcdef(BcParse *p)
4383 p->fidx = bc_program_addFunc(name); 4421 p->fidx = bc_program_addFunc(name);
4384 p->func = bc_program_func(p->fidx); 4422 p->func = bc_program_func(p->fidx);
4385 4423
4386 s = zbc_lex_next(&p->l); 4424 s = zbc_lex_next();
4387 if (s) RETURN_STATUS(s); 4425 if (s) RETURN_STATUS(s);
4388 if (p->l.lex != BC_LEX_LPAREN) 4426 if (p->l.lex != BC_LEX_LPAREN)
4389 RETURN_STATUS(bc_error("bad function definition")); 4427 RETURN_STATUS(bc_error("bad function definition"));
4390 s = zbc_lex_next(&p->l); 4428 s = zbc_lex_next();
4391 if (s) RETURN_STATUS(s); 4429 if (s) RETURN_STATUS(s);
4392 4430
4393 while (p->l.lex != BC_LEX_RPAREN) { 4431 while (p->l.lex != BC_LEX_RPAREN) {
@@ -4397,13 +4435,13 @@ static BC_STATUS zbc_parse_funcdef(BcParse *p)
4397 ++p->func->nparams; 4435 ++p->func->nparams;
4398 4436
4399 name = xstrdup(p->l.lex_buf.v); 4437 name = xstrdup(p->l.lex_buf.v);
4400 s = zbc_lex_next(&p->l); 4438 s = zbc_lex_next();
4401 if (s) goto err; 4439 if (s) goto err;
4402 4440
4403 var = p->l.lex != BC_LEX_LBRACKET; 4441 var = p->l.lex != BC_LEX_LBRACKET;
4404 4442
4405 if (!var) { 4443 if (!var) {
4406 s = zbc_lex_next(&p->l); 4444 s = zbc_lex_next();
4407 if (s) goto err; 4445 if (s) goto err;
4408 4446
4409 if (p->l.lex != BC_LEX_RBRACKET) { 4447 if (p->l.lex != BC_LEX_RBRACKET) {
@@ -4411,13 +4449,13 @@ static BC_STATUS zbc_parse_funcdef(BcParse *p)
4411 goto err; 4449 goto err;
4412 } 4450 }
4413 4451
4414 s = zbc_lex_next(&p->l); 4452 s = zbc_lex_next();
4415 if (s) goto err; 4453 if (s) goto err;
4416 } 4454 }
4417 4455
4418 comma = p->l.lex == BC_LEX_COMMA; 4456 comma = p->l.lex == BC_LEX_COMMA;
4419 if (comma) { 4457 if (comma) {
4420 s = zbc_lex_next(&p->l); 4458 s = zbc_lex_next();
4421 if (s) goto err; 4459 if (s) goto err;
4422 } 4460 }
4423 4461
@@ -4427,7 +4465,7 @@ static BC_STATUS zbc_parse_funcdef(BcParse *p)
4427 4465
4428 if (comma) RETURN_STATUS(bc_error("bad function definition")); 4466 if (comma) RETURN_STATUS(bc_error("bad function definition"));
4429 4467
4430 s = zbc_lex_next(&p->l); 4468 s = zbc_lex_next();
4431 if (s) RETURN_STATUS(s); 4469 if (s) RETURN_STATUS(s);
4432 4470
4433 if (p->l.lex != BC_LEX_LBRACE) { 4471 if (p->l.lex != BC_LEX_LBRACE) {
@@ -4436,18 +4474,18 @@ static BC_STATUS zbc_parse_funcdef(BcParse *p)
4436 } 4474 }
4437 4475
4438 // Prevent "define z()<newline>" from being interpreted as function with empty stmt as body 4476 // Prevent "define z()<newline>" from being interpreted as function with empty stmt as body
4439 s = zbc_lex_skip_if_at_NLINE(&p->l); 4477 s = zbc_lex_skip_if_at_NLINE();
4440 if (s) RETURN_STATUS(s); 4478 if (s) RETURN_STATUS(s);
4441 //GNU bc requires a {} block even if function body has single stmt, enforce this? 4479 //GNU bc requires a {} block even if function body has single stmt, enforce this?
4442 if (p->l.lex != BC_LEX_LBRACE) 4480 if (p->l.lex != BC_LEX_LBRACE)
4443 RETURN_STATUS(bc_error("function { body } expected")); 4481 RETURN_STATUS(bc_error("function { body } expected"));
4444 4482
4445 p->in_funcdef++; // to determine whether "return" stmt is allowed, and such 4483 p->in_funcdef++; // to determine whether "return" stmt is allowed, and such
4446 s = zbc_parse_stmt_possibly_auto(p, true); 4484 s = zbc_parse_stmt_possibly_auto(true);
4447 p->in_funcdef--; 4485 p->in_funcdef--;
4448 if (s) RETURN_STATUS(s); 4486 if (s) RETURN_STATUS(s);
4449 4487
4450 bc_parse_push(p, BC_INST_RET0); 4488 bc_parse_push(BC_INST_RET0);
4451 4489
4452 // Subsequent code generation is into main program 4490 // Subsequent code generation is into main program
4453 p->fidx = BC_PROG_MAIN; 4491 p->fidx = BC_PROG_MAIN;
@@ -4462,13 +4500,14 @@ static BC_STATUS zbc_parse_funcdef(BcParse *p)
4462} 4500}
4463#define zbc_parse_funcdef(...) (zbc_parse_funcdef(__VA_ARGS__) COMMA_SUCCESS) 4501#define zbc_parse_funcdef(...) (zbc_parse_funcdef(__VA_ARGS__) COMMA_SUCCESS)
4464 4502
4465static BC_STATUS zbc_parse_auto(BcParse *p) 4503static BC_STATUS zbc_parse_auto(void)
4466{ 4504{
4505 BcParse *p = &G.prs;
4467 BcStatus s; 4506 BcStatus s;
4468 char *name; 4507 char *name;
4469 4508
4470 dbg_lex_enter("%s:%d entered", __func__, __LINE__); 4509 dbg_lex_enter("%s:%d entered", __func__, __LINE__);
4471 s = zbc_lex_next(&p->l); 4510 s = zbc_lex_next();
4472 if (s) RETURN_STATUS(s); 4511 if (s) RETURN_STATUS(s);
4473 4512
4474 for (;;) { 4513 for (;;) {
@@ -4478,19 +4517,19 @@ static BC_STATUS zbc_parse_auto(BcParse *p)
4478 RETURN_STATUS(bc_error("bad 'auto' syntax")); 4517 RETURN_STATUS(bc_error("bad 'auto' syntax"));
4479 4518
4480 name = xstrdup(p->l.lex_buf.v); 4519 name = xstrdup(p->l.lex_buf.v);
4481 s = zbc_lex_next(&p->l); 4520 s = zbc_lex_next();
4482 if (s) goto err; 4521 if (s) goto err;
4483 4522
4484 var = (p->l.lex != BC_LEX_LBRACKET); 4523 var = (p->l.lex != BC_LEX_LBRACKET);
4485 if (!var) { 4524 if (!var) {
4486 s = zbc_lex_next(&p->l); 4525 s = zbc_lex_next();
4487 if (s) goto err; 4526 if (s) goto err;
4488 4527
4489 if (p->l.lex != BC_LEX_RBRACKET) { 4528 if (p->l.lex != BC_LEX_RBRACKET) {
4490 s = bc_error("bad 'auto' syntax"); 4529 s = bc_error("bad 'auto' syntax");
4491 goto err; 4530 goto err;
4492 } 4531 }
4493 s = zbc_lex_next(&p->l); 4532 s = zbc_lex_next();
4494 if (s) goto err; 4533 if (s) goto err;
4495 } 4534 }
4496 4535
@@ -4505,7 +4544,7 @@ static BC_STATUS zbc_parse_auto(BcParse *p)
4505 } 4544 }
4506 if (p->l.lex != BC_LEX_COMMA) 4545 if (p->l.lex != BC_LEX_COMMA)
4507 RETURN_STATUS(bc_error("bad 'auto' syntax")); 4546 RETURN_STATUS(bc_error("bad 'auto' syntax"));
4508 s = zbc_lex_next(&p->l); // skip comma 4547 s = zbc_lex_next(); // skip comma
4509 if (s) RETURN_STATUS(s); 4548 if (s) RETURN_STATUS(s);
4510 } 4549 }
4511 4550
@@ -4519,38 +4558,39 @@ static BC_STATUS zbc_parse_auto(BcParse *p)
4519#define zbc_parse_auto(...) (zbc_parse_auto(__VA_ARGS__) COMMA_SUCCESS) 4558#define zbc_parse_auto(...) (zbc_parse_auto(__VA_ARGS__) COMMA_SUCCESS)
4520 4559
4521#undef zbc_parse_stmt_possibly_auto 4560#undef zbc_parse_stmt_possibly_auto
4522static BC_STATUS zbc_parse_stmt_possibly_auto(BcParse *p, bool auto_allowed) 4561static BC_STATUS zbc_parse_stmt_possibly_auto(bool auto_allowed)
4523{ 4562{
4563 BcParse *p = &G.prs;
4524 BcStatus s = BC_STATUS_SUCCESS; 4564 BcStatus s = BC_STATUS_SUCCESS;
4525 4565
4526 dbg_lex_enter("%s:%d entered, p->l.lex:%d", __func__, __LINE__, p->l.lex); 4566 dbg_lex_enter("%s:%d entered, p->l.lex:%d", __func__, __LINE__, p->l.lex);
4527 4567
4528 if (p->l.lex == XC_LEX_NLINE) { 4568 if (p->l.lex == XC_LEX_NLINE) {
4529 dbg_lex_done("%s:%d done (seen XC_LEX_NLINE)", __func__, __LINE__); 4569 dbg_lex_done("%s:%d done (seen XC_LEX_NLINE)", __func__, __LINE__);
4530 RETURN_STATUS(zbc_lex_next(&p->l)); 4570 RETURN_STATUS(zbc_lex_next());
4531 } 4571 }
4532 if (p->l.lex == BC_LEX_SCOLON) { 4572 if (p->l.lex == BC_LEX_SCOLON) {
4533 dbg_lex_done("%s:%d done (seen BC_LEX_SCOLON)", __func__, __LINE__); 4573 dbg_lex_done("%s:%d done (seen BC_LEX_SCOLON)", __func__, __LINE__);
4534 RETURN_STATUS(zbc_lex_next(&p->l)); 4574 RETURN_STATUS(zbc_lex_next());
4535 } 4575 }
4536 4576
4537 if (p->l.lex == BC_LEX_LBRACE) { 4577 if (p->l.lex == BC_LEX_LBRACE) {
4538 dbg_lex("%s:%d BC_LEX_LBRACE: (auto_allowed:%d)", __func__, __LINE__, auto_allowed); 4578 dbg_lex("%s:%d BC_LEX_LBRACE: (auto_allowed:%d)", __func__, __LINE__, auto_allowed);
4539 do { 4579 do {
4540 s = zbc_lex_next(&p->l); 4580 s = zbc_lex_next();
4541 if (s) RETURN_STATUS(s); 4581 if (s) RETURN_STATUS(s);
4542 } while (p->l.lex == XC_LEX_NLINE); 4582 } while (p->l.lex == XC_LEX_NLINE);
4543 if (auto_allowed && p->l.lex == BC_LEX_KEY_AUTO) { 4583 if (auto_allowed && p->l.lex == BC_LEX_KEY_AUTO) {
4544 dbg_lex("%s:%d calling zbc_parse_auto()", __func__, __LINE__); 4584 dbg_lex("%s:%d calling zbc_parse_auto()", __func__, __LINE__);
4545 s = zbc_parse_auto(p); 4585 s = zbc_parse_auto();
4546 if (s) RETURN_STATUS(s); 4586 if (s) RETURN_STATUS(s);
4547 } 4587 }
4548 while (p->l.lex != BC_LEX_RBRACE) { 4588 while (p->l.lex != BC_LEX_RBRACE) {
4549 dbg_lex("%s:%d block parsing loop", __func__, __LINE__); 4589 dbg_lex("%s:%d block parsing loop", __func__, __LINE__);
4550 s = zbc_parse_stmt(p); 4590 s = zbc_parse_stmt();
4551 if (s) RETURN_STATUS(s); 4591 if (s) RETURN_STATUS(s);
4552 } 4592 }
4553 s = zbc_lex_next(&p->l); 4593 s = zbc_lex_next();
4554 dbg_lex_done("%s:%d done (seen BC_LEX_RBRACE)", __func__, __LINE__); 4594 dbg_lex_done("%s:%d done (seen BC_LEX_RBRACE)", __func__, __LINE__);
4555 RETURN_STATUS(s); 4595 RETURN_STATUS(s);
4556 } 4596 }
@@ -4571,25 +4611,25 @@ static BC_STATUS zbc_parse_stmt_possibly_auto(BcParse *p, bool auto_allowed)
4571 case BC_LEX_KEY_READ: 4611 case BC_LEX_KEY_READ:
4572 case BC_LEX_KEY_SCALE: 4612 case BC_LEX_KEY_SCALE:
4573 case BC_LEX_KEY_SQRT: 4613 case BC_LEX_KEY_SQRT:
4574 s = zbc_parse_expr(p, BC_PARSE_PRINT); 4614 s = zbc_parse_expr(BC_PARSE_PRINT);
4575 break; 4615 break;
4576 case XC_LEX_STR: 4616 case XC_LEX_STR:
4577 s = zbc_parse_pushSTR(p); 4617 s = zbc_parse_pushSTR();
4578 bc_parse_push(p, XC_INST_PRINT_STR); 4618 bc_parse_push(XC_INST_PRINT_STR);
4579 break; 4619 break;
4580 case BC_LEX_KEY_BREAK: 4620 case BC_LEX_KEY_BREAK:
4581 case BC_LEX_KEY_CONTINUE: 4621 case BC_LEX_KEY_CONTINUE:
4582 s = zbc_parse_break_or_continue(p, p->l.lex); 4622 s = zbc_parse_break_or_continue(p->l.lex);
4583 break; 4623 break;
4584 case BC_LEX_KEY_FOR: 4624 case BC_LEX_KEY_FOR:
4585 s = zbc_parse_for(p); 4625 s = zbc_parse_for();
4586 break; 4626 break;
4587 case BC_LEX_KEY_HALT: 4627 case BC_LEX_KEY_HALT:
4588 bc_parse_push(p, BC_INST_HALT); 4628 bc_parse_push(BC_INST_HALT);
4589 s = zbc_lex_next(&p->l); 4629 s = zbc_lex_next();
4590 break; 4630 break;
4591 case BC_LEX_KEY_IF: 4631 case BC_LEX_KEY_IF:
4592 s = zbc_parse_if(p); 4632 s = zbc_parse_if();
4593 break; 4633 break;
4594 case BC_LEX_KEY_LIMITS: 4634 case BC_LEX_KEY_LIMITS:
4595 // "limits" is a compile-time command, 4635 // "limits" is a compile-time command,
@@ -4604,10 +4644,10 @@ static BC_STATUS zbc_parse_stmt_possibly_auto(BcParse *p, bool auto_allowed)
4604 "MAX Exponent = "BC_MAX_EXP_STR "\n" 4644 "MAX Exponent = "BC_MAX_EXP_STR "\n"
4605 "Number of vars = "BC_MAX_VARS_STR "\n" 4645 "Number of vars = "BC_MAX_VARS_STR "\n"
4606 ); 4646 );
4607 s = zbc_lex_next(&p->l); 4647 s = zbc_lex_next();
4608 break; 4648 break;
4609 case BC_LEX_KEY_PRINT: 4649 case BC_LEX_KEY_PRINT:
4610 s = zbc_parse_print(p); 4650 s = zbc_parse_print();
4611 break; 4651 break;
4612 case BC_LEX_KEY_QUIT: 4652 case BC_LEX_KEY_QUIT:
4613 // "quit" is a compile-time command. For example, 4653 // "quit" is a compile-time command. For example,
@@ -4617,10 +4657,10 @@ static BC_STATUS zbc_parse_stmt_possibly_auto(BcParse *p, bool auto_allowed)
4617 case BC_LEX_KEY_RETURN: 4657 case BC_LEX_KEY_RETURN:
4618 if (!p->in_funcdef) 4658 if (!p->in_funcdef)
4619 RETURN_STATUS(bc_error("'return' not in a function")); 4659 RETURN_STATUS(bc_error("'return' not in a function"));
4620 s = zbc_parse_return(p); 4660 s = zbc_parse_return();
4621 break; 4661 break;
4622 case BC_LEX_KEY_WHILE: 4662 case BC_LEX_KEY_WHILE:
4623 s = zbc_parse_while(p); 4663 s = zbc_parse_while();
4624 break; 4664 break;
4625 default: 4665 default:
4626 s = bc_error_bad_token(); 4666 s = bc_error_bad_token();
@@ -4632,8 +4672,9 @@ static BC_STATUS zbc_parse_stmt_possibly_auto(BcParse *p, bool auto_allowed)
4632} 4672}
4633#define zbc_parse_stmt_possibly_auto(...) (zbc_parse_stmt_possibly_auto(__VA_ARGS__) COMMA_SUCCESS) 4673#define zbc_parse_stmt_possibly_auto(...) (zbc_parse_stmt_possibly_auto(__VA_ARGS__) COMMA_SUCCESS)
4634 4674
4635static BC_STATUS zbc_parse_stmt_or_funcdef(BcParse *p) 4675static BC_STATUS zbc_parse_stmt_or_funcdef(void)
4636{ 4676{
4677 BcParse *p = &G.prs;
4637 BcStatus s; 4678 BcStatus s;
4638 4679
4639 dbg_lex_enter("%s:%d entered", __func__, __LINE__); 4680 dbg_lex_enter("%s:%d entered", __func__, __LINE__);
@@ -4641,10 +4682,10 @@ static BC_STATUS zbc_parse_stmt_or_funcdef(BcParse *p)
4641 s = bc_error("end of file"); 4682 s = bc_error("end of file");
4642 else if (p->l.lex == BC_LEX_KEY_DEFINE) { 4683 else if (p->l.lex == BC_LEX_KEY_DEFINE) {
4643 dbg_lex("%s:%d p->l.lex:BC_LEX_KEY_DEFINE", __func__, __LINE__); 4684 dbg_lex("%s:%d p->l.lex:BC_LEX_KEY_DEFINE", __func__, __LINE__);
4644 s = zbc_parse_funcdef(p); 4685 s = zbc_parse_funcdef();
4645 } else { 4686 } else {
4646 dbg_lex("%s:%d p->l.lex:%d (not BC_LEX_KEY_DEFINE)", __func__, __LINE__, p->l.lex); 4687 dbg_lex("%s:%d p->l.lex:%d (not BC_LEX_KEY_DEFINE)", __func__, __LINE__, p->l.lex);
4647 s = zbc_parse_stmt(p); 4688 s = zbc_parse_stmt();
4648 } 4689 }
4649 4690
4650 dbg_lex_done("%s:%d done", __func__, __LINE__); 4691 dbg_lex_done("%s:%d done", __func__, __LINE__);
@@ -4653,8 +4694,9 @@ static BC_STATUS zbc_parse_stmt_or_funcdef(BcParse *p)
4653#define zbc_parse_stmt_or_funcdef(...) (zbc_parse_stmt_or_funcdef(__VA_ARGS__) COMMA_SUCCESS) 4694#define zbc_parse_stmt_or_funcdef(...) (zbc_parse_stmt_or_funcdef(__VA_ARGS__) COMMA_SUCCESS)
4654 4695
4655// This is not a "z" function: can also return BC_STATUS_PARSE_EMPTY_EXP 4696// This is not a "z" function: can also return BC_STATUS_PARSE_EMPTY_EXP
4656static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags) 4697static BcStatus bc_parse_expr_empty_ok(uint8_t flags)
4657{ 4698{
4699 BcParse *p = &G.prs;
4658 BcInst prev = XC_INST_PRINT; 4700 BcInst prev = XC_INST_PRINT;
4659 size_t nexprs = 0, ops_bgn = p->ops.len; 4701 size_t nexprs = 0, ops_bgn = p->ops.len;
4660 unsigned nparens, nrelops; 4702 unsigned nparens, nrelops;
@@ -4680,12 +4722,12 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags)
4680 switch (t) { 4722 switch (t) {
4681 case BC_LEX_OP_INC: 4723 case BC_LEX_OP_INC:
4682 case BC_LEX_OP_DEC: 4724 case BC_LEX_OP_DEC:
4683 s = zbc_parse_incdec(p, &prev, &paren_expr, &nexprs, flags); 4725 s = zbc_parse_incdec(&prev, &paren_expr, &nexprs, flags);
4684 rprn = bin_last = false; 4726 rprn = bin_last = false;
4685 //get_token = false; - already is 4727 //get_token = false; - already is
4686 break; 4728 break;
4687 case XC_LEX_OP_MINUS: 4729 case XC_LEX_OP_MINUS:
4688 s = zbc_parse_minus(p, &prev, ops_bgn, rprn, &nexprs); 4730 s = zbc_parse_minus(&prev, ops_bgn, rprn, &nexprs);
4689 rprn = false; 4731 rprn = false;
4690 //get_token = false; - already is 4732 //get_token = false; - already is
4691 bin_last = (prev == XC_INST_MINUS); 4733 bin_last = (prev == XC_INST_MINUS);
@@ -4728,8 +4770,8 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags)
4728 } 4770 }
4729 nrelops += (t >= XC_LEX_OP_REL_EQ && t <= XC_LEX_OP_REL_GT); 4771 nrelops += (t >= XC_LEX_OP_REL_EQ && t <= XC_LEX_OP_REL_GT);
4730 prev = BC_TOKEN_2_INST(t); 4772 prev = BC_TOKEN_2_INST(t);
4731 bc_parse_operator(p, t, ops_bgn, &nexprs); 4773 bc_parse_operator(t, ops_bgn, &nexprs);
4732 s = zbc_lex_next(&p->l); 4774 s = zbc_lex_next();
4733 rprn = false; 4775 rprn = false;
4734 //get_token = false; - already is 4776 //get_token = false; - already is
4735 bin_last = (t != BC_LEX_OP_BOOL_NOT); 4777 bin_last = (t != BC_LEX_OP_BOOL_NOT);
@@ -4753,7 +4795,7 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags)
4753 dbg_lex_done("%s:%d done (returning EMPTY_EXP)", __func__, __LINE__); 4795 dbg_lex_done("%s:%d done (returning EMPTY_EXP)", __func__, __LINE__);
4754 return BC_STATUS_PARSE_EMPTY_EXP; 4796 return BC_STATUS_PARSE_EMPTY_EXP;
4755 } 4797 }
4756 s = zbc_parse_rightParen(p, ops_bgn, &nexprs); 4798 s = zbc_parse_rightParen(ops_bgn, &nexprs);
4757 nparens--; 4799 nparens--;
4758 get_token = true; 4800 get_token = true;
4759 paren_expr = rprn = true; 4801 paren_expr = rprn = true;
@@ -4762,7 +4804,7 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags)
4762 case XC_LEX_NAME: 4804 case XC_LEX_NAME:
4763 if (BC_PARSE_LEAF(prev, rprn)) 4805 if (BC_PARSE_LEAF(prev, rprn))
4764 return bc_error_bad_expression(); 4806 return bc_error_bad_expression();
4765 s = zbc_parse_name(p, &prev, flags & ~BC_PARSE_NOCALL); 4807 s = zbc_parse_name(&prev, flags & ~BC_PARSE_NOCALL);
4766 paren_expr = true; 4808 paren_expr = true;
4767 rprn = bin_last = false; 4809 rprn = bin_last = false;
4768 //get_token = false; - already is 4810 //get_token = false; - already is
@@ -4771,7 +4813,7 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags)
4771 case XC_LEX_NUMBER: 4813 case XC_LEX_NUMBER:
4772 if (BC_PARSE_LEAF(prev, rprn)) 4814 if (BC_PARSE_LEAF(prev, rprn))
4773 return bc_error_bad_expression(); 4815 return bc_error_bad_expression();
4774 bc_parse_pushNUM(p); 4816 bc_parse_pushNUM();
4775 prev = XC_INST_NUM; 4817 prev = XC_INST_NUM;
4776 get_token = true; 4818 get_token = true;
4777 paren_expr = true; 4819 paren_expr = true;
@@ -4784,7 +4826,7 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags)
4784 if (BC_PARSE_LEAF(prev, rprn)) 4826 if (BC_PARSE_LEAF(prev, rprn))
4785 return bc_error_bad_expression(); 4827 return bc_error_bad_expression();
4786 prev = (char) (t - BC_LEX_KEY_IBASE + XC_INST_IBASE); 4828 prev = (char) (t - BC_LEX_KEY_IBASE + XC_INST_IBASE);
4787 bc_parse_push(p, (char) prev); 4829 bc_parse_push((char) prev);
4788 get_token = true; 4830 get_token = true;
4789 paren_expr = true; 4831 paren_expr = true;
4790 rprn = bin_last = false; 4832 rprn = bin_last = false;
@@ -4794,7 +4836,7 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags)
4794 case BC_LEX_KEY_SQRT: 4836 case BC_LEX_KEY_SQRT:
4795 if (BC_PARSE_LEAF(prev, rprn)) 4837 if (BC_PARSE_LEAF(prev, rprn))
4796 return bc_error_bad_expression(); 4838 return bc_error_bad_expression();
4797 s = zbc_parse_builtin(p, t, flags, &prev); 4839 s = zbc_parse_builtin(t, flags, &prev);
4798 get_token = true; 4840 get_token = true;
4799 paren_expr = true; 4841 paren_expr = true;
4800 rprn = bin_last = false; 4842 rprn = bin_last = false;
@@ -4803,7 +4845,7 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags)
4803 case BC_LEX_KEY_READ: 4845 case BC_LEX_KEY_READ:
4804 if (BC_PARSE_LEAF(prev, rprn)) 4846 if (BC_PARSE_LEAF(prev, rprn))
4805 return bc_error_bad_expression(); 4847 return bc_error_bad_expression();
4806 s = zbc_parse_read(p); 4848 s = zbc_parse_read();
4807 prev = XC_INST_READ; 4849 prev = XC_INST_READ;
4808 get_token = true; 4850 get_token = true;
4809 paren_expr = true; 4851 paren_expr = true;
@@ -4813,7 +4855,7 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags)
4813 case BC_LEX_KEY_SCALE: 4855 case BC_LEX_KEY_SCALE:
4814 if (BC_PARSE_LEAF(prev, rprn)) 4856 if (BC_PARSE_LEAF(prev, rprn))
4815 return bc_error_bad_expression(); 4857 return bc_error_bad_expression();
4816 s = zbc_parse_scale(p, &prev, flags); 4858 s = zbc_parse_scale(&prev, flags);
4817 prev = XC_INST_SCALE; 4859 prev = XC_INST_SCALE;
4818 //get_token = false; - already is 4860 //get_token = false; - already is
4819 paren_expr = true; 4861 paren_expr = true;
@@ -4827,7 +4869,7 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags)
4827 if (s || G_interrupt) // error, or ^C: stop parsing 4869 if (s || G_interrupt) // error, or ^C: stop parsing
4828 return BC_STATUS_FAILURE; 4870 return BC_STATUS_FAILURE;
4829 if (get_token) { 4871 if (get_token) {
4830 s = zbc_lex_next(&p->l); 4872 s = zbc_lex_next();
4831 if (s) return s; 4873 if (s) return s;
4832 } 4874 }
4833 } 4875 }
@@ -4840,7 +4882,7 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags)
4840 if (top == BC_LEX_LPAREN || top == BC_LEX_RPAREN) 4882 if (top == BC_LEX_LPAREN || top == BC_LEX_RPAREN)
4841 return bc_error_bad_expression(); 4883 return bc_error_bad_expression();
4842 4884
4843 bc_parse_push(p, BC_TOKEN_2_INST(top)); 4885 bc_parse_push(BC_TOKEN_2_INST(top));
4844 4886
4845 nexprs -= (top != BC_LEX_OP_BOOL_NOT && top != XC_LEX_NEG); 4887 nexprs -= (top != BC_LEX_OP_BOOL_NOT && top != XC_LEX_NEG);
4846 bc_vec_pop(&p->ops); 4888 bc_vec_pop(&p->ops);
@@ -4861,8 +4903,8 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags)
4861 4903
4862 if (flags & BC_PARSE_PRINT) { 4904 if (flags & BC_PARSE_PRINT) {
4863 if (paren_first || !assign) 4905 if (paren_first || !assign)
4864 bc_parse_push(p, XC_INST_PRINT); 4906 bc_parse_push(XC_INST_PRINT);
4865 bc_parse_push(p, XC_INST_POP); 4907 bc_parse_push(XC_INST_POP);
4866 } 4908 }
4867 4909
4868 dbg_lex_done("%s:%d done", __func__, __LINE__); 4910 dbg_lex_done("%s:%d done", __func__, __LINE__);
@@ -4873,30 +4915,32 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags)
4873 4915
4874#if ENABLE_DC 4916#if ENABLE_DC
4875 4917
4876static BC_STATUS zdc_parse_register(BcParse *p) 4918static BC_STATUS zdc_parse_register(void)
4877{ 4919{
4920 BcParse *p = &G.prs;
4878 BcStatus s; 4921 BcStatus s;
4879 4922
4880 s = zbc_lex_next(&p->l); 4923 s = zbc_lex_next();
4881 if (s) RETURN_STATUS(s); 4924 if (s) RETURN_STATUS(s);
4882 if (p->l.lex != XC_LEX_NAME) RETURN_STATUS(bc_error_bad_token()); 4925 if (p->l.lex != XC_LEX_NAME) RETURN_STATUS(bc_error_bad_token());
4883 4926
4884 bc_parse_pushName(p, p->l.lex_buf.v); 4927 bc_parse_pushName(p->l.lex_buf.v);
4885 4928
4886 RETURN_STATUS(s); 4929 RETURN_STATUS(s);
4887} 4930}
4888#define zdc_parse_register(...) (zdc_parse_register(__VA_ARGS__) COMMA_SUCCESS) 4931#define zdc_parse_register(...) (zdc_parse_register(__VA_ARGS__) COMMA_SUCCESS)
4889 4932
4890static void dc_parse_string(BcParse *p) 4933static void dc_parse_string(void)
4891{ 4934{
4935 BcParse *p = &G.prs;
4892 char *str; 4936 char *str;
4893 size_t len = G.prog.strs.len; 4937 size_t len = G.prog.strs.len;
4894 4938
4895 dbg_lex_enter("%s:%d entered", __func__, __LINE__); 4939 dbg_lex_enter("%s:%d entered", __func__, __LINE__);
4896 4940
4897 str = xstrdup(p->l.lex_buf.v); 4941 str = xstrdup(p->l.lex_buf.v);
4898 bc_parse_push(p, XC_INST_STR); 4942 bc_parse_push(XC_INST_STR);
4899 bc_parse_pushIndex(p, len); 4943 bc_parse_pushIndex(len);
4900 bc_vec_push(&G.prog.strs, &str); 4944 bc_vec_push(&G.prog.strs, &str);
4901 4945
4902 // Explanation needed here 4946 // Explanation needed here
@@ -4906,55 +4950,56 @@ static void dc_parse_string(BcParse *p)
4906 dbg_lex_done("%s:%d done", __func__, __LINE__); 4950 dbg_lex_done("%s:%d done", __func__, __LINE__);
4907} 4951}
4908 4952
4909static BC_STATUS zdc_parse_mem(BcParse *p, uint8_t inst, bool name, bool store) 4953static BC_STATUS zdc_parse_mem(uint8_t inst, bool name, bool store)
4910{ 4954{
4911 BcStatus s; 4955 BcStatus s;
4912 4956
4913 bc_parse_push(p, inst); 4957 bc_parse_push(inst);
4914 if (name) { 4958 if (name) {
4915 s = zdc_parse_register(p); 4959 s = zdc_parse_register();
4916 if (s) RETURN_STATUS(s); 4960 if (s) RETURN_STATUS(s);
4917 } 4961 }
4918 4962
4919 if (store) { 4963 if (store) {
4920 bc_parse_push(p, DC_INST_SWAP); 4964 bc_parse_push(DC_INST_SWAP);
4921 bc_parse_push(p, XC_INST_ASSIGN); 4965 bc_parse_push(XC_INST_ASSIGN);
4922 bc_parse_push(p, XC_INST_POP); 4966 bc_parse_push(XC_INST_POP);
4923 } 4967 }
4924 4968
4925 RETURN_STATUS(BC_STATUS_SUCCESS); 4969 RETURN_STATUS(BC_STATUS_SUCCESS);
4926} 4970}
4927#define zdc_parse_mem(...) (zdc_parse_mem(__VA_ARGS__) COMMA_SUCCESS) 4971#define zdc_parse_mem(...) (zdc_parse_mem(__VA_ARGS__) COMMA_SUCCESS)
4928 4972
4929static BC_STATUS zdc_parse_cond(BcParse *p, uint8_t inst) 4973static BC_STATUS zdc_parse_cond(uint8_t inst)
4930{ 4974{
4975 BcParse *p = &G.prs;
4931 BcStatus s; 4976 BcStatus s;
4932 4977
4933 bc_parse_push(p, inst); 4978 bc_parse_push(inst);
4934 bc_parse_push(p, DC_INST_EXEC_COND); 4979 bc_parse_push(DC_INST_EXEC_COND);
4935 4980
4936 s = zdc_parse_register(p); 4981 s = zdc_parse_register();
4937 if (s) RETURN_STATUS(s); 4982 if (s) RETURN_STATUS(s);
4938 4983
4939 s = zbc_lex_next(&p->l); 4984 s = zbc_lex_next();
4940 if (s) RETURN_STATUS(s); 4985 if (s) RETURN_STATUS(s);
4941 4986
4942 // Note that 'else' part can not be on the next line: 4987 // Note that 'else' part can not be on the next line:
4943 // echo -e '[1p]sa [2p]sb 2 1>a eb' | dc - OK, prints "2" 4988 // echo -e '[1p]sa [2p]sb 2 1>a eb' | dc - OK, prints "2"
4944 // echo -e '[1p]sa [2p]sb 2 1>a\neb' | dc - parse error 4989 // echo -e '[1p]sa [2p]sb 2 1>a\neb' | dc - parse error
4945 if (p->l.lex == DC_LEX_ELSE) { 4990 if (p->l.lex == DC_LEX_ELSE) {
4946 s = zdc_parse_register(p); 4991 s = zdc_parse_register();
4947 if (s) RETURN_STATUS(s); 4992 if (s) RETURN_STATUS(s);
4948 s = zbc_lex_next(&p->l); 4993 s = zbc_lex_next();
4949 } else { 4994 } else {
4950 bc_parse_push(p, BC_PARSE_STREND); 4995 bc_parse_push(BC_PARSE_STREND);
4951 } 4996 }
4952 4997
4953 RETURN_STATUS(s); 4998 RETURN_STATUS(s);
4954} 4999}
4955#define zdc_parse_cond(...) (zdc_parse_cond(__VA_ARGS__) COMMA_SUCCESS) 5000#define zdc_parse_cond(...) (zdc_parse_cond(__VA_ARGS__) COMMA_SUCCESS)
4956 5001
4957static BC_STATUS zdc_parse_token(BcParse *p, BcLexType t) 5002static BC_STATUS zdc_parse_token(BcLexType t)
4958{ 5003{
4959 BcStatus s; 5004 BcStatus s;
4960 uint8_t inst; 5005 uint8_t inst;
@@ -4971,88 +5016,90 @@ static BC_STATUS zdc_parse_token(BcParse *p, BcLexType t)
4971 case XC_LEX_OP_REL_LT: 5016 case XC_LEX_OP_REL_LT:
4972 case XC_LEX_OP_REL_GT: 5017 case XC_LEX_OP_REL_GT:
4973 dbg_lex("%s:%d LEX_OP_REL_xyz", __func__, __LINE__); 5018 dbg_lex("%s:%d LEX_OP_REL_xyz", __func__, __LINE__);
4974 s = zdc_parse_cond(p, t - XC_LEX_OP_REL_EQ + XC_INST_REL_EQ); 5019 s = zdc_parse_cond(t - XC_LEX_OP_REL_EQ + XC_INST_REL_EQ);
4975 get_token = false; 5020 get_token = false;
4976 break; 5021 break;
4977 case DC_LEX_SCOLON: 5022 case DC_LEX_SCOLON:
4978 case DC_LEX_COLON: 5023 case DC_LEX_COLON:
4979 dbg_lex("%s:%d LEX_[S]COLON", __func__, __LINE__); 5024 dbg_lex("%s:%d LEX_[S]COLON", __func__, __LINE__);
4980 s = zdc_parse_mem(p, XC_INST_ARRAY_ELEM, true, t == DC_LEX_COLON); 5025 s = zdc_parse_mem(XC_INST_ARRAY_ELEM, true, t == DC_LEX_COLON);
4981 break; 5026 break;
4982 case XC_LEX_STR: 5027 case XC_LEX_STR:
4983 dbg_lex("%s:%d LEX_STR", __func__, __LINE__); 5028 dbg_lex("%s:%d LEX_STR", __func__, __LINE__);
4984 dc_parse_string(p); 5029 dc_parse_string();
4985 break; 5030 break;
4986 case XC_LEX_NEG: 5031 case XC_LEX_NEG:
4987 dbg_lex("%s:%d LEX_NEG", __func__, __LINE__); 5032 dbg_lex("%s:%d LEX_NEG", __func__, __LINE__);
4988 s = zbc_lex_next(&p->l); 5033 s = zbc_lex_next();
4989 if (s) RETURN_STATUS(s); 5034 if (s) RETURN_STATUS(s);
4990 if (p->l.lex != XC_LEX_NUMBER) 5035 if (G.prs.l.lex != XC_LEX_NUMBER)
4991 RETURN_STATUS(bc_error_bad_token()); 5036 RETURN_STATUS(bc_error_bad_token());
4992 bc_parse_pushNUM(p); 5037 bc_parse_pushNUM();
4993 bc_parse_push(p, XC_INST_NEG); 5038 bc_parse_push(XC_INST_NEG);
4994 break; 5039 break;
4995 case XC_LEX_NUMBER: 5040 case XC_LEX_NUMBER:
4996 dbg_lex("%s:%d LEX_NUMBER", __func__, __LINE__); 5041 dbg_lex("%s:%d LEX_NUMBER", __func__, __LINE__);
4997 bc_parse_pushNUM(p); 5042 bc_parse_pushNUM();
4998 break; 5043 break;
4999 case DC_LEX_READ: 5044 case DC_LEX_READ:
5000 dbg_lex("%s:%d LEX_KEY_READ", __func__, __LINE__); 5045 dbg_lex("%s:%d LEX_KEY_READ", __func__, __LINE__);
5001 bc_parse_push(p, XC_INST_READ); 5046 bc_parse_push(XC_INST_READ);
5002 break; 5047 break;
5003 case DC_LEX_OP_ASSIGN: 5048 case DC_LEX_OP_ASSIGN:
5004 case DC_LEX_STORE_PUSH: 5049 case DC_LEX_STORE_PUSH:
5005 dbg_lex("%s:%d LEX_OP_ASSIGN/STORE_PUSH", __func__, __LINE__); 5050 dbg_lex("%s:%d LEX_OP_ASSIGN/STORE_PUSH", __func__, __LINE__);
5006 assign = (t == DC_LEX_OP_ASSIGN); 5051 assign = (t == DC_LEX_OP_ASSIGN);
5007 inst = assign ? XC_INST_VAR : DC_INST_PUSH_TO_VAR; 5052 inst = assign ? XC_INST_VAR : DC_INST_PUSH_TO_VAR;
5008 s = zdc_parse_mem(p, inst, true, assign); 5053 s = zdc_parse_mem(inst, true, assign);
5009 break; 5054 break;
5010 case DC_LEX_LOAD: 5055 case DC_LEX_LOAD:
5011 case DC_LEX_LOAD_POP: 5056 case DC_LEX_LOAD_POP:
5012 dbg_lex("%s:%d LEX_OP_LOAD[_POP]", __func__, __LINE__); 5057 dbg_lex("%s:%d LEX_OP_LOAD[_POP]", __func__, __LINE__);
5013 inst = t == DC_LEX_LOAD_POP ? DC_INST_PUSH_VAR : DC_INST_LOAD; 5058 inst = t == DC_LEX_LOAD_POP ? DC_INST_PUSH_VAR : DC_INST_LOAD;
5014 s = zdc_parse_mem(p, inst, true, false); 5059 s = zdc_parse_mem(inst, true, false);
5015 break; 5060 break;
5016 case DC_LEX_STORE_IBASE: 5061 case DC_LEX_STORE_IBASE:
5017 case DC_LEX_STORE_SCALE: 5062 case DC_LEX_STORE_SCALE:
5018 case DC_LEX_STORE_OBASE: 5063 case DC_LEX_STORE_OBASE:
5019 dbg_lex("%s:%d LEX_OP_STORE_I/OBASE/SCALE", __func__, __LINE__); 5064 dbg_lex("%s:%d LEX_OP_STORE_I/OBASE/SCALE", __func__, __LINE__);
5020 inst = t - DC_LEX_STORE_IBASE + XC_INST_IBASE; 5065 inst = t - DC_LEX_STORE_IBASE + XC_INST_IBASE;
5021 s = zdc_parse_mem(p, inst, false, true); 5066 s = zdc_parse_mem(inst, false, true);
5022 break; 5067 break;
5023 default: 5068 default:
5024 dbg_lex_done("%s:%d done (bad token)", __func__, __LINE__); 5069 dbg_lex_done("%s:%d done (bad token)", __func__, __LINE__);
5025 RETURN_STATUS(bc_error_bad_token()); 5070 RETURN_STATUS(bc_error_bad_token());
5026 } 5071 }
5027 5072
5028 if (!s && get_token) s = zbc_lex_next(&p->l); 5073 if (!s && get_token) s = zbc_lex_next();
5029 5074
5030 dbg_lex_done("%s:%d done", __func__, __LINE__); 5075 dbg_lex_done("%s:%d done", __func__, __LINE__);
5031 RETURN_STATUS(s); 5076 RETURN_STATUS(s);
5032} 5077}
5033#define zdc_parse_token(...) (zdc_parse_token(__VA_ARGS__) COMMA_SUCCESS) 5078#define zdc_parse_token(...) (zdc_parse_token(__VA_ARGS__) COMMA_SUCCESS)
5034 5079
5035static BC_STATUS zdc_parse_expr(BcParse *p) 5080static BC_STATUS zdc_parse_expr(void)
5036{ 5081{
5082 BcParse *p = &G.prs;
5037 int i; 5083 int i;
5038 5084
5039 i = (int)p->l.lex - (int)XC_LEX_OP_POWER; 5085 i = (int)p->l.lex - (int)XC_LEX_OP_POWER;
5040 if (i >= 0) { 5086 if (i >= 0) {
5041 BcInst inst = dc_LEX_to_INST[i]; 5087 BcInst inst = dc_LEX_to_INST[i];
5042 if (inst != DC_INST_INVALID) { 5088 if (inst != DC_INST_INVALID) {
5043 bc_parse_push(p, inst); 5089 bc_parse_push(inst);
5044 RETURN_STATUS(zbc_lex_next(&p->l)); 5090 RETURN_STATUS(zbc_lex_next());
5045 } 5091 }
5046 } 5092 }
5047 RETURN_STATUS(zdc_parse_token(p, p->l.lex)); 5093 RETURN_STATUS(zdc_parse_token(p->l.lex));
5048} 5094}
5049#define zdc_parse_expr(...) (zdc_parse_expr(__VA_ARGS__) COMMA_SUCCESS) 5095#define zdc_parse_expr(...) (zdc_parse_expr(__VA_ARGS__) COMMA_SUCCESS)
5050 5096
5051static BC_STATUS zdc_parse_exprs_until_eof(BcParse *p) 5097static BC_STATUS zdc_parse_exprs_until_eof(void)
5052{ 5098{
5099 BcParse *p = &G.prs;
5053 dbg_lex_enter("%s:%d entered, p->l.lex:%d", __func__, __LINE__, p->l.lex); 5100 dbg_lex_enter("%s:%d entered, p->l.lex:%d", __func__, __LINE__, p->l.lex);
5054 while (p->l.lex != XC_LEX_EOF) { 5101 while (p->l.lex != XC_LEX_EOF) {
5055 BcStatus s = zdc_parse_expr(p); 5102 BcStatus s = zdc_parse_expr();
5056 if (s) RETURN_STATUS(s); 5103 if (s) RETURN_STATUS(s);
5057 } 5104 }
5058 5105
@@ -5269,15 +5316,15 @@ static BC_STATUS zbc_program_read(void)
5269 bc_vec_pop_all(&f->code); 5316 bc_vec_pop_all(&f->code);
5270 5317
5271 sv_parse = G.prs; // struct copy 5318 sv_parse = G.prs; // struct copy
5272 bc_parse_create(&G.prs, BC_PROG_READ); 5319 bc_parse_create(BC_PROG_READ);
5273 //bc_lex_file(&G.prs.l); - not needed, error line info is not printed for read() 5320 //bc_lex_file(&G.prs.l); - not needed, error line info is not printed for read()
5274 5321
5275 s = zbc_parse_text_init(&G.prs, buf.v); 5322 s = zbc_parse_text_init(buf.v);
5276 if (s) goto exec_err; 5323 if (s) goto exec_err;
5277 if (IS_BC) { 5324 if (IS_BC) {
5278 IF_BC(s = zbc_parse_expr(&G.prs, 0)); 5325 IF_BC(s = zbc_parse_expr(0));
5279 } else { 5326 } else {
5280 IF_DC(s = zdc_parse_exprs_until_eof(&G.prs)); 5327 IF_DC(s = zdc_parse_exprs_until_eof());
5281 } 5328 }
5282 if (s) goto exec_err; 5329 if (s) goto exec_err;
5283 5330
@@ -5290,11 +5337,11 @@ static BC_STATUS zbc_program_read(void)
5290 ip.inst_idx = 0; 5337 ip.inst_idx = 0;
5291 IF_BC(ip.results_len_before_call = G.prog.results.len;) 5338 IF_BC(ip.results_len_before_call = G.prog.results.len;)
5292 5339
5293 bc_parse_push(&G.prs, XC_INST_RET); 5340 bc_parse_push(XC_INST_RET);
5294 bc_vec_push(&G.prog.exestack, &ip); 5341 bc_vec_push(&G.prog.exestack, &ip);
5295 5342
5296 exec_err: 5343 exec_err:
5297 bc_parse_free(&G.prs); 5344 bc_parse_free();
5298 G.prs = sv_parse; // struct copy 5345 G.prs = sv_parse; // struct copy
5299 bc_vec_free(&buf); 5346 bc_vec_free(&buf);
5300 RETURN_STATUS(s); 5347 RETURN_STATUS(s);
@@ -6404,17 +6451,17 @@ static BC_STATUS zdc_program_execStr(char *code, size_t *bgn, bool cond)
6404 char *str; 6451 char *str;
6405 6452
6406 sv_parse = G.prs; // struct copy 6453 sv_parse = G.prs; // struct copy
6407 bc_parse_create(&G.prs, fidx); 6454 bc_parse_create(fidx);
6408 str = *bc_program_str(sidx); 6455 str = *bc_program_str(sidx);
6409 s = zbc_parse_text_init(&G.prs, str); 6456 s = zbc_parse_text_init(str);
6410 if (s) goto err; 6457 if (s) goto err;
6411 6458
6412 s = zdc_parse_exprs_until_eof(&G.prs); 6459 s = zdc_parse_exprs_until_eof();
6413 if (s) goto err; 6460 if (s) goto err;
6414 bc_parse_push(&G.prs, DC_INST_POP_EXEC); 6461 bc_parse_push(DC_INST_POP_EXEC);
6415 if (G.prs.l.lex != XC_LEX_EOF) 6462 if (G.prs.l.lex != XC_LEX_EOF)
6416 s = bc_error_bad_expression(); 6463 s = bc_error_bad_expression();
6417 bc_parse_free(&G.prs); 6464 bc_parse_free();
6418 G.prs = sv_parse; // struct copy 6465 G.prs = sv_parse; // struct copy
6419 if (s) { 6466 if (s) {
6420 err: 6467 err:
@@ -6745,7 +6792,7 @@ static BC_STATUS zbc_vm_process(const char *text)
6745 BcStatus s; 6792 BcStatus s;
6746 6793
6747 dbg_lex_enter("%s:%d entered", __func__, __LINE__); 6794 dbg_lex_enter("%s:%d entered", __func__, __LINE__);
6748 s = zbc_parse_text_init(&G.prs, text); // does the first zbc_lex_next() 6795 s = zbc_parse_text_init(text); // does the first zbc_lex_next()
6749 if (s) RETURN_STATUS(s); 6796 if (s) RETURN_STATUS(s);
6750 6797
6751 IF_BC(check_eof:) 6798 IF_BC(check_eof:)
@@ -6759,12 +6806,12 @@ static BC_STATUS zbc_vm_process(const char *text)
6759 if (G.prs.l.lex == BC_LEX_SCOLON 6806 if (G.prs.l.lex == BC_LEX_SCOLON
6760 || G.prs.l.lex == XC_LEX_NLINE 6807 || G.prs.l.lex == XC_LEX_NLINE
6761 ) { 6808 ) {
6762 s = zbc_lex_next(&G.prs.l); 6809 s = zbc_lex_next();
6763 if (s) goto err; 6810 if (s) goto err;
6764 goto check_eof; 6811 goto check_eof;
6765 } 6812 }
6766 6813
6767 s = zbc_parse_stmt_or_funcdef(&G.prs); 6814 s = zbc_parse_stmt_or_funcdef();
6768 if (s) goto err; 6815 if (s) goto err;
6769 6816
6770 // Check that next token is a correct stmt delimiter - 6817 // Check that next token is a correct stmt delimiter -
@@ -6790,17 +6837,17 @@ static BC_STATUS zbc_vm_process(const char *text)
6790 // Most of dc parsing assumes all whitespace, 6837 // Most of dc parsing assumes all whitespace,
6791 // including '\n', is eaten. 6838 // including '\n', is eaten.
6792 while (G.prs.l.lex == XC_LEX_NLINE) { 6839 while (G.prs.l.lex == XC_LEX_NLINE) {
6793 s = zbc_lex_next(&G.prs.l); 6840 s = zbc_lex_next();
6794 if (s) goto err; 6841 if (s) goto err;
6795 if (G.prs.l.lex == XC_LEX_EOF) 6842 if (G.prs.l.lex == XC_LEX_EOF)
6796 goto done; 6843 goto done;
6797 } 6844 }
6798 s = zdc_parse_expr(&G.prs); 6845 s = zdc_parse_expr();
6799#endif 6846#endif
6800 } 6847 }
6801 if (s || G_interrupt) { 6848 if (s || G_interrupt) {
6802 err: 6849 err:
6803 bc_parse_reset(&G.prs); // includes bc_program_reset() 6850 bc_parse_reset(); // includes bc_program_reset()
6804 RETURN_STATUS(BC_STATUS_FAILURE); 6851 RETURN_STATUS(BC_STATUS_FAILURE);
6805 } 6852 }
6806 6853
@@ -6872,7 +6919,7 @@ static BC_STATUS zbc_vm_execute_FILE(FILE *fp, const char *filename)
6872 6919
6873 G.prs.filename = filename; 6920 G.prs.filename = filename;
6874 G.prs.input_fp = fp; 6921 G.prs.input_fp = fp;
6875 bc_lex_file(&G.prs.l); 6922 bc_lex_file();
6876 6923
6877 do { 6924 do {
6878 s = zbc_vm_process(""); 6925 s = zbc_vm_process("");
@@ -7153,7 +7200,7 @@ static BC_STATUS zbc_vm_exec(void)
7153 // We know that internal library is not buggy, 7200 // We know that internal library is not buggy,
7154 // thus error checking is normally disabled. 7201 // thus error checking is normally disabled.
7155# define DEBUG_LIB 0 7202# define DEBUG_LIB 0
7156 bc_lex_file(&G.prs.l); 7203 bc_lex_file();
7157 s = zbc_vm_process(bc_lib); 7204 s = zbc_vm_process(bc_lib);
7158 if (DEBUG_LIB && s) RETURN_STATUS(s); 7205 if (DEBUG_LIB && s) RETURN_STATUS(s);
7159 } 7206 }
@@ -7202,7 +7249,7 @@ static void bc_vm_free(void)
7202{ 7249{
7203 bc_vec_free(&G.files); 7250 bc_vec_free(&G.files);
7204 bc_program_free(); 7251 bc_program_free();
7205 bc_parse_free(&G.prs); 7252 bc_parse_free();
7206 free(G.env_args); 7253 free(G.env_args);
7207} 7254}
7208#endif 7255#endif
@@ -7266,7 +7313,7 @@ static int bc_vm_init(const char *env_len)
7266 bc_vec_init(&G.files, sizeof(char *), NULL); 7313 bc_vec_init(&G.files, sizeof(char *), NULL);
7267 IF_BC(if (IS_BC) bc_vm_envArgs();) 7314 IF_BC(if (IS_BC) bc_vm_envArgs();)
7268 bc_program_init(); 7315 bc_program_init();
7269 bc_parse_create(&G.prs, BC_PROG_MAIN); 7316 bc_parse_create(BC_PROG_MAIN);
7270 7317
7271//TODO: in GNU bc, the check is (isatty(0) && isatty(1)), 7318//TODO: in GNU bc, the check is (isatty(0) && isatty(1)),
7272//-i option unconditionally enables this regardless of isatty(): 7319//-i option unconditionally enables this regardless of isatty():