diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-25 22:32:41 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-25 22:32:41 +0100 |
commit | ecb62edd478e8ae2b1a5f3d122e316345909a805 (patch) | |
tree | dfdffd86d089fcb1041554f010d89242bd0409bc | |
parent | 6e6182342ef59c47972a49543cd8b15dc4f28f6d (diff) | |
download | busybox-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.c | 529 |
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 | ||
713 | typedef struct BcLex { | 713 | typedef 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 | |||
725 | typedef 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) | |||
937 | static void bc_verror_msg(const char *fmt, va_list p) | 932 | static 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 | ||
2752 | static void bc_lex_lineComment(void) | 2747 | static 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 | ||
2764 | static void bc_lex_whitespace(void) | 2759 | static 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 | ||
2778 | static BC_STATUS zbc_lex_number(char start) | 2773 | static 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 | ||
2849 | static void bc_lex_name(void) | 2844 | static 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 | ||
2880 | static void bc_lex_init(void) | 2875 | static 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 | ||
2885 | static void bc_lex_free(void) | 2880 | static 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 | ||
2890 | static void bc_lex_file(void) | 2885 | static 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 | ||
2896 | static bool bc_lex_more_input(void) | 2891 | static 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 | ||
2969 | IF_BC(static BC_STATUS zbc_lex_token(void);) | 2964 | IF_BC(static BC_STATUS zbc_lex_token(void);) |
@@ -2973,43 +2968,43 @@ IF_DC(static BC_STATUS zdc_lex_token(void);) | |||
2973 | 2968 | ||
2974 | static BC_STATUS zbc_lex_next(void) | 2969 | static 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 |
3019 | static BC_STATUS zbc_lex_skip_if_at_NLINE(void) | 3014 | static 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 | ||
3039 | static BC_STATUS zbc_lex_text_init(const char *text) | 3034 | static 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 |
3050 | static BC_STATUS zbc_lex_identifier(void) | 3045 | static 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 | ||
3097 | static BC_STATUS zbc_lex_string(void) | 3092 | static 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 | ||
3134 | static void bc_lex_assign(unsigned with_and_without) | 3129 | static 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 | ||
3146 | static BC_STATUS zbc_lex_comment(void) | 3141 | static 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 |
3179 | static BC_STATUS zbc_lex_token(void) | 3174 | static 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 |
3374 | static BC_STATUS zdc_lex_register(void) | 3369 | static 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 | ||
3392 | static BC_STATUS zdc_lex_string(void) | 3387 | static 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 |
3437 | static BC_STATUS zdc_lex_token(void) | 3432 | static 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) | |||
3593 | static BC_STATUS zbc_parse_pushSTR(void) | 3588 | static 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) | |||
3607 | static void bc_parse_pushNUM(void) | 3602 | static 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 | ||
5098 | static BC_STATUS zdc_parse_exprs_until_eof(void) | 5093 | static 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) | |||
6914 | static BC_STATUS zbc_vm_execute_FILE(FILE *fp, const char *filename) | 6909 | static 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) |