aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-12-25 22:32:41 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-12-25 22:32:41 +0100
commitecb62edd478e8ae2b1a5f3d122e316345909a805 (patch)
treedfdffd86d089fcb1041554f010d89242bd0409bc
parent6e6182342ef59c47972a49543cd8b15dc4f28f6d (diff)
downloadbusybox-w32-ecb62edd478e8ae2b1a5f3d122e316345909a805.tar.gz
busybox-w32-ecb62edd478e8ae2b1a5f3d122e316345909a805.tar.bz2
busybox-w32-ecb62edd478e8ae2b1a5f3d122e316345909a805.zip
bc: fold struct BcLex into BcParse
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--miscutils/bc.c529
1 files changed, 262 insertions, 267 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c
index 44d4976cc..61fb24304 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -710,7 +710,7 @@ dc_LEX_to_INST[] = { // starts at XC_LEX_OP_POWER // corresponding XC/DC_L
710}; 710};
711#endif // ENABLE_DC 711#endif // ENABLE_DC
712 712
713typedef struct BcLex { 713typedef struct BcParse {
714 smallint lex; // was BcLexType // first member is most used 714 smallint lex; // was BcLexType // first member is most used
715 smallint lex_last; // was BcLexType 715 smallint lex_last; // was BcLexType
716 bool lex_newline; 716 bool lex_newline;
@@ -719,14 +719,9 @@ typedef struct BcLex {
719 size_t lex_len; 719 size_t lex_len;
720 const char *lex_inbuf; 720 const char *lex_inbuf;
721 const char *lex_next_at; // last lex_next() was called at this string 721 const char *lex_next_at; // last lex_next() was called at this string
722 const char *lex_filename;
723 FILE *lex_input_fp;
722 BcVec lex_strnumbuf; 724 BcVec lex_strnumbuf;
723} BcLex;
724
725typedef struct BcParse {
726 BcLex l; // first member is most used
727
728 const char *filename;
729 FILE *input_fp;
730 725
731 BcFunc *func; 726 BcFunc *func;
732 size_t fidx; 727 size_t fidx;
@@ -937,12 +932,12 @@ static void quit(void)
937static void bc_verror_msg(const char *fmt, va_list p) 932static void bc_verror_msg(const char *fmt, va_list p)
938{ 933{
939 const char *sv = sv; // for compiler 934 const char *sv = sv; // for compiler
940 if (G.prs.filename) { 935 if (G.prs.lex_filename) {
941 sv = applet_name; 936 sv = applet_name;
942 applet_name = xasprintf("%s: %s:%u", applet_name, G.prs.filename, G.err_line); 937 applet_name = xasprintf("%s: %s:%u", applet_name, G.prs.lex_filename, G.err_line);
943 } 938 }
944 bb_verror_msg(fmt, p, NULL); 939 bb_verror_msg(fmt, p, NULL);
945 if (G.prs.filename) { 940 if (G.prs.lex_filename) {
946 free((char*)applet_name); 941 free((char*)applet_name);
947 applet_name = sv; 942 applet_name = sv;
948 } 943 }
@@ -2582,12 +2577,12 @@ static void bc_read_line(BcVec *vec, FILE *fp)
2582 2577
2583 if (bad_chars) { 2578 if (bad_chars) {
2584 // Bad chars on this line 2579 // Bad chars on this line
2585 if (!G.prs.filename) { // stdin 2580 if (!G.prs.lex_filename) { // stdin
2586 // ignore entire line, get another one 2581 // ignore entire line, get another one
2587 vec->len = len; 2582 vec->len = len;
2588 goto again; 2583 goto again;
2589 } 2584 }
2590 bb_perror_msg_and_die("file '%s' is not text", G.prs.filename); 2585 bb_perror_msg_and_die("file '%s' is not text", G.prs.lex_filename);
2591 } 2586 }
2592 bc_vec_pushZeroByte(vec); 2587 bc_vec_pushZeroByte(vec);
2593 } 2588 }
@@ -2751,39 +2746,39 @@ static BC_STATUS zbc_num_parse(BcNum *n, const char *val, unsigned base_t)
2751 2746
2752static void bc_lex_lineComment(void) 2747static void bc_lex_lineComment(void)
2753{ 2748{
2754 BcLex *l = &G.prs.l; 2749 BcParse *p = &G.prs;
2755 // Try: echo -n '#foo' | bc 2750 // Try: echo -n '#foo' | bc
2756 size_t i; 2751 size_t i;
2757 l->lex = XC_LEX_WHITESPACE; 2752 p->lex = XC_LEX_WHITESPACE;
2758 i = l->lex_i; 2753 i = p->lex_i;
2759 while (i < l->lex_len && l->lex_inbuf[i] != '\n') 2754 while (i < p->lex_len && p->lex_inbuf[i] != '\n')
2760 i++; 2755 i++;
2761 l->lex_i = i; 2756 p->lex_i = i;
2762} 2757}
2763 2758
2764static void bc_lex_whitespace(void) 2759static void bc_lex_whitespace(void)
2765{ 2760{
2766 BcLex *l = &G.prs.l; 2761 BcParse *p = &G.prs;
2767 l->lex = XC_LEX_WHITESPACE; 2762 p->lex = XC_LEX_WHITESPACE;
2768 for (;;) { 2763 for (;;) {
2769 char c = l->lex_inbuf[l->lex_i]; 2764 char c = p->lex_inbuf[p->lex_i];
2770 if (c == '\n') // this is XC_LEX_NLINE, not XC_LEX_WHITESPACE 2765 if (c == '\n') // this is XC_LEX_NLINE, not XC_LEX_WHITESPACE
2771 break; 2766 break;
2772 if (!isspace(c)) 2767 if (!isspace(c))
2773 break; 2768 break;
2774 l->lex_i++; 2769 p->lex_i++;
2775 } 2770 }
2776} 2771}
2777 2772
2778static BC_STATUS zbc_lex_number(char start) 2773static BC_STATUS zbc_lex_number(char start)
2779{ 2774{
2780 BcLex *l = &G.prs.l; 2775 BcParse *p = &G.prs;
2781 const char *buf = l->lex_inbuf + l->lex_i; 2776 const char *buf = p->lex_inbuf + p->lex_i;
2782 size_t len, i, ccnt; 2777 size_t len, i, ccnt;
2783 bool pt; 2778 bool pt;
2784 2779
2785 pt = (start == '.'); 2780 pt = (start == '.');
2786 l->lex = XC_LEX_NUMBER; 2781 p->lex = XC_LEX_NUMBER;
2787 ccnt = i = 0; 2782 ccnt = i = 0;
2788 for (;;) { 2783 for (;;) {
2789 char c = buf[i]; 2784 char c = buf[i];
@@ -2808,7 +2803,7 @@ static BC_STATUS zbc_lex_number(char start)
2808 //ccnt is the number of chars in the number string, excluding possible 2803 //ccnt is the number of chars in the number string, excluding possible
2809 //trailing "[\<newline>].[\<newline>]" (with any number of \<NL> repetitions). 2804 //trailing "[\<newline>].[\<newline>]" (with any number of \<NL> repetitions).
2810 //i is buf[i] index of the first not-yet-parsed char after that. 2805 //i is buf[i] index of the first not-yet-parsed char after that.
2811 l->lex_i += i; 2806 p->lex_i += i;
2812 2807
2813 // This might overestimate the size, if there are "\<NL>"'s 2808 // This might overestimate the size, if there are "\<NL>"'s
2814 // in the number. Subtracting number_of_backslashes*2 correctly 2809 // in the number. Subtracting number_of_backslashes*2 correctly
@@ -2823,9 +2818,9 @@ static BC_STATUS zbc_lex_number(char start)
2823 RETURN_STATUS(bc_error("number too long: must be [1,"BC_MAX_NUM_STR"]")); 2818 RETURN_STATUS(bc_error("number too long: must be [1,"BC_MAX_NUM_STR"]"));
2824 } 2819 }
2825 2820
2826 bc_vec_pop_all(&l->lex_strnumbuf); 2821 bc_vec_pop_all(&p->lex_strnumbuf);
2827 bc_vec_expand(&l->lex_strnumbuf, 1 + len); 2822 bc_vec_expand(&p->lex_strnumbuf, 1 + len);
2828 bc_vec_push(&l->lex_strnumbuf, &start); 2823 bc_vec_push(&p->lex_strnumbuf, &start);
2829 2824
2830 while (ccnt != 0) { 2825 while (ccnt != 0) {
2831 // If we have hit a backslash, skip it. We don't have 2826 // If we have hit a backslash, skip it. We don't have
@@ -2835,12 +2830,12 @@ static BC_STATUS zbc_lex_number(char start)
2835 ccnt -= 2; 2830 ccnt -= 2;
2836 continue; 2831 continue;
2837 } 2832 }
2838 bc_vec_push(&l->lex_strnumbuf, buf); 2833 bc_vec_push(&p->lex_strnumbuf, buf);
2839 buf++; 2834 buf++;
2840 ccnt--; 2835 ccnt--;
2841 } 2836 }
2842 2837
2843 bc_vec_pushZeroByte(&l->lex_strnumbuf); 2838 bc_vec_pushZeroByte(&p->lex_strnumbuf);
2844 2839
2845 RETURN_STATUS(BC_STATUS_SUCCESS); 2840 RETURN_STATUS(BC_STATUS_SUCCESS);
2846} 2841}
@@ -2848,14 +2843,14 @@ static BC_STATUS zbc_lex_number(char start)
2848 2843
2849static void bc_lex_name(void) 2844static void bc_lex_name(void)
2850{ 2845{
2851 BcLex *l = &G.prs.l; 2846 BcParse *p = &G.prs;
2852 size_t i; 2847 size_t i;
2853 const char *buf; 2848 const char *buf;
2854 2849
2855 l->lex = XC_LEX_NAME; 2850 p->lex = XC_LEX_NAME;
2856 2851
2857 i = 0; 2852 i = 0;
2858 buf = l->lex_inbuf + l->lex_i - 1; 2853 buf = p->lex_inbuf + p->lex_i - 1;
2859 for (;;) { 2854 for (;;) {
2860 char c = buf[i]; 2855 char c = buf[i];
2861 if ((c < 'a' || c > 'z') && !isdigit(c) && c != '_') break; 2856 if ((c < 'a' || c > 'z') && !isdigit(c) && c != '_') break;
@@ -2869,33 +2864,33 @@ static void bc_lex_name(void)
2869 return bc_error("name too long: must be [1,"BC_MAX_STRING_STR"]"); 2864 return bc_error("name too long: must be [1,"BC_MAX_STRING_STR"]");
2870 } 2865 }
2871#endif 2866#endif
2872 bc_vec_string(&l->lex_strnumbuf, i, buf); 2867 bc_vec_string(&p->lex_strnumbuf, i, buf);
2873 2868
2874 // Increment the index. We minus 1 because it has already been incremented. 2869 // Increment the index. We minus 1 because it has already been incremented.
2875 l->lex_i += i - 1; 2870 p->lex_i += i - 1;
2876 2871
2877 //return BC_STATUS_SUCCESS; 2872 //return BC_STATUS_SUCCESS;
2878} 2873}
2879 2874
2880static void bc_lex_init(void) 2875static void bc_lex_init(void)
2881{ 2876{
2882 bc_char_vec_init(&G.prs.l.lex_strnumbuf); 2877 bc_char_vec_init(&G.prs.lex_strnumbuf);
2883} 2878}
2884 2879
2885static void bc_lex_free(void) 2880static void bc_lex_free(void)
2886{ 2881{
2887 bc_vec_free(&G.prs.l.lex_strnumbuf); 2882 bc_vec_free(&G.prs.lex_strnumbuf);
2888} 2883}
2889 2884
2890static void bc_lex_file(void) 2885static void bc_lex_file(void)
2891{ 2886{
2892 G.err_line = G.prs.l.lex_line = 1; 2887 G.err_line = G.prs.lex_line = 1;
2893 G.prs.l.lex_newline = false; 2888 G.prs.lex_newline = false;
2894} 2889}
2895 2890
2896static bool bc_lex_more_input(void) 2891static bool bc_lex_more_input(void)
2897{ 2892{
2898 BcLex *l = &G.prs.l; 2893 BcParse *p = &G.prs;
2899 size_t str; 2894 size_t str;
2900 bool comment; 2895 bool comment;
2901 2896
@@ -2911,7 +2906,7 @@ static bool bc_lex_more_input(void)
2911 size_t prevlen = G.input_buffer.len; 2906 size_t prevlen = G.input_buffer.len;
2912 char *string; 2907 char *string;
2913 2908
2914 bc_read_line(&G.input_buffer, G.prs.input_fp); 2909 bc_read_line(&G.input_buffer, G.prs.lex_input_fp);
2915 // No more input means EOF 2910 // No more input means EOF
2916 if (G.input_buffer.len <= prevlen + 1) // (we expect +1 for NUL byte) 2911 if (G.input_buffer.len <= prevlen + 1) // (we expect +1 for NUL byte)
2917 break; 2912 break;
@@ -2958,12 +2953,12 @@ static bool bc_lex_more_input(void)
2958 break; 2953 break;
2959 } 2954 }
2960 2955
2961 l->lex_inbuf = G.input_buffer.v; 2956 p->lex_inbuf = G.input_buffer.v;
2962 l->lex_i = 0; 2957 p->lex_i = 0;
2963// bb_error_msg("G.input_buffer.len:%d '%s'", G.input_buffer.len, G.input_buffer.v); 2958// bb_error_msg("G.input_buffer.len:%d '%s'", G.input_buffer.len, G.input_buffer.v);
2964 l->lex_len = G.input_buffer.len - 1; // do not include NUL 2959 p->lex_len = G.input_buffer.len - 1; // do not include NUL
2965 2960
2966 return l->lex_len != 0; 2961 return p->lex_len != 0;
2967} 2962}
2968 2963
2969IF_BC(static BC_STATUS zbc_lex_token(void);) 2964IF_BC(static BC_STATUS zbc_lex_token(void);)
@@ -2973,43 +2968,43 @@ IF_DC(static BC_STATUS zdc_lex_token(void);)
2973 2968
2974static BC_STATUS zbc_lex_next(void) 2969static BC_STATUS zbc_lex_next(void)
2975{ 2970{
2976 BcLex *l = &G.prs.l; 2971 BcParse *p = &G.prs;
2977 BcStatus s; 2972 BcStatus s;
2978 2973
2979 l->lex_last = l->lex; 2974 p->lex_last = p->lex;
2980 if (l->lex_last == XC_LEX_EOF) RETURN_STATUS(bc_error("end of file")); 2975 if (p->lex_last == XC_LEX_EOF) RETURN_STATUS(bc_error("end of file"));
2981 2976
2982 l->lex_line += l->lex_newline; 2977 p->lex_line += p->lex_newline;
2983 G.err_line = l->lex_line; 2978 G.err_line = p->lex_line;
2984 l->lex_newline = false; 2979 p->lex_newline = false;
2985 2980
2986 // Loop until failure or we don't have whitespace. This 2981 // Loop until failure or we don't have whitespace. This
2987 // is so the parser doesn't get inundated with whitespace. 2982 // is so the parser doesn't get inundated with whitespace.
2988 // Comments are also XC_LEX_WHITESPACE tokens and eaten here. 2983 // Comments are also XC_LEX_WHITESPACE tokens and eaten here.
2989 s = BC_STATUS_SUCCESS; 2984 s = BC_STATUS_SUCCESS;
2990 do { 2985 do {
2991 if (l->lex_i == l->lex_len) { 2986 if (p->lex_i == p->lex_len) {
2992 l->lex = XC_LEX_EOF; 2987 p->lex = XC_LEX_EOF;
2993 if (!G.prs.input_fp) 2988 if (!G.prs.lex_input_fp)
2994 RETURN_STATUS(BC_STATUS_SUCCESS); 2989 RETURN_STATUS(BC_STATUS_SUCCESS);
2995 if (!bc_lex_more_input()) { 2990 if (!bc_lex_more_input()) {
2996 G.prs.input_fp = NULL; 2991 G.prs.lex_input_fp = NULL;
2997 RETURN_STATUS(BC_STATUS_SUCCESS); 2992 RETURN_STATUS(BC_STATUS_SUCCESS);
2998 } 2993 }
2999 // here it's guaranteed that l->lex_i is below l->lex_len 2994 // here it's guaranteed that p->lex_i is below p->lex_len
3000 } 2995 }
3001 l->lex_next_at = l->lex_inbuf + l->lex_i; 2996 p->lex_next_at = p->lex_inbuf + p->lex_i;
3002 dbg_lex("next string to parse:'%.*s'", 2997 dbg_lex("next string to parse:'%.*s'",
3003 (int)(strchrnul(l->lex_next_at, '\n') - l->lex_next_at), 2998 (int)(strchrnul(p->lex_next_at, '\n') - p->lex_next_at),
3004 l->lex_next_at 2999 p->lex_next_at
3005 ); 3000 );
3006 if (IS_BC) { 3001 if (IS_BC) {
3007 IF_BC(s = zbc_lex_token()); 3002 IF_BC(s = zbc_lex_token());
3008 } else { 3003 } else {
3009 IF_DC(s = zdc_lex_token()); 3004 IF_DC(s = zdc_lex_token());
3010 } 3005 }
3011 } while (!s && l->lex == XC_LEX_WHITESPACE); 3006 } while (!s && p->lex == XC_LEX_WHITESPACE);
3012 dbg_lex("l->lex from string:%d", l->lex); 3007 dbg_lex("p->lex from string:%d", p->lex);
3013 3008
3014 RETURN_STATUS(s); 3009 RETURN_STATUS(s);
3015} 3010}
@@ -3018,7 +3013,7 @@ static BC_STATUS zbc_lex_next(void)
3018#if ENABLE_BC 3013#if ENABLE_BC
3019static BC_STATUS zbc_lex_skip_if_at_NLINE(void) 3014static BC_STATUS zbc_lex_skip_if_at_NLINE(void)
3020{ 3015{
3021 if (G.prs.l.lex == XC_LEX_NLINE) 3016 if (G.prs.lex == XC_LEX_NLINE)
3022 RETURN_STATUS(zbc_lex_next()); 3017 RETURN_STATUS(zbc_lex_next());
3023 RETURN_STATUS(BC_STATUS_SUCCESS); 3018 RETURN_STATUS(BC_STATUS_SUCCESS);
3024} 3019}
@@ -3038,10 +3033,10 @@ static BC_STATUS zbc_lex_next_and_skip_NLINE(void)
3038 3033
3039static BC_STATUS zbc_lex_text_init(const char *text) 3034static BC_STATUS zbc_lex_text_init(const char *text)
3040{ 3035{
3041 G.prs.l.lex_inbuf = text; 3036 G.prs.lex_inbuf = text;
3042 G.prs.l.lex_i = 0; 3037 G.prs.lex_i = 0;
3043 G.prs.l.lex_len = strlen(text); 3038 G.prs.lex_len = strlen(text);
3044 G.prs.l.lex = G.prs.l.lex_last = XC_LEX_INVALID; 3039 G.prs.lex = G.prs.lex_last = XC_LEX_INVALID;
3045 RETURN_STATUS(zbc_lex_next()); 3040 RETURN_STATUS(zbc_lex_next());
3046} 3041}
3047#define zbc_lex_text_init(...) (zbc_lex_text_init(__VA_ARGS__) COMMA_SUCCESS) 3042#define zbc_lex_text_init(...) (zbc_lex_text_init(__VA_ARGS__) COMMA_SUCCESS)
@@ -3049,10 +3044,10 @@ static BC_STATUS zbc_lex_text_init(const char *text)
3049#if ENABLE_BC 3044#if ENABLE_BC
3050static BC_STATUS zbc_lex_identifier(void) 3045static BC_STATUS zbc_lex_identifier(void)
3051{ 3046{
3052 BcLex *l = &G.prs.l; 3047 BcParse *p = &G.prs;
3053 BcStatus s; 3048 BcStatus s;
3054 unsigned i; 3049 unsigned i;
3055 const char *buf = l->lex_inbuf + l->lex_i - 1; 3050 const char *buf = p->lex_inbuf + p->lex_i - 1;
3056 3051
3057 for (i = 0; i < ARRAY_SIZE(bc_lex_kws); ++i) { 3052 for (i = 0; i < ARRAY_SIZE(bc_lex_kws); ++i) {
3058 const char *keyword8 = bc_lex_kws[i].name8; 3053 const char *keyword8 = bc_lex_kws[i].name8;
@@ -3067,21 +3062,21 @@ static BC_STATUS zbc_lex_identifier(void)
3067 // buf starts with keyword bc_lex_kws[i] 3062 // buf starts with keyword bc_lex_kws[i]
3068 if (isalnum(buf[j]) || buf[j]=='_') 3063 if (isalnum(buf[j]) || buf[j]=='_')
3069 continue; // "ifz" does not match "if" keyword, "if." does 3064 continue; // "ifz" does not match "if" keyword, "if." does
3070 l->lex = BC_LEX_KEY_1st_keyword + i; 3065 p->lex = BC_LEX_KEY_1st_keyword + i;
3071 if (!keyword_is_POSIX(i)) { 3066 if (!keyword_is_POSIX(i)) {
3072 s = zbc_posix_error_fmt("%sthe '%.8s' keyword", "POSIX does not allow ", bc_lex_kws[i].name8); 3067 s = zbc_posix_error_fmt("%sthe '%.8s' keyword", "POSIX does not allow ", bc_lex_kws[i].name8);
3073 if (s) RETURN_STATUS(s); 3068 if (s) RETURN_STATUS(s);
3074 } 3069 }
3075 3070
3076 // We minus 1 because the index has already been incremented. 3071 // We minus 1 because the index has already been incremented.
3077 l->lex_i += j - 1; 3072 p->lex_i += j - 1;
3078 RETURN_STATUS(BC_STATUS_SUCCESS); 3073 RETURN_STATUS(BC_STATUS_SUCCESS);
3079 } 3074 }
3080 3075
3081 bc_lex_name(); 3076 bc_lex_name();
3082 s = BC_STATUS_SUCCESS; 3077 s = BC_STATUS_SUCCESS;
3083 3078
3084 if (l->lex_strnumbuf.len > 2) { 3079 if (p->lex_strnumbuf.len > 2) {
3085 // Prevent this: 3080 // Prevent this:
3086 // >>> qwe=1 3081 // >>> qwe=1
3087 // bc: POSIX only allows one character names; this is bad: 'qwe=1 3082 // bc: POSIX only allows one character names; this is bad: 'qwe=1
@@ -3096,17 +3091,17 @@ static BC_STATUS zbc_lex_identifier(void)
3096 3091
3097static BC_STATUS zbc_lex_string(void) 3092static BC_STATUS zbc_lex_string(void)
3098{ 3093{
3099 BcLex *l = &G.prs.l; 3094 BcParse *p = &G.prs;
3100 size_t len, nls, i; 3095 size_t len, nls, i;
3101 3096
3102 l->lex = XC_LEX_STR; 3097 p->lex = XC_LEX_STR;
3103 3098
3104 nls = 0; 3099 nls = 0;
3105 i = l->lex_i; 3100 i = p->lex_i;
3106 for (;;) { 3101 for (;;) {
3107 char c = l->lex_inbuf[i]; 3102 char c = p->lex_inbuf[i];
3108 if (c == '\0') { 3103 if (c == '\0') {
3109 l->lex_i = i; 3104 p->lex_i = i;
3110 RETURN_STATUS(bc_error("unterminated string")); 3105 RETURN_STATUS(bc_error("unterminated string"));
3111 } 3106 }
3112 if (c == '"') 3107 if (c == '"')
@@ -3115,17 +3110,17 @@ static BC_STATUS zbc_lex_string(void)
3115 i++; 3110 i++;
3116 } 3111 }
3117 3112
3118 len = i - l->lex_i; 3113 len = i - p->lex_i;
3119 // This check makes sense only if size_t is (much) larger than BC_MAX_STRING. 3114 // This check makes sense only if size_t is (much) larger than BC_MAX_STRING.
3120 if (SIZE_MAX > (BC_MAX_STRING | 0xff)) { 3115 if (SIZE_MAX > (BC_MAX_STRING | 0xff)) {
3121 if (len > BC_MAX_STRING) 3116 if (len > BC_MAX_STRING)
3122 RETURN_STATUS(bc_error("string too long: must be [1,"BC_MAX_STRING_STR"]")); 3117 RETURN_STATUS(bc_error("string too long: must be [1,"BC_MAX_STRING_STR"]"));
3123 } 3118 }
3124 bc_vec_string(&l->lex_strnumbuf, len, l->lex_inbuf + l->lex_i); 3119 bc_vec_string(&p->lex_strnumbuf, len, p->lex_inbuf + p->lex_i);
3125 3120
3126 l->lex_i = i + 1; 3121 p->lex_i = i + 1;
3127 l->lex_line += nls; 3122 p->lex_line += nls;
3128 G.err_line = l->lex_line; 3123 G.err_line = p->lex_line;
3129 3124
3130 RETURN_STATUS(BC_STATUS_SUCCESS); 3125 RETURN_STATUS(BC_STATUS_SUCCESS);
3131} 3126}
@@ -3133,24 +3128,24 @@ static BC_STATUS zbc_lex_string(void)
3133 3128
3134static void bc_lex_assign(unsigned with_and_without) 3129static void bc_lex_assign(unsigned with_and_without)
3135{ 3130{
3136 BcLex *l = &G.prs.l; 3131 BcParse *p = &G.prs;
3137 if (l->lex_inbuf[l->lex_i] == '=') { 3132 if (p->lex_inbuf[p->lex_i] == '=') {
3138 l->lex_i++; 3133 p->lex_i++;
3139 with_and_without >>= 8; // store "with" value 3134 with_and_without >>= 8; // store "with" value
3140 } // else store "without" value 3135 } // else store "without" value
3141 l->lex = (with_and_without & 0xff); 3136 p->lex = (with_and_without & 0xff);
3142} 3137}
3143#define bc_lex_assign(with, without) \ 3138#define bc_lex_assign(with, without) \
3144 bc_lex_assign(((with)<<8)|(without)) 3139 bc_lex_assign(((with)<<8)|(without))
3145 3140
3146static BC_STATUS zbc_lex_comment(void) 3141static BC_STATUS zbc_lex_comment(void)
3147{ 3142{
3148 BcLex *l = &G.prs.l; 3143 BcParse *p = &G.prs;
3149 size_t i, nls = 0; 3144 size_t i, nls = 0;
3150 const char *buf = l->lex_inbuf; 3145 const char *buf = p->lex_inbuf;
3151 3146
3152 l->lex = XC_LEX_WHITESPACE; 3147 p->lex = XC_LEX_WHITESPACE;
3153 i = l->lex_i; /* here buf[l->lex_i] is the '*' of opening comment delimiter */ 3148 i = p->lex_i; /* here buf[p->lex_i] is the '*' of opening comment delimiter */
3154 for (;;) { 3149 for (;;) {
3155 char c = buf[++i]; 3150 char c = buf[++i];
3156 check_star: 3151 check_star:
@@ -3161,15 +3156,15 @@ static BC_STATUS zbc_lex_comment(void)
3161 goto check_star; 3156 goto check_star;
3162 } 3157 }
3163 if (c == '\0') { 3158 if (c == '\0') {
3164 l->lex_i = i; 3159 p->lex_i = i;
3165 RETURN_STATUS(bc_error("unterminated comment")); 3160 RETURN_STATUS(bc_error("unterminated comment"));
3166 } 3161 }
3167 nls += (c == '\n'); 3162 nls += (c == '\n');
3168 } 3163 }
3169 3164
3170 l->lex_i = i + 1; 3165 p->lex_i = i + 1;
3171 l->lex_line += nls; 3166 p->lex_line += nls;
3172 G.err_line = l->lex_line; 3167 G.err_line = p->lex_line;
3173 3168
3174 RETURN_STATUS(BC_STATUS_SUCCESS); 3169 RETURN_STATUS(BC_STATUS_SUCCESS);
3175} 3170}
@@ -3178,20 +3173,20 @@ static BC_STATUS zbc_lex_comment(void)
3178#undef zbc_lex_token 3173#undef zbc_lex_token
3179static BC_STATUS zbc_lex_token(void) 3174static BC_STATUS zbc_lex_token(void)
3180{ 3175{
3181 BcLex *l = &G.prs.l; 3176 BcParse *p = &G.prs;
3182 BcStatus s = BC_STATUS_SUCCESS; 3177 BcStatus s = BC_STATUS_SUCCESS;
3183 char c = l->lex_inbuf[l->lex_i++], c2; 3178 char c = p->lex_inbuf[p->lex_i++], c2;
3184 3179
3185 // This is the workhorse of the lexer. 3180 // This is the workhorse of the lexer.
3186 switch (c) { 3181 switch (c) {
3187// case '\0': // probably never reached 3182// case '\0': // probably never reached
3188// l->lex_i--; 3183// p->lex_i--;
3189// l->lex = XC_LEX_EOF; 3184// p->lex = XC_LEX_EOF;
3190// l->lex_newline = true; 3185// p->lex_newline = true;
3191// break; 3186// break;
3192 case '\n': 3187 case '\n':
3193 l->lex = XC_LEX_NLINE; 3188 p->lex = XC_LEX_NLINE;
3194 l->lex_newline = true; 3189 p->lex_newline = true;
3195 break; 3190 break;
3196 case '\t': 3191 case '\t':
3197 case '\v': 3192 case '\v':
@@ -3202,7 +3197,7 @@ static BC_STATUS zbc_lex_token(void)
3202 break; 3197 break;
3203 case '!': 3198 case '!':
3204 bc_lex_assign(XC_LEX_OP_REL_NE, BC_LEX_OP_BOOL_NOT); 3199 bc_lex_assign(XC_LEX_OP_REL_NE, BC_LEX_OP_BOOL_NOT);
3205 if (l->lex == BC_LEX_OP_BOOL_NOT) { 3200 if (p->lex == BC_LEX_OP_BOOL_NOT) {
3206 s = zbc_POSIX_does_not_allow_bool_ops_this_is_bad("!"); 3201 s = zbc_POSIX_does_not_allow_bool_ops_this_is_bad("!");
3207 if (s) RETURN_STATUS(s); 3202 if (s) RETURN_STATUS(s);
3208 } 3203 }
@@ -3219,53 +3214,53 @@ static BC_STATUS zbc_lex_token(void)
3219 bc_lex_assign(BC_LEX_OP_ASSIGN_MODULUS, XC_LEX_OP_MODULUS); 3214 bc_lex_assign(BC_LEX_OP_ASSIGN_MODULUS, XC_LEX_OP_MODULUS);
3220 break; 3215 break;
3221 case '&': 3216 case '&':
3222 c2 = l->lex_inbuf[l->lex_i]; 3217 c2 = p->lex_inbuf[p->lex_i];
3223 if (c2 == '&') { 3218 if (c2 == '&') {
3224 s = zbc_POSIX_does_not_allow_bool_ops_this_is_bad("&&"); 3219 s = zbc_POSIX_does_not_allow_bool_ops_this_is_bad("&&");
3225 if (s) RETURN_STATUS(s); 3220 if (s) RETURN_STATUS(s);
3226 l->lex_i++; 3221 p->lex_i++;
3227 l->lex = BC_LEX_OP_BOOL_AND; 3222 p->lex = BC_LEX_OP_BOOL_AND;
3228 } else { 3223 } else {
3229 l->lex = XC_LEX_INVALID; 3224 p->lex = XC_LEX_INVALID;
3230 s = bc_error_bad_character('&'); 3225 s = bc_error_bad_character('&');
3231 } 3226 }
3232 break; 3227 break;
3233 case '(': 3228 case '(':
3234 case ')': 3229 case ')':
3235 l->lex = (BcLexType)(c - '(' + BC_LEX_LPAREN); 3230 p->lex = (BcLexType)(c - '(' + BC_LEX_LPAREN);
3236 break; 3231 break;
3237 case '*': 3232 case '*':
3238 bc_lex_assign(BC_LEX_OP_ASSIGN_MULTIPLY, XC_LEX_OP_MULTIPLY); 3233 bc_lex_assign(BC_LEX_OP_ASSIGN_MULTIPLY, XC_LEX_OP_MULTIPLY);
3239 break; 3234 break;
3240 case '+': 3235 case '+':
3241 c2 = l->lex_inbuf[l->lex_i]; 3236 c2 = p->lex_inbuf[p->lex_i];
3242 if (c2 == '+') { 3237 if (c2 == '+') {
3243 l->lex_i++; 3238 p->lex_i++;
3244 l->lex = BC_LEX_OP_INC; 3239 p->lex = BC_LEX_OP_INC;
3245 } else 3240 } else
3246 bc_lex_assign(BC_LEX_OP_ASSIGN_PLUS, XC_LEX_OP_PLUS); 3241 bc_lex_assign(BC_LEX_OP_ASSIGN_PLUS, XC_LEX_OP_PLUS);
3247 break; 3242 break;
3248 case ',': 3243 case ',':
3249 l->lex = BC_LEX_COMMA; 3244 p->lex = BC_LEX_COMMA;
3250 break; 3245 break;
3251 case '-': 3246 case '-':
3252 c2 = l->lex_inbuf[l->lex_i]; 3247 c2 = p->lex_inbuf[p->lex_i];
3253 if (c2 == '-') { 3248 if (c2 == '-') {
3254 l->lex_i++; 3249 p->lex_i++;
3255 l->lex = BC_LEX_OP_DEC; 3250 p->lex = BC_LEX_OP_DEC;
3256 } else 3251 } else
3257 bc_lex_assign(BC_LEX_OP_ASSIGN_MINUS, XC_LEX_OP_MINUS); 3252 bc_lex_assign(BC_LEX_OP_ASSIGN_MINUS, XC_LEX_OP_MINUS);
3258 break; 3253 break;
3259 case '.': 3254 case '.':
3260 if (isdigit(l->lex_inbuf[l->lex_i])) 3255 if (isdigit(p->lex_inbuf[p->lex_i]))
3261 s = zbc_lex_number(c); 3256 s = zbc_lex_number(c);
3262 else { 3257 else {
3263 l->lex = BC_LEX_KEY_LAST; 3258 p->lex = BC_LEX_KEY_LAST;
3264 s = zbc_POSIX_does_not_allow("'.' as 'last'"); 3259 s = zbc_POSIX_does_not_allow("'.' as 'last'");
3265 } 3260 }
3266 break; 3261 break;
3267 case '/': 3262 case '/':
3268 c2 = l->lex_inbuf[l->lex_i]; 3263 c2 = p->lex_inbuf[p->lex_i];
3269 if (c2 == '*') 3264 if (c2 == '*')
3270 s = zbc_lex_comment(); 3265 s = zbc_lex_comment();
3271 else 3266 else
@@ -3290,7 +3285,7 @@ static BC_STATUS zbc_lex_token(void)
3290 s = zbc_lex_number(c); 3285 s = zbc_lex_number(c);
3291 break; 3286 break;
3292 case ';': 3287 case ';':
3293 l->lex = BC_LEX_SCOLON; 3288 p->lex = BC_LEX_SCOLON;
3294 break; 3289 break;
3295 case '<': 3290 case '<':
3296 bc_lex_assign(XC_LEX_OP_REL_LE, XC_LEX_OP_REL_LT); 3291 bc_lex_assign(XC_LEX_OP_REL_LE, XC_LEX_OP_REL_LT);
@@ -3303,12 +3298,12 @@ static BC_STATUS zbc_lex_token(void)
3303 break; 3298 break;
3304 case '[': 3299 case '[':
3305 case ']': 3300 case ']':
3306 l->lex = (BcLexType)(c - '[' + BC_LEX_LBRACKET); 3301 p->lex = (BcLexType)(c - '[' + BC_LEX_LBRACKET);
3307 break; 3302 break;
3308 case '\\': 3303 case '\\':
3309 if (l->lex_inbuf[l->lex_i] == '\n') { 3304 if (p->lex_inbuf[p->lex_i] == '\n') {
3310 l->lex = XC_LEX_WHITESPACE; 3305 p->lex = XC_LEX_WHITESPACE;
3311 l->lex_i++; 3306 p->lex_i++;
3312 } else 3307 } else
3313 s = bc_error_bad_character(c); 3308 s = bc_error_bad_character(c);
3314 break; 3309 break;
@@ -3345,22 +3340,22 @@ static BC_STATUS zbc_lex_token(void)
3345 break; 3340 break;
3346 case '{': 3341 case '{':
3347 case '}': 3342 case '}':
3348 l->lex = (BcLexType)(c - '{' + BC_LEX_LBRACE); 3343 p->lex = (BcLexType)(c - '{' + BC_LEX_LBRACE);
3349 break; 3344 break;
3350 case '|': 3345 case '|':
3351 c2 = l->lex_inbuf[l->lex_i]; 3346 c2 = p->lex_inbuf[p->lex_i];
3352 if (c2 == '|') { 3347 if (c2 == '|') {
3353 s = zbc_POSIX_does_not_allow_bool_ops_this_is_bad("||"); 3348 s = zbc_POSIX_does_not_allow_bool_ops_this_is_bad("||");
3354 if (s) RETURN_STATUS(s); 3349 if (s) RETURN_STATUS(s);
3355 l->lex_i++; 3350 p->lex_i++;
3356 l->lex = BC_LEX_OP_BOOL_OR; 3351 p->lex = BC_LEX_OP_BOOL_OR;
3357 } else { 3352 } else {
3358 l->lex = XC_LEX_INVALID; 3353 p->lex = XC_LEX_INVALID;
3359 s = bc_error_bad_character(c); 3354 s = bc_error_bad_character(c);
3360 } 3355 }
3361 break; 3356 break;
3362 default: 3357 default:
3363 l->lex = XC_LEX_INVALID; 3358 p->lex = XC_LEX_INVALID;
3364 s = bc_error_bad_character(c); 3359 s = bc_error_bad_character(c);
3365 break; 3360 break;
3366 } 3361 }
@@ -3373,16 +3368,16 @@ static BC_STATUS zbc_lex_token(void)
3373#if ENABLE_DC 3368#if ENABLE_DC
3374static BC_STATUS zdc_lex_register(void) 3369static BC_STATUS zdc_lex_register(void)
3375{ 3370{
3376 BcLex *l = &G.prs.l; 3371 BcParse *p = &G.prs;
3377 if (G_exreg && isspace(l->lex_inbuf[l->lex_i])) { 3372 if (G_exreg && isspace(p->lex_inbuf[p->lex_i])) {
3378 bc_lex_whitespace(); // eats whitespace (but not newline) 3373 bc_lex_whitespace(); // eats whitespace (but not newline)
3379 l->lex_i++; // bc_lex_name() expects this 3374 p->lex_i++; // bc_lex_name() expects this
3380 bc_lex_name(); 3375 bc_lex_name();
3381 } else { 3376 } else {
3382 bc_vec_pop_all(&l->lex_strnumbuf); 3377 bc_vec_pop_all(&p->lex_strnumbuf);
3383 bc_vec_push(&l->lex_strnumbuf, &l->lex_inbuf[l->lex_i++]); 3378 bc_vec_push(&p->lex_strnumbuf, &p->lex_inbuf[p->lex_i++]);
3384 bc_vec_pushZeroByte(&l->lex_strnumbuf); 3379 bc_vec_pushZeroByte(&p->lex_strnumbuf);
3385 l->lex = XC_LEX_NAME; 3380 p->lex = XC_LEX_NAME;
3386 } 3381 }
3387 3382
3388 RETURN_STATUS(BC_STATUS_SUCCESS); 3383 RETURN_STATUS(BC_STATUS_SUCCESS);
@@ -3391,43 +3386,43 @@ static BC_STATUS zdc_lex_register(void)
3391 3386
3392static BC_STATUS zdc_lex_string(void) 3387static BC_STATUS zdc_lex_string(void)
3393{ 3388{
3394 BcLex *l = &G.prs.l; 3389 BcParse *p = &G.prs;
3395 size_t depth, nls, i; 3390 size_t depth, nls, i;
3396 3391
3397 l->lex = XC_LEX_STR; 3392 p->lex = XC_LEX_STR;
3398 bc_vec_pop_all(&l->lex_strnumbuf); 3393 bc_vec_pop_all(&p->lex_strnumbuf);
3399 3394
3400 nls = 0; 3395 nls = 0;
3401 depth = 1; 3396 depth = 1;
3402 i = l->lex_i; 3397 i = p->lex_i;
3403 for (;;) { 3398 for (;;) {
3404 char c = l->lex_inbuf[i]; 3399 char c = p->lex_inbuf[i];
3405 if (c == '\0') { 3400 if (c == '\0') {
3406 l->lex_i = i; 3401 p->lex_i = i;
3407 RETURN_STATUS(bc_error("string end could not be found")); 3402 RETURN_STATUS(bc_error("string end could not be found"));
3408 } 3403 }
3409 nls += (c == '\n'); 3404 nls += (c == '\n');
3410 if (i == l->lex_i || l->lex_inbuf[i - 1] != '\\') { 3405 if (i == p->lex_i || p->lex_inbuf[i - 1] != '\\') {
3411 if (c == '[') depth++; 3406 if (c == '[') depth++;
3412 if (c == ']') 3407 if (c == ']')
3413 if (--depth == 0) 3408 if (--depth == 0)
3414 break; 3409 break;
3415 } 3410 }
3416 bc_vec_push(&l->lex_strnumbuf, &l->lex_inbuf[i]); 3411 bc_vec_push(&p->lex_strnumbuf, &p->lex_inbuf[i]);
3417 i++; 3412 i++;
3418 } 3413 }
3419 i++; 3414 i++;
3420 3415
3421 bc_vec_pushZeroByte(&l->lex_strnumbuf); 3416 bc_vec_pushZeroByte(&p->lex_strnumbuf);
3422 // This check makes sense only if size_t is (much) larger than BC_MAX_STRING. 3417 // This check makes sense only if size_t is (much) larger than BC_MAX_STRING.
3423 if (SIZE_MAX > (BC_MAX_STRING | 0xff)) { 3418 if (SIZE_MAX > (BC_MAX_STRING | 0xff)) {
3424 if (i - l->lex_i > BC_MAX_STRING) 3419 if (i - p->lex_i > BC_MAX_STRING)
3425 RETURN_STATUS(bc_error("string too long: must be [1,"BC_MAX_STRING_STR"]")); 3420 RETURN_STATUS(bc_error("string too long: must be [1,"BC_MAX_STRING_STR"]"));
3426 } 3421 }
3427 3422
3428 l->lex_i = i; 3423 p->lex_i = i;
3429 l->lex_line += nls; 3424 p->lex_line += nls;
3430 G.err_line = l->lex_line; 3425 G.err_line = p->lex_line;
3431 3426
3432 RETURN_STATUS(BC_STATUS_SUCCESS); 3427 RETURN_STATUS(BC_STATUS_SUCCESS);
3433} 3428}
@@ -3436,7 +3431,7 @@ static BC_STATUS zdc_lex_string(void)
3436#undef zdc_lex_token 3431#undef zdc_lex_token
3437static BC_STATUS zdc_lex_token(void) 3432static BC_STATUS zdc_lex_token(void)
3438{ 3433{
3439 BcLex *l = &G.prs.l; 3434 BcParse *p = &G.prs;
3440 static const //BcLexType - should be this type, but narrower type saves size: 3435 static const //BcLexType - should be this type, but narrower type saves size:
3441 uint8_t 3436 uint8_t
3442 dc_lex_regs[] = { 3437 dc_lex_regs[] = {
@@ -3451,14 +3446,14 @@ static BC_STATUS zdc_lex_token(void)
3451 size_t i; 3446 size_t i;
3452 3447
3453 for (i = 0; i < ARRAY_SIZE(dc_lex_regs); ++i) { 3448 for (i = 0; i < ARRAY_SIZE(dc_lex_regs); ++i) {
3454 if (l->lex_last == dc_lex_regs[i]) 3449 if (p->lex_last == dc_lex_regs[i])
3455 RETURN_STATUS(zdc_lex_register()); 3450 RETURN_STATUS(zdc_lex_register());
3456 } 3451 }
3457 3452
3458 s = BC_STATUS_SUCCESS; 3453 s = BC_STATUS_SUCCESS;
3459 c = l->lex_inbuf[l->lex_i++]; 3454 c = p->lex_inbuf[p->lex_i++];
3460 if (c >= '%' && c <= '~' 3455 if (c >= '%' && c <= '~'
3461 && (l->lex = dc_char_to_LEX[c - '%']) != XC_LEX_INVALID 3456 && (p->lex = dc_char_to_LEX[c - '%']) != XC_LEX_INVALID
3462 ) { 3457 ) {
3463 RETURN_STATUS(s); 3458 RETURN_STATUS(s);
3464 } 3459 }
@@ -3466,7 +3461,7 @@ static BC_STATUS zdc_lex_token(void)
3466 // This is the workhorse of the lexer. 3461 // This is the workhorse of the lexer.
3467 switch (c) { 3462 switch (c) {
3468// case '\0': // probably never reached 3463// case '\0': // probably never reached
3469// l->lex = XC_LEX_EOF; 3464// p->lex = XC_LEX_EOF;
3470// break; 3465// break;
3471 case '\n': 3466 case '\n':
3472 // '\n' is XC_LEX_NLINE, not XC_LEX_WHITESPACE 3467 // '\n' is XC_LEX_NLINE, not XC_LEX_WHITESPACE
@@ -3477,34 +3472,34 @@ static BC_STATUS zdc_lex_token(void)
3477 // commands are not executed on pressing <enter>). 3472 // commands are not executed on pressing <enter>).
3478 // IOW: typing "1p<enter>" should print "1" _at once_, 3473 // IOW: typing "1p<enter>" should print "1" _at once_,
3479 // not after some more input. 3474 // not after some more input.
3480 l->lex = XC_LEX_NLINE; 3475 p->lex = XC_LEX_NLINE;
3481 l->lex_newline = true; 3476 p->lex_newline = true;
3482 break; 3477 break;
3483 case '\t': 3478 case '\t':
3484 case '\v': 3479 case '\v':
3485 case '\f': 3480 case '\f':
3486 case '\r': 3481 case '\r':
3487 case ' ': 3482 case ' ':
3488 l->lex_newline = 0; // was (c == '\n') 3483 p->lex_newline = 0; // was (c == '\n')
3489 bc_lex_whitespace(); 3484 bc_lex_whitespace();
3490 break; 3485 break;
3491 case '!': 3486 case '!':
3492 c2 = l->lex_inbuf[l->lex_i]; 3487 c2 = p->lex_inbuf[p->lex_i];
3493 if (c2 == '=') 3488 if (c2 == '=')
3494 l->lex = XC_LEX_OP_REL_NE; 3489 p->lex = XC_LEX_OP_REL_NE;
3495 else if (c2 == '<') 3490 else if (c2 == '<')
3496 l->lex = XC_LEX_OP_REL_LE; 3491 p->lex = XC_LEX_OP_REL_LE;
3497 else if (c2 == '>') 3492 else if (c2 == '>')
3498 l->lex = XC_LEX_OP_REL_GE; 3493 p->lex = XC_LEX_OP_REL_GE;
3499 else 3494 else
3500 RETURN_STATUS(bc_error_bad_character(c)); 3495 RETURN_STATUS(bc_error_bad_character(c));
3501 l->lex_i++; 3496 p->lex_i++;
3502 break; 3497 break;
3503 case '#': 3498 case '#':
3504 bc_lex_lineComment(); 3499 bc_lex_lineComment();
3505 break; 3500 break;
3506 case '.': 3501 case '.':
3507 if (isdigit(l->lex_inbuf[l->lex_i])) 3502 if (isdigit(p->lex_inbuf[p->lex_i]))
3508 s = zbc_lex_number(c); 3503 s = zbc_lex_number(c);
3509 else 3504 else
3510 s = bc_error_bad_character(c); 3505 s = bc_error_bad_character(c);
@@ -3531,7 +3526,7 @@ static BC_STATUS zdc_lex_token(void)
3531 s = zdc_lex_string(); 3526 s = zdc_lex_string();
3532 break; 3527 break;
3533 default: 3528 default:
3534 l->lex = XC_LEX_INVALID; 3529 p->lex = XC_LEX_INVALID;
3535 s = bc_error_bad_character(c); 3530 s = bc_error_bad_character(c);
3536 break; 3531 break;
3537 } 3532 }
@@ -3593,7 +3588,7 @@ static void bc_parse_pushJUMP_ZERO(size_t idx)
3593static BC_STATUS zbc_parse_pushSTR(void) 3588static BC_STATUS zbc_parse_pushSTR(void)
3594{ 3589{
3595 BcParse *p = &G.prs; 3590 BcParse *p = &G.prs;
3596 char *str = xstrdup(p->l.lex_strnumbuf.v); 3591 char *str = xstrdup(p->lex_strnumbuf.v);
3597 3592
3598 bc_parse_push(XC_INST_STR); 3593 bc_parse_push(XC_INST_STR);
3599 bc_parse_pushIndex(p->func->strs.len); 3594 bc_parse_pushIndex(p->func->strs.len);
@@ -3607,7 +3602,7 @@ static BC_STATUS zbc_parse_pushSTR(void)
3607static void bc_parse_pushNUM(void) 3602static void bc_parse_pushNUM(void)
3608{ 3603{
3609 BcParse *p = &G.prs; 3604 BcParse *p = &G.prs;
3610 char *num = xstrdup(p->l.lex_strnumbuf.v); 3605 char *num = xstrdup(p->lex_strnumbuf.v);
3611#if ENABLE_BC && ENABLE_DC 3606#if ENABLE_BC && ENABLE_DC
3612 size_t idx = bc_vec_push(IS_BC ? &p->func->consts : &G.prog.consts, &num); 3607 size_t idx = bc_vec_push(IS_BC ? &p->func->consts : &G.prog.consts, &num);
3613#elif ENABLE_BC 3608#elif ENABLE_BC
@@ -3656,8 +3651,8 @@ static void bc_parse_reset(void)
3656 p->func = bc_program_func_BC_PROG_MAIN(); 3651 p->func = bc_program_func_BC_PROG_MAIN();
3657 } 3652 }
3658 3653
3659 p->l.lex_i = p->l.lex_len; 3654 p->lex_i = p->lex_len;
3660 p->l.lex = XC_LEX_EOF; 3655 p->lex = XC_LEX_EOF;
3661 3656
3662 IF_BC(bc_vec_pop_all(&p->exits);) 3657 IF_BC(bc_vec_pop_all(&p->exits);)
3663 IF_BC(bc_vec_pop_all(&p->conds);) 3658 IF_BC(bc_vec_pop_all(&p->conds);)
@@ -3765,7 +3760,7 @@ static BC_STATUS zbc_parse_stmt_allow_NLINE_before(const char *after_X)
3765 // Same for "else", "while()", "for()". 3760 // Same for "else", "while()", "for()".
3766 BcStatus s = zbc_lex_next_and_skip_NLINE(); 3761 BcStatus s = zbc_lex_next_and_skip_NLINE();
3767 if (s) RETURN_STATUS(s); 3762 if (s) RETURN_STATUS(s);
3768 if (p->l.lex == XC_LEX_NLINE) 3763 if (p->lex == XC_LEX_NLINE)
3769 RETURN_STATUS(bc_error_fmt("no statement after '%s'", after_X)); 3764 RETURN_STATUS(bc_error_fmt("no statement after '%s'", after_X));
3770 3765
3771 RETURN_STATUS(zbc_parse_stmt()); 3766 RETURN_STATUS(zbc_parse_stmt());
@@ -3825,20 +3820,20 @@ static BC_STATUS zbc_parse_params(uint8_t flags)
3825 BcStatus s; 3820 BcStatus s;
3826 size_t nparams; 3821 size_t nparams;
3827 3822
3828 dbg_lex("%s:%d p->l.lex:%d", __func__, __LINE__, p->l.lex); 3823 dbg_lex("%s:%d p->lex:%d", __func__, __LINE__, p->lex);
3829 flags = (flags & ~(BC_PARSE_PRINT | BC_PARSE_REL)) | BC_PARSE_ARRAY; 3824 flags = (flags & ~(BC_PARSE_PRINT | BC_PARSE_REL)) | BC_PARSE_ARRAY;
3830 3825
3831 s = zbc_lex_next(); 3826 s = zbc_lex_next();
3832 if (s) RETURN_STATUS(s); 3827 if (s) RETURN_STATUS(s);
3833 3828
3834 nparams = 0; 3829 nparams = 0;
3835 if (p->l.lex != BC_LEX_RPAREN) { 3830 if (p->lex != BC_LEX_RPAREN) {
3836 for (;;) { 3831 for (;;) {
3837 s = zbc_parse_expr(flags); 3832 s = zbc_parse_expr(flags);
3838 if (s) RETURN_STATUS(s); 3833 if (s) RETURN_STATUS(s);
3839 nparams++; 3834 nparams++;
3840 if (p->l.lex != BC_LEX_COMMA) { 3835 if (p->lex != BC_LEX_COMMA) {
3841 if (p->l.lex == BC_LEX_RPAREN) 3836 if (p->lex == BC_LEX_RPAREN)
3842 break; 3837 break;
3843 RETURN_STATUS(bc_error_bad_token()); 3838 RETURN_STATUS(bc_error_bad_token());
3844 } 3839 }
@@ -3867,7 +3862,7 @@ static BC_STATUS zbc_parse_call(char *name, uint8_t flags)
3867 s = zbc_parse_params(flags); 3862 s = zbc_parse_params(flags);
3868 if (s) goto err; 3863 if (s) goto err;
3869 3864
3870 if (p->l.lex != BC_LEX_RPAREN) { 3865 if (p->lex != BC_LEX_RPAREN) {
3871 s = bc_error_bad_token(); 3866 s = bc_error_bad_token();
3872 goto err; 3867 goto err;
3873 } 3868 }
@@ -3897,15 +3892,15 @@ static BC_STATUS zbc_parse_name(BcInst *type, uint8_t flags)
3897 BcStatus s; 3892 BcStatus s;
3898 char *name; 3893 char *name;
3899 3894
3900 name = xstrdup(p->l.lex_strnumbuf.v); 3895 name = xstrdup(p->lex_strnumbuf.v);
3901 s = zbc_lex_next(); 3896 s = zbc_lex_next();
3902 if (s) goto err; 3897 if (s) goto err;
3903 3898
3904 if (p->l.lex == BC_LEX_LBRACKET) { 3899 if (p->lex == BC_LEX_LBRACKET) {
3905 s = zbc_lex_next(); 3900 s = zbc_lex_next();
3906 if (s) goto err; 3901 if (s) goto err;
3907 3902
3908 if (p->l.lex == BC_LEX_RBRACKET) { 3903 if (p->lex == BC_LEX_RBRACKET) {
3909 if (!(flags & BC_PARSE_ARRAY)) { 3904 if (!(flags & BC_PARSE_ARRAY)) {
3910 s = bc_error_bad_expression(); 3905 s = bc_error_bad_expression();
3911 goto err; 3906 goto err;
@@ -3922,7 +3917,7 @@ static BC_STATUS zbc_parse_name(BcInst *type, uint8_t flags)
3922 bc_parse_push(*type); 3917 bc_parse_push(*type);
3923 bc_parse_pushName(name); 3918 bc_parse_pushName(name);
3924 free(name); 3919 free(name);
3925 } else if (p->l.lex == BC_LEX_LPAREN) { 3920 } else if (p->lex == BC_LEX_LPAREN) {
3926 if (flags & BC_PARSE_NOCALL) { 3921 if (flags & BC_PARSE_NOCALL) {
3927 s = bc_error_bad_token(); 3922 s = bc_error_bad_token();
3928 goto err; 3923 goto err;
@@ -3950,11 +3945,11 @@ static BC_STATUS zbc_parse_read(void)
3950 3945
3951 s = zbc_lex_next(); 3946 s = zbc_lex_next();
3952 if (s) RETURN_STATUS(s); 3947 if (s) RETURN_STATUS(s);
3953 if (p->l.lex != BC_LEX_LPAREN) RETURN_STATUS(bc_error_bad_token()); 3948 if (p->lex != BC_LEX_LPAREN) RETURN_STATUS(bc_error_bad_token());
3954 3949
3955 s = zbc_lex_next(); 3950 s = zbc_lex_next();
3956 if (s) RETURN_STATUS(s); 3951 if (s) RETURN_STATUS(s);
3957 if (p->l.lex != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token()); 3952 if (p->lex != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token());
3958 3953
3959 bc_parse_push(XC_INST_READ); 3954 bc_parse_push(XC_INST_READ);
3960 3955
@@ -3969,7 +3964,7 @@ static BC_STATUS zbc_parse_builtin(BcLexType type, uint8_t flags, BcInst *prev)
3969 3964
3970 s = zbc_lex_next(); 3965 s = zbc_lex_next();
3971 if (s) RETURN_STATUS(s); 3966 if (s) RETURN_STATUS(s);
3972 if (p->l.lex != BC_LEX_LPAREN) RETURN_STATUS(bc_error_bad_token()); 3967 if (p->lex != BC_LEX_LPAREN) RETURN_STATUS(bc_error_bad_token());
3973 3968
3974 flags = (flags & ~(BC_PARSE_PRINT | BC_PARSE_REL)) | BC_PARSE_ARRAY; 3969 flags = (flags & ~(BC_PARSE_PRINT | BC_PARSE_REL)) | BC_PARSE_ARRAY;
3975 3970
@@ -3979,7 +3974,7 @@ static BC_STATUS zbc_parse_builtin(BcLexType type, uint8_t flags, BcInst *prev)
3979 s = zbc_parse_expr(flags); 3974 s = zbc_parse_expr(flags);
3980 if (s) RETURN_STATUS(s); 3975 if (s) RETURN_STATUS(s);
3981 3976
3982 if (p->l.lex != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token()); 3977 if (p->lex != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token());
3983 3978
3984 *prev = (type == BC_LEX_KEY_LENGTH) ? XC_INST_LENGTH : XC_INST_SQRT; 3979 *prev = (type == BC_LEX_KEY_LENGTH) ? XC_INST_LENGTH : XC_INST_SQRT;
3985 bc_parse_push(*prev); 3980 bc_parse_push(*prev);
@@ -3996,7 +3991,7 @@ static BC_STATUS zbc_parse_scale(BcInst *type, uint8_t flags)
3996 s = zbc_lex_next(); 3991 s = zbc_lex_next();
3997 if (s) RETURN_STATUS(s); 3992 if (s) RETURN_STATUS(s);
3998 3993
3999 if (p->l.lex != BC_LEX_LPAREN) { 3994 if (p->lex != BC_LEX_LPAREN) {
4000 *type = XC_INST_SCALE; 3995 *type = XC_INST_SCALE;
4001 bc_parse_push(XC_INST_SCALE); 3996 bc_parse_push(XC_INST_SCALE);
4002 RETURN_STATUS(BC_STATUS_SUCCESS); 3997 RETURN_STATUS(BC_STATUS_SUCCESS);
@@ -4010,7 +4005,7 @@ static BC_STATUS zbc_parse_scale(BcInst *type, uint8_t flags)
4010 4005
4011 s = zbc_parse_expr(flags); 4006 s = zbc_parse_expr(flags);
4012 if (s) RETURN_STATUS(s); 4007 if (s) RETURN_STATUS(s);
4013 if (p->l.lex != BC_LEX_RPAREN) 4008 if (p->lex != BC_LEX_RPAREN)
4014 RETURN_STATUS(bc_error_bad_token()); 4009 RETURN_STATUS(bc_error_bad_token());
4015 bc_parse_push(XC_INST_SCALE_FUNC); 4010 bc_parse_push(XC_INST_SCALE_FUNC);
4016 4011
@@ -4031,16 +4026,16 @@ static BC_STATUS zbc_parse_incdec(BcInst *prev, bool *paren_expr,
4031 || etype == XC_INST_SCALE || etype == BC_INST_LAST 4026 || etype == XC_INST_SCALE || etype == BC_INST_LAST
4032 || etype == XC_INST_IBASE || etype == XC_INST_OBASE 4027 || etype == XC_INST_IBASE || etype == XC_INST_OBASE
4033 ) { 4028 ) {
4034 *prev = inst = BC_INST_INC_POST + (p->l.lex != BC_LEX_OP_INC); 4029 *prev = inst = BC_INST_INC_POST + (p->lex != BC_LEX_OP_INC);
4035 bc_parse_push(inst); 4030 bc_parse_push(inst);
4036 s = zbc_lex_next(); 4031 s = zbc_lex_next();
4037 } else { 4032 } else {
4038 *prev = inst = BC_INST_INC_PRE + (p->l.lex != BC_LEX_OP_INC); 4033 *prev = inst = BC_INST_INC_PRE + (p->lex != BC_LEX_OP_INC);
4039 *paren_expr = true; 4034 *paren_expr = true;
4040 4035
4041 s = zbc_lex_next(); 4036 s = zbc_lex_next();
4042 if (s) RETURN_STATUS(s); 4037 if (s) RETURN_STATUS(s);
4043 type = p->l.lex; 4038 type = p->lex;
4044 4039
4045 // Because we parse the next part of the expression 4040 // Because we parse the next part of the expression
4046 // right here, we need to increment this. 4041 // right here, we need to increment this.
@@ -4059,7 +4054,7 @@ static BC_STATUS zbc_parse_incdec(BcInst *prev, bool *paren_expr,
4059 case BC_LEX_KEY_SCALE: 4054 case BC_LEX_KEY_SCALE:
4060 s = zbc_lex_next(); 4055 s = zbc_lex_next();
4061 if (s) RETURN_STATUS(s); 4056 if (s) RETURN_STATUS(s);
4062 if (p->l.lex == BC_LEX_LPAREN) 4057 if (p->lex == BC_LEX_LPAREN)
4063 s = bc_error_bad_token(); 4058 s = bc_error_bad_token();
4064 else 4059 else
4065 bc_parse_push(XC_INST_SCALE); 4060 bc_parse_push(XC_INST_SCALE);
@@ -4128,7 +4123,7 @@ static BC_STATUS zbc_parse_print(void)
4128 for (;;) { 4123 for (;;) {
4129 s = zbc_lex_next(); 4124 s = zbc_lex_next();
4130 if (s) RETURN_STATUS(s); 4125 if (s) RETURN_STATUS(s);
4131 type = p->l.lex; 4126 type = p->lex;
4132 if (type == XC_LEX_STR) { 4127 if (type == XC_LEX_STR) {
4133 s = zbc_parse_pushSTR(); 4128 s = zbc_parse_pushSTR();
4134 } else { 4129 } else {
@@ -4136,7 +4131,7 @@ static BC_STATUS zbc_parse_print(void)
4136 } 4131 }
4137 if (s) RETURN_STATUS(s); 4132 if (s) RETURN_STATUS(s);
4138 bc_parse_push(XC_INST_PRINT_POP); 4133 bc_parse_push(XC_INST_PRINT_POP);
4139 if (p->l.lex != BC_LEX_COMMA) 4134 if (p->lex != BC_LEX_COMMA)
4140 break; 4135 break;
4141 } 4136 }
4142 4137
@@ -4154,7 +4149,7 @@ static BC_STATUS zbc_parse_return(void)
4154 s = zbc_lex_next(); 4149 s = zbc_lex_next();
4155 if (s) RETURN_STATUS(s); 4150 if (s) RETURN_STATUS(s);
4156 4151
4157 t = p->l.lex; 4152 t = p->lex;
4158 if (t == XC_LEX_NLINE || t == BC_LEX_SCOLON) 4153 if (t == XC_LEX_NLINE || t == BC_LEX_SCOLON)
4159 bc_parse_push(BC_INST_RET0); 4154 bc_parse_push(BC_INST_RET0);
4160 else { 4155 else {
@@ -4166,7 +4161,7 @@ static BC_STATUS zbc_parse_return(void)
4166 } 4161 }
4167 if (s) RETURN_STATUS(s); 4162 if (s) RETURN_STATUS(s);
4168 4163
4169 if (!paren || p->l.lex_last != BC_LEX_RPAREN) { 4164 if (!paren || p->lex_last != BC_LEX_RPAREN) {
4170 s = zbc_POSIX_requires("parentheses around return expressions"); 4165 s = zbc_POSIX_requires("parentheses around return expressions");
4171 if (s) RETURN_STATUS(s); 4166 if (s) RETURN_STATUS(s);
4172 } 4167 }
@@ -4195,13 +4190,13 @@ static BC_STATUS zbc_parse_if(void)
4195 dbg_lex_enter("%s:%d entered", __func__, __LINE__); 4190 dbg_lex_enter("%s:%d entered", __func__, __LINE__);
4196 s = zbc_lex_next(); 4191 s = zbc_lex_next();
4197 if (s) RETURN_STATUS(s); 4192 if (s) RETURN_STATUS(s);
4198 if (p->l.lex != BC_LEX_LPAREN) RETURN_STATUS(bc_error_bad_token()); 4193 if (p->lex != BC_LEX_LPAREN) RETURN_STATUS(bc_error_bad_token());
4199 4194
4200 s = zbc_lex_next(); 4195 s = zbc_lex_next();
4201 if (s) RETURN_STATUS(s); 4196 if (s) RETURN_STATUS(s);
4202 s = zbc_parse_expr(BC_PARSE_REL); 4197 s = zbc_parse_expr(BC_PARSE_REL);
4203 if (s) RETURN_STATUS(s); 4198 if (s) RETURN_STATUS(s);
4204 if (p->l.lex != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token()); 4199 if (p->lex != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token());
4205 4200
4206 // Encode "if zero, jump to ..." 4201 // Encode "if zero, jump to ..."
4207 // Pushed value (destination of the jump) is uninitialized, 4202 // Pushed value (destination of the jump) is uninitialized,
@@ -4212,8 +4207,8 @@ static BC_STATUS zbc_parse_if(void)
4212 s = zbc_parse_stmt_allow_NLINE_before(STRING_if); 4207 s = zbc_parse_stmt_allow_NLINE_before(STRING_if);
4213 if (s) RETURN_STATUS(s); 4208 if (s) RETURN_STATUS(s);
4214 4209
4215 dbg_lex("%s:%d in if after stmt: p->l.lex:%d", __func__, __LINE__, p->l.lex); 4210 dbg_lex("%s:%d in if after stmt: p->lex:%d", __func__, __LINE__, p->lex);
4216 if (p->l.lex == BC_LEX_KEY_ELSE) { 4211 if (p->lex == BC_LEX_KEY_ELSE) {
4217 size_t ip2_idx; 4212 size_t ip2_idx;
4218 4213
4219 // Encode "after then_stmt, jump to end of if()" 4214 // Encode "after then_stmt, jump to end of if()"
@@ -4247,7 +4242,7 @@ static BC_STATUS zbc_parse_while(void)
4247 4242
4248 s = zbc_lex_next(); 4243 s = zbc_lex_next();
4249 if (s) RETURN_STATUS(s); 4244 if (s) RETURN_STATUS(s);
4250 if (p->l.lex != BC_LEX_LPAREN) RETURN_STATUS(bc_error_bad_token()); 4245 if (p->lex != BC_LEX_LPAREN) RETURN_STATUS(bc_error_bad_token());
4251 s = zbc_lex_next(); 4246 s = zbc_lex_next();
4252 if (s) RETURN_STATUS(s); 4247 if (s) RETURN_STATUS(s);
4253 4248
@@ -4260,7 +4255,7 @@ static BC_STATUS zbc_parse_while(void)
4260 4255
4261 s = zbc_parse_expr(BC_PARSE_REL); 4256 s = zbc_parse_expr(BC_PARSE_REL);
4262 if (s) RETURN_STATUS(s); 4257 if (s) RETURN_STATUS(s);
4263 if (p->l.lex != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token()); 4258 if (p->lex != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token());
4264 4259
4265 bc_parse_pushJUMP_ZERO(ip_idx); 4260 bc_parse_pushJUMP_ZERO(ip_idx);
4266 4261
@@ -4286,14 +4281,14 @@ static BC_STATUS zbc_parse_for(void)
4286 BcStatus s; 4281 BcStatus s;
4287 size_t cond_idx, exit_idx, body_idx, update_idx; 4282 size_t cond_idx, exit_idx, body_idx, update_idx;
4288 4283
4289 dbg_lex("%s:%d p->l.lex:%d", __func__, __LINE__, p->l.lex); 4284 dbg_lex("%s:%d p->lex:%d", __func__, __LINE__, p->lex);
4290 s = zbc_lex_next(); 4285 s = zbc_lex_next();
4291 if (s) RETURN_STATUS(s); 4286 if (s) RETURN_STATUS(s);
4292 if (p->l.lex != BC_LEX_LPAREN) RETURN_STATUS(bc_error_bad_token()); 4287 if (p->lex != BC_LEX_LPAREN) RETURN_STATUS(bc_error_bad_token());
4293 s = zbc_lex_next(); 4288 s = zbc_lex_next();
4294 if (s) RETURN_STATUS(s); 4289 if (s) RETURN_STATUS(s);
4295 4290
4296 if (p->l.lex != BC_LEX_SCOLON) { 4291 if (p->lex != BC_LEX_SCOLON) {
4297 s = zbc_parse_expr(0); 4292 s = zbc_parse_expr(0);
4298 bc_parse_push(XC_INST_POP); 4293 bc_parse_push(XC_INST_POP);
4299 if (s) RETURN_STATUS(s); 4294 if (s) RETURN_STATUS(s);
@@ -4302,7 +4297,7 @@ static BC_STATUS zbc_parse_for(void)
4302 if (s) RETURN_STATUS(s); 4297 if (s) RETURN_STATUS(s);
4303 } 4298 }
4304 4299
4305 if (p->l.lex != BC_LEX_SCOLON) RETURN_STATUS(bc_error_bad_token()); 4300 if (p->lex != BC_LEX_SCOLON) RETURN_STATUS(bc_error_bad_token());
4306 s = zbc_lex_next(); 4301 s = zbc_lex_next();
4307 if (s) RETURN_STATUS(s); 4302 if (s) RETURN_STATUS(s);
4308 4303
@@ -4311,19 +4306,19 @@ static BC_STATUS zbc_parse_for(void)
4311 body_idx = update_idx + 1; 4306 body_idx = update_idx + 1;
4312 exit_idx = body_idx + 1; 4307 exit_idx = body_idx + 1;
4313 4308
4314 if (p->l.lex != BC_LEX_SCOLON) 4309 if (p->lex != BC_LEX_SCOLON)
4315 s = zbc_parse_expr(BC_PARSE_REL); 4310 s = zbc_parse_expr(BC_PARSE_REL);
4316 else { 4311 else {
4317 // Set this for the next call to bc_parse_pushNUM(). 4312 // Set this for the next call to bc_parse_pushNUM().
4318 // This is safe to set because the current token is a semicolon, 4313 // This is safe to set because the current token is a semicolon,
4319 // which has no string requirement. 4314 // which has no string requirement.
4320 bc_vec_string(&p->l.lex_strnumbuf, 1, "1"); 4315 bc_vec_string(&p->lex_strnumbuf, 1, "1");
4321 bc_parse_pushNUM(); 4316 bc_parse_pushNUM();
4322 s = zbc_POSIX_does_not_allow_empty_X_expression_in_for("condition"); 4317 s = zbc_POSIX_does_not_allow_empty_X_expression_in_for("condition");
4323 } 4318 }
4324 if (s) RETURN_STATUS(s); 4319 if (s) RETURN_STATUS(s);
4325 4320
4326 if (p->l.lex != BC_LEX_SCOLON) RETURN_STATUS(bc_error_bad_token()); 4321 if (p->lex != BC_LEX_SCOLON) RETURN_STATUS(bc_error_bad_token());
4327 4322
4328 s = zbc_lex_next(); 4323 s = zbc_lex_next();
4329 if (s) RETURN_STATUS(s); 4324 if (s) RETURN_STATUS(s);
@@ -4334,10 +4329,10 @@ static BC_STATUS zbc_parse_for(void)
4334 bc_vec_push(&p->conds, &update_idx); 4329 bc_vec_push(&p->conds, &update_idx);
4335 bc_vec_push(&p->func->labels, &p->func->code.len); 4330 bc_vec_push(&p->func->labels, &p->func->code.len);
4336 4331
4337 if (p->l.lex != BC_LEX_RPAREN) { 4332 if (p->lex != BC_LEX_RPAREN) {
4338 s = zbc_parse_expr(0); 4333 s = zbc_parse_expr(0);
4339 if (s) RETURN_STATUS(s); 4334 if (s) RETURN_STATUS(s);
4340 if (p->l.lex != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token()); 4335 if (p->lex != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token());
4341 bc_parse_push(XC_INST_POP); 4336 bc_parse_push(XC_INST_POP);
4342 } else { 4337 } else {
4343 s = zbc_POSIX_does_not_allow_empty_X_expression_in_for("update"); 4338 s = zbc_POSIX_does_not_allow_empty_X_expression_in_for("update");
@@ -4415,37 +4410,37 @@ static BC_STATUS zbc_parse_funcdef(void)
4415 dbg_lex_enter("%s:%d entered", __func__, __LINE__); 4410 dbg_lex_enter("%s:%d entered", __func__, __LINE__);
4416 s = zbc_lex_next(); 4411 s = zbc_lex_next();
4417 if (s) RETURN_STATUS(s); 4412 if (s) RETURN_STATUS(s);
4418 if (p->l.lex != XC_LEX_NAME) 4413 if (p->lex != XC_LEX_NAME)
4419 RETURN_STATUS(bc_error("bad function definition")); 4414 RETURN_STATUS(bc_error("bad function definition"));
4420 4415
4421 name = xstrdup(p->l.lex_strnumbuf.v); 4416 name = xstrdup(p->lex_strnumbuf.v);
4422 p->fidx = bc_program_addFunc(name); 4417 p->fidx = bc_program_addFunc(name);
4423 p->func = bc_program_func(p->fidx); 4418 p->func = bc_program_func(p->fidx);
4424 4419
4425 s = zbc_lex_next(); 4420 s = zbc_lex_next();
4426 if (s) RETURN_STATUS(s); 4421 if (s) RETURN_STATUS(s);
4427 if (p->l.lex != BC_LEX_LPAREN) 4422 if (p->lex != BC_LEX_LPAREN)
4428 RETURN_STATUS(bc_error("bad function definition")); 4423 RETURN_STATUS(bc_error("bad function definition"));
4429 s = zbc_lex_next(); 4424 s = zbc_lex_next();
4430 if (s) RETURN_STATUS(s); 4425 if (s) RETURN_STATUS(s);
4431 4426
4432 while (p->l.lex != BC_LEX_RPAREN) { 4427 while (p->lex != BC_LEX_RPAREN) {
4433 if (p->l.lex != XC_LEX_NAME) 4428 if (p->lex != XC_LEX_NAME)
4434 RETURN_STATUS(bc_error("bad function definition")); 4429 RETURN_STATUS(bc_error("bad function definition"));
4435 4430
4436 ++p->func->nparams; 4431 ++p->func->nparams;
4437 4432
4438 name = xstrdup(p->l.lex_strnumbuf.v); 4433 name = xstrdup(p->lex_strnumbuf.v);
4439 s = zbc_lex_next(); 4434 s = zbc_lex_next();
4440 if (s) goto err; 4435 if (s) goto err;
4441 4436
4442 var = p->l.lex != BC_LEX_LBRACKET; 4437 var = p->lex != BC_LEX_LBRACKET;
4443 4438
4444 if (!var) { 4439 if (!var) {
4445 s = zbc_lex_next(); 4440 s = zbc_lex_next();
4446 if (s) goto err; 4441 if (s) goto err;
4447 4442
4448 if (p->l.lex != BC_LEX_RBRACKET) { 4443 if (p->lex != BC_LEX_RBRACKET) {
4449 s = bc_error("bad function definition"); 4444 s = bc_error("bad function definition");
4450 goto err; 4445 goto err;
4451 } 4446 }
@@ -4454,7 +4449,7 @@ static BC_STATUS zbc_parse_funcdef(void)
4454 if (s) goto err; 4449 if (s) goto err;
4455 } 4450 }
4456 4451
4457 comma = p->l.lex == BC_LEX_COMMA; 4452 comma = p->lex == BC_LEX_COMMA;
4458 if (comma) { 4453 if (comma) {
4459 s = zbc_lex_next(); 4454 s = zbc_lex_next();
4460 if (s) goto err; 4455 if (s) goto err;
@@ -4469,7 +4464,7 @@ static BC_STATUS zbc_parse_funcdef(void)
4469 s = zbc_lex_next(); 4464 s = zbc_lex_next();
4470 if (s) RETURN_STATUS(s); 4465 if (s) RETURN_STATUS(s);
4471 4466
4472 if (p->l.lex != BC_LEX_LBRACE) { 4467 if (p->lex != BC_LEX_LBRACE) {
4473 s = zbc_POSIX_requires("the left brace be on the same line as the function header"); 4468 s = zbc_POSIX_requires("the left brace be on the same line as the function header");
4474 if (s) RETURN_STATUS(s); 4469 if (s) RETURN_STATUS(s);
4475 } 4470 }
@@ -4478,7 +4473,7 @@ static BC_STATUS zbc_parse_funcdef(void)
4478 s = zbc_lex_skip_if_at_NLINE(); 4473 s = zbc_lex_skip_if_at_NLINE();
4479 if (s) RETURN_STATUS(s); 4474 if (s) RETURN_STATUS(s);
4480 //GNU bc requires a {} block even if function body has single stmt, enforce this? 4475 //GNU bc requires a {} block even if function body has single stmt, enforce this?
4481 if (p->l.lex != BC_LEX_LBRACE) 4476 if (p->lex != BC_LEX_LBRACE)
4482 RETURN_STATUS(bc_error("function { body } expected")); 4477 RETURN_STATUS(bc_error("function { body } expected"));
4483 4478
4484 p->in_funcdef++; // to determine whether "return" stmt is allowed, and such 4479 p->in_funcdef++; // to determine whether "return" stmt is allowed, and such
@@ -4514,19 +4509,19 @@ static BC_STATUS zbc_parse_auto(void)
4514 for (;;) { 4509 for (;;) {
4515 bool var; 4510 bool var;
4516 4511
4517 if (p->l.lex != XC_LEX_NAME) 4512 if (p->lex != XC_LEX_NAME)
4518 RETURN_STATUS(bc_error("bad 'auto' syntax")); 4513 RETURN_STATUS(bc_error("bad 'auto' syntax"));
4519 4514
4520 name = xstrdup(p->l.lex_strnumbuf.v); 4515 name = xstrdup(p->lex_strnumbuf.v);
4521 s = zbc_lex_next(); 4516 s = zbc_lex_next();
4522 if (s) goto err; 4517 if (s) goto err;
4523 4518
4524 var = (p->l.lex != BC_LEX_LBRACKET); 4519 var = (p->lex != BC_LEX_LBRACKET);
4525 if (!var) { 4520 if (!var) {
4526 s = zbc_lex_next(); 4521 s = zbc_lex_next();
4527 if (s) goto err; 4522 if (s) goto err;
4528 4523
4529 if (p->l.lex != BC_LEX_RBRACKET) { 4524 if (p->lex != BC_LEX_RBRACKET) {
4530 s = bc_error("bad 'auto' syntax"); 4525 s = bc_error("bad 'auto' syntax");
4531 goto err; 4526 goto err;
4532 } 4527 }
@@ -4537,13 +4532,13 @@ static BC_STATUS zbc_parse_auto(void)
4537 s = zbc_func_insert(p->func, name, var); 4532 s = zbc_func_insert(p->func, name, var);
4538 if (s) goto err; 4533 if (s) goto err;
4539 4534
4540 if (p->l.lex == XC_LEX_NLINE 4535 if (p->lex == XC_LEX_NLINE
4541 || p->l.lex == BC_LEX_SCOLON 4536 || p->lex == BC_LEX_SCOLON
4542 //|| p->l.lex == BC_LEX_RBRACE // allow "define f() {auto a}" 4537 //|| p->lex == BC_LEX_RBRACE // allow "define f() {auto a}"
4543 ) { 4538 ) {
4544 break; 4539 break;
4545 } 4540 }
4546 if (p->l.lex != BC_LEX_COMMA) 4541 if (p->lex != BC_LEX_COMMA)
4547 RETURN_STATUS(bc_error("bad 'auto' syntax")); 4542 RETURN_STATUS(bc_error("bad 'auto' syntax"));
4548 s = zbc_lex_next(); // skip comma 4543 s = zbc_lex_next(); // skip comma
4549 if (s) RETURN_STATUS(s); 4544 if (s) RETURN_STATUS(s);
@@ -4564,29 +4559,29 @@ static BC_STATUS zbc_parse_stmt_possibly_auto(bool auto_allowed)
4564 BcParse *p = &G.prs; 4559 BcParse *p = &G.prs;
4565 BcStatus s = BC_STATUS_SUCCESS; 4560 BcStatus s = BC_STATUS_SUCCESS;
4566 4561
4567 dbg_lex_enter("%s:%d entered, p->l.lex:%d", __func__, __LINE__, p->l.lex); 4562 dbg_lex_enter("%s:%d entered, p->lex:%d", __func__, __LINE__, p->lex);
4568 4563
4569 if (p->l.lex == XC_LEX_NLINE) { 4564 if (p->lex == XC_LEX_NLINE) {
4570 dbg_lex_done("%s:%d done (seen XC_LEX_NLINE)", __func__, __LINE__); 4565 dbg_lex_done("%s:%d done (seen XC_LEX_NLINE)", __func__, __LINE__);
4571 RETURN_STATUS(zbc_lex_next()); 4566 RETURN_STATUS(zbc_lex_next());
4572 } 4567 }
4573 if (p->l.lex == BC_LEX_SCOLON) { 4568 if (p->lex == BC_LEX_SCOLON) {
4574 dbg_lex_done("%s:%d done (seen BC_LEX_SCOLON)", __func__, __LINE__); 4569 dbg_lex_done("%s:%d done (seen BC_LEX_SCOLON)", __func__, __LINE__);
4575 RETURN_STATUS(zbc_lex_next()); 4570 RETURN_STATUS(zbc_lex_next());
4576 } 4571 }
4577 4572
4578 if (p->l.lex == BC_LEX_LBRACE) { 4573 if (p->lex == BC_LEX_LBRACE) {
4579 dbg_lex("%s:%d BC_LEX_LBRACE: (auto_allowed:%d)", __func__, __LINE__, auto_allowed); 4574 dbg_lex("%s:%d BC_LEX_LBRACE: (auto_allowed:%d)", __func__, __LINE__, auto_allowed);
4580 do { 4575 do {
4581 s = zbc_lex_next(); 4576 s = zbc_lex_next();
4582 if (s) RETURN_STATUS(s); 4577 if (s) RETURN_STATUS(s);
4583 } while (p->l.lex == XC_LEX_NLINE); 4578 } while (p->lex == XC_LEX_NLINE);
4584 if (auto_allowed && p->l.lex == BC_LEX_KEY_AUTO) { 4579 if (auto_allowed && p->lex == BC_LEX_KEY_AUTO) {
4585 dbg_lex("%s:%d calling zbc_parse_auto()", __func__, __LINE__); 4580 dbg_lex("%s:%d calling zbc_parse_auto()", __func__, __LINE__);
4586 s = zbc_parse_auto(); 4581 s = zbc_parse_auto();
4587 if (s) RETURN_STATUS(s); 4582 if (s) RETURN_STATUS(s);
4588 } 4583 }
4589 while (p->l.lex != BC_LEX_RBRACE) { 4584 while (p->lex != BC_LEX_RBRACE) {
4590 dbg_lex("%s:%d block parsing loop", __func__, __LINE__); 4585 dbg_lex("%s:%d block parsing loop", __func__, __LINE__);
4591 s = zbc_parse_stmt(); 4586 s = zbc_parse_stmt();
4592 if (s) RETURN_STATUS(s); 4587 if (s) RETURN_STATUS(s);
@@ -4596,8 +4591,8 @@ static BC_STATUS zbc_parse_stmt_possibly_auto(bool auto_allowed)
4596 RETURN_STATUS(s); 4591 RETURN_STATUS(s);
4597 } 4592 }
4598 4593
4599 dbg_lex("%s:%d p->l.lex:%d", __func__, __LINE__, p->l.lex); 4594 dbg_lex("%s:%d p->lex:%d", __func__, __LINE__, p->lex);
4600 switch (p->l.lex) { 4595 switch (p->lex) {
4601 case XC_LEX_OP_MINUS: 4596 case XC_LEX_OP_MINUS:
4602 case BC_LEX_OP_INC: 4597 case BC_LEX_OP_INC:
4603 case BC_LEX_OP_DEC: 4598 case BC_LEX_OP_DEC:
@@ -4620,7 +4615,7 @@ static BC_STATUS zbc_parse_stmt_possibly_auto(bool auto_allowed)
4620 break; 4615 break;
4621 case BC_LEX_KEY_BREAK: 4616 case BC_LEX_KEY_BREAK:
4622 case BC_LEX_KEY_CONTINUE: 4617 case BC_LEX_KEY_CONTINUE:
4623 s = zbc_parse_break_or_continue(p->l.lex); 4618 s = zbc_parse_break_or_continue(p->lex);
4624 break; 4619 break;
4625 case BC_LEX_KEY_FOR: 4620 case BC_LEX_KEY_FOR:
4626 s = zbc_parse_for(); 4621 s = zbc_parse_for();
@@ -4679,13 +4674,13 @@ static BC_STATUS zbc_parse_stmt_or_funcdef(void)
4679 BcStatus s; 4674 BcStatus s;
4680 4675
4681 dbg_lex_enter("%s:%d entered", __func__, __LINE__); 4676 dbg_lex_enter("%s:%d entered", __func__, __LINE__);
4682 if (p->l.lex == XC_LEX_EOF) 4677 if (p->lex == XC_LEX_EOF)
4683 s = bc_error("end of file"); 4678 s = bc_error("end of file");
4684 else if (p->l.lex == BC_LEX_KEY_DEFINE) { 4679 else if (p->lex == BC_LEX_KEY_DEFINE) {
4685 dbg_lex("%s:%d p->l.lex:BC_LEX_KEY_DEFINE", __func__, __LINE__); 4680 dbg_lex("%s:%d p->lex:BC_LEX_KEY_DEFINE", __func__, __LINE__);
4686 s = zbc_parse_funcdef(); 4681 s = zbc_parse_funcdef();
4687 } else { 4682 } else {
4688 dbg_lex("%s:%d p->l.lex:%d (not BC_LEX_KEY_DEFINE)", __func__, __LINE__, p->l.lex); 4683 dbg_lex("%s:%d p->lex:%d (not BC_LEX_KEY_DEFINE)", __func__, __LINE__, p->lex);
4689 s = zbc_parse_stmt(); 4684 s = zbc_parse_stmt();
4690 } 4685 }
4691 4686
@@ -4704,7 +4699,7 @@ static BcStatus bc_parse_expr_empty_ok(uint8_t flags)
4704 bool paren_first, paren_expr, rprn, assign, bin_last; 4699 bool paren_first, paren_expr, rprn, assign, bin_last;
4705 4700
4706 dbg_lex_enter("%s:%d entered", __func__, __LINE__); 4701 dbg_lex_enter("%s:%d entered", __func__, __LINE__);
4707 paren_first = (p->l.lex == BC_LEX_LPAREN); 4702 paren_first = (p->lex == BC_LEX_LPAREN);
4708 nparens = nrelops = 0; 4703 nparens = nrelops = 0;
4709 paren_expr = rprn = assign = false; 4704 paren_expr = rprn = assign = false;
4710 bin_last = true; 4705 bin_last = true;
@@ -4712,7 +4707,7 @@ static BcStatus bc_parse_expr_empty_ok(uint8_t flags)
4712 for (;;) { 4707 for (;;) {
4713 bool get_token; 4708 bool get_token;
4714 BcStatus s; 4709 BcStatus s;
4715 BcLexType t = p->l.lex; 4710 BcLexType t = p->lex;
4716 4711
4717 if (!lex_allowed_in_bc_expr(t)) 4712 if (!lex_allowed_in_bc_expr(t))
4718 break; 4713 break;
@@ -4923,9 +4918,9 @@ static BC_STATUS zdc_parse_register(void)
4923 4918
4924 s = zbc_lex_next(); 4919 s = zbc_lex_next();
4925 if (s) RETURN_STATUS(s); 4920 if (s) RETURN_STATUS(s);
4926 if (p->l.lex != XC_LEX_NAME) RETURN_STATUS(bc_error_bad_token()); 4921 if (p->lex != XC_LEX_NAME) RETURN_STATUS(bc_error_bad_token());
4927 4922
4928 bc_parse_pushName(p->l.lex_strnumbuf.v); 4923 bc_parse_pushName(p->lex_strnumbuf.v);
4929 4924
4930 RETURN_STATUS(s); 4925 RETURN_STATUS(s);
4931} 4926}
@@ -4939,7 +4934,7 @@ static void dc_parse_string(void)
4939 4934
4940 dbg_lex_enter("%s:%d entered", __func__, __LINE__); 4935 dbg_lex_enter("%s:%d entered", __func__, __LINE__);
4941 4936
4942 str = xstrdup(p->l.lex_strnumbuf.v); 4937 str = xstrdup(p->lex_strnumbuf.v);
4943 bc_parse_push(XC_INST_STR); 4938 bc_parse_push(XC_INST_STR);
4944 bc_parse_pushIndex(len); 4939 bc_parse_pushIndex(len);
4945 bc_vec_push(&G.prog.strs, &str); 4940 bc_vec_push(&G.prog.strs, &str);
@@ -4988,7 +4983,7 @@ static BC_STATUS zdc_parse_cond(uint8_t inst)
4988 // Note that 'else' part can not be on the next line: 4983 // Note that 'else' part can not be on the next line:
4989 // echo -e '[1p]sa [2p]sb 2 1>a eb' | dc - OK, prints "2" 4984 // echo -e '[1p]sa [2p]sb 2 1>a eb' | dc - OK, prints "2"
4990 // echo -e '[1p]sa [2p]sb 2 1>a\neb' | dc - parse error 4985 // echo -e '[1p]sa [2p]sb 2 1>a\neb' | dc - parse error
4991 if (p->l.lex == DC_LEX_ELSE) { 4986 if (p->lex == DC_LEX_ELSE) {
4992 s = zdc_parse_register(); 4987 s = zdc_parse_register();
4993 if (s) RETURN_STATUS(s); 4988 if (s) RETURN_STATUS(s);
4994 s = zbc_lex_next(); 4989 s = zbc_lex_next();
@@ -5033,7 +5028,7 @@ static BC_STATUS zdc_parse_token(BcLexType t)
5033 dbg_lex("%s:%d LEX_NEG", __func__, __LINE__); 5028 dbg_lex("%s:%d LEX_NEG", __func__, __LINE__);
5034 s = zbc_lex_next(); 5029 s = zbc_lex_next();
5035 if (s) RETURN_STATUS(s); 5030 if (s) RETURN_STATUS(s);
5036 if (G.prs.l.lex != XC_LEX_NUMBER) 5031 if (G.prs.lex != XC_LEX_NUMBER)
5037 RETURN_STATUS(bc_error_bad_token()); 5032 RETURN_STATUS(bc_error_bad_token());
5038 bc_parse_pushNUM(); 5033 bc_parse_pushNUM();
5039 bc_parse_push(XC_INST_NEG); 5034 bc_parse_push(XC_INST_NEG);
@@ -5083,7 +5078,7 @@ static BC_STATUS zdc_parse_expr(void)
5083 BcParse *p = &G.prs; 5078 BcParse *p = &G.prs;
5084 int i; 5079 int i;
5085 5080
5086 i = (int)p->l.lex - (int)XC_LEX_OP_POWER; 5081 i = (int)p->lex - (int)XC_LEX_OP_POWER;
5087 if (i >= 0) { 5082 if (i >= 0) {
5088 BcInst inst = dc_LEX_to_INST[i]; 5083 BcInst inst = dc_LEX_to_INST[i];
5089 if (inst != DC_INST_INVALID) { 5084 if (inst != DC_INST_INVALID) {
@@ -5091,15 +5086,15 @@ static BC_STATUS zdc_parse_expr(void)
5091 RETURN_STATUS(zbc_lex_next()); 5086 RETURN_STATUS(zbc_lex_next());
5092 } 5087 }
5093 } 5088 }
5094 RETURN_STATUS(zdc_parse_token(p->l.lex)); 5089 RETURN_STATUS(zdc_parse_token(p->lex));
5095} 5090}
5096#define zdc_parse_expr(...) (zdc_parse_expr(__VA_ARGS__) COMMA_SUCCESS) 5091#define zdc_parse_expr(...) (zdc_parse_expr(__VA_ARGS__) COMMA_SUCCESS)
5097 5092
5098static BC_STATUS zdc_parse_exprs_until_eof(void) 5093static BC_STATUS zdc_parse_exprs_until_eof(void)
5099{ 5094{
5100 BcParse *p = &G.prs; 5095 BcParse *p = &G.prs;
5101 dbg_lex_enter("%s:%d entered, p->l.lex:%d", __func__, __LINE__, p->l.lex); 5096 dbg_lex_enter("%s:%d entered, p->lex:%d", __func__, __LINE__, p->lex);
5102 while (p->l.lex != XC_LEX_EOF) { 5097 while (p->lex != XC_LEX_EOF) {
5103 BcStatus s = zdc_parse_expr(); 5098 BcStatus s = zdc_parse_expr();
5104 if (s) RETURN_STATUS(s); 5099 if (s) RETURN_STATUS(s);
5105 } 5100 }
@@ -5329,7 +5324,7 @@ static BC_STATUS zbc_program_read(void)
5329 } 5324 }
5330 if (s) goto exec_err; 5325 if (s) goto exec_err;
5331 5326
5332 if (G.prs.l.lex != XC_LEX_NLINE && G.prs.l.lex != XC_LEX_EOF) { 5327 if (G.prs.lex != XC_LEX_NLINE && G.prs.lex != XC_LEX_EOF) {
5333 s = bc_error("bad read() expression"); 5328 s = bc_error("bad read() expression");
5334 goto exec_err; 5329 goto exec_err;
5335 } 5330 }
@@ -6460,7 +6455,7 @@ static BC_STATUS zdc_program_execStr(char *code, size_t *bgn, bool cond)
6460 s = zdc_parse_exprs_until_eof(); 6455 s = zdc_parse_exprs_until_eof();
6461 if (s) goto err; 6456 if (s) goto err;
6462 bc_parse_push(DC_INST_POP_EXEC); 6457 bc_parse_push(DC_INST_POP_EXEC);
6463 if (G.prs.l.lex != XC_LEX_EOF) 6458 if (G.prs.lex != XC_LEX_EOF)
6464 s = bc_error_bad_expression(); 6459 s = bc_error_bad_expression();
6465 bc_parse_free(); 6460 bc_parse_free();
6466 G.prs = sv_parse; // struct copy 6461 G.prs = sv_parse; // struct copy
@@ -6797,15 +6792,15 @@ static BC_STATUS zbc_vm_process(const char *text)
6797 if (s) RETURN_STATUS(s); 6792 if (s) RETURN_STATUS(s);
6798 6793
6799 IF_BC(check_eof:) 6794 IF_BC(check_eof:)
6800 while (G.prs.l.lex != XC_LEX_EOF) { 6795 while (G.prs.lex != XC_LEX_EOF) {
6801 BcInstPtr *ip; 6796 BcInstPtr *ip;
6802 BcFunc *f; 6797 BcFunc *f;
6803 6798
6804 dbg_lex("%s:%d G.prs.l.lex:%d, parsing...", __func__, __LINE__, G.prs.l.lex); 6799 dbg_lex("%s:%d G.prs.lex:%d, parsing...", __func__, __LINE__, G.prs.lex);
6805 if (IS_BC) { 6800 if (IS_BC) {
6806#if ENABLE_BC 6801#if ENABLE_BC
6807 if (G.prs.l.lex == BC_LEX_SCOLON 6802 if (G.prs.lex == BC_LEX_SCOLON
6808 || G.prs.l.lex == XC_LEX_NLINE 6803 || G.prs.lex == XC_LEX_NLINE
6809 ) { 6804 ) {
6810 s = zbc_lex_next(); 6805 s = zbc_lex_next();
6811 if (s) goto err; 6806 if (s) goto err;
@@ -6817,13 +6812,13 @@ static BC_STATUS zbc_vm_process(const char *text)
6817 6812
6818 // Check that next token is a correct stmt delimiter - 6813 // Check that next token is a correct stmt delimiter -
6819 // disallows "print 1 print 2" and such. 6814 // disallows "print 1 print 2" and such.
6820 if (G.prs.l.lex != BC_LEX_SCOLON 6815 if (G.prs.lex != BC_LEX_SCOLON
6821 && G.prs.l.lex != XC_LEX_NLINE 6816 && G.prs.lex != XC_LEX_NLINE
6822 && G.prs.l.lex != XC_LEX_EOF 6817 && G.prs.lex != XC_LEX_EOF
6823 ) { 6818 ) {
6824 const char *err_at; 6819 const char *err_at;
6825//TODO: commonalize for other parse errors: 6820//TODO: commonalize for other parse errors:
6826 err_at = G.prs.l.lex_next_at ? G.prs.l.lex_next_at : "UNKNOWN"; 6821 err_at = G.prs.lex_next_at ? G.prs.lex_next_at : "UNKNOWN";
6827 bc_error_fmt("bad statement terminator at '%.*s'", 6822 bc_error_fmt("bad statement terminator at '%.*s'",
6828 (int)(strchrnul(err_at, '\n') - err_at), 6823 (int)(strchrnul(err_at, '\n') - err_at),
6829 err_at 6824 err_at
@@ -6837,10 +6832,10 @@ static BC_STATUS zbc_vm_process(const char *text)
6837#if ENABLE_DC 6832#if ENABLE_DC
6838 // Most of dc parsing assumes all whitespace, 6833 // Most of dc parsing assumes all whitespace,
6839 // including '\n', is eaten. 6834 // including '\n', is eaten.
6840 while (G.prs.l.lex == XC_LEX_NLINE) { 6835 while (G.prs.lex == XC_LEX_NLINE) {
6841 s = zbc_lex_next(); 6836 s = zbc_lex_next();
6842 if (s) goto err; 6837 if (s) goto err;
6843 if (G.prs.l.lex == XC_LEX_EOF) 6838 if (G.prs.lex == XC_LEX_EOF)
6844 goto done; 6839 goto done;
6845 } 6840 }
6846 s = zdc_parse_expr(); 6841 s = zdc_parse_expr();
@@ -6914,12 +6909,12 @@ static BC_STATUS zbc_vm_process(const char *text)
6914static BC_STATUS zbc_vm_execute_FILE(FILE *fp, const char *filename) 6909static BC_STATUS zbc_vm_execute_FILE(FILE *fp, const char *filename)
6915{ 6910{
6916 // So far bc/dc have no way to include a file from another file, 6911 // So far bc/dc have no way to include a file from another file,
6917 // therefore we know G.prs.filename == NULL on entry 6912 // therefore we know G.prs.lex_filename == NULL on entry
6918 //const char *sv_file; 6913 //const char *sv_file;
6919 BcStatus s; 6914 BcStatus s;
6920 6915
6921 G.prs.filename = filename; 6916 G.prs.lex_filename = filename;
6922 G.prs.input_fp = fp; 6917 G.prs.lex_input_fp = fp;
6923 bc_lex_file(); 6918 bc_lex_file();
6924 6919
6925 do { 6920 do {
@@ -6928,8 +6923,8 @@ static BC_STATUS zbc_vm_execute_FILE(FILE *fp, const char *filename)
6928 // Example: start interactive bc and enter "return". 6923 // Example: start interactive bc and enter "return".
6929 // It should say "'return' not in a function" 6924 // It should say "'return' not in a function"
6930 // but should not exit. 6925 // but should not exit.
6931 } while (G.prs.input_fp == stdin); 6926 } while (G.prs.lex_input_fp == stdin);
6932 G.prs.filename = NULL; 6927 G.prs.lex_filename = NULL;
6933 RETURN_STATUS(s); 6928 RETURN_STATUS(s);
6934} 6929}
6935#define zbc_vm_execute_FILE(...) (zbc_vm_execute_FILE(__VA_ARGS__) COMMA_SUCCESS) 6930#define zbc_vm_execute_FILE(...) (zbc_vm_execute_FILE(__VA_ARGS__) COMMA_SUCCESS)