aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-12-25 23:15:59 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-12-25 23:15:59 +0100
commitc192b0442b0b3f50d4fbb34322e07f0ff3c5aecd (patch)
treecd2e0a52eb585c261ae3f65fb71b9a6f63ab97db
parentecb62edd478e8ae2b1a5f3d122e316345909a805 (diff)
downloadbusybox-w32-c192b0442b0b3f50d4fbb34322e07f0ff3c5aecd.tar.gz
busybox-w32-c192b0442b0b3f50d4fbb34322e07f0ff3c5aecd.tar.bz2
busybox-w32-c192b0442b0b3f50d4fbb34322e07f0ff3c5aecd.zip
bc: simplify input pointer manipulation while lexing
function old new delta bc_lex_name 70 68 -2 zbc_lex_number 177 174 -3 bc_vm_init 679 676 -3 bc_lex_whitespace 42 39 -3 zbc_parse_text_init 55 51 -4 bc_lex_lineComment 37 29 -8 bc_lex_assign 34 26 -8 zbc_lex_next 2039 1965 -74 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/8 up/down: 0/-105) Total: -105 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--miscutils/bc.c115
1 files changed, 55 insertions, 60 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c
index 61fb24304..809b4bfc4 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -714,10 +714,9 @@ 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;
717 size_t lex_i;
718 size_t lex_line; 717 size_t lex_line;
719 size_t lex_len;
720 const char *lex_inbuf; 718 const char *lex_inbuf;
719 const char *lex_end;
721 const char *lex_next_at; // last lex_next() was called at this string 720 const char *lex_next_at; // last lex_next() was called at this string
722 const char *lex_filename; 721 const char *lex_filename;
723 FILE *lex_input_fp; 722 FILE *lex_input_fp;
@@ -2748,12 +2747,9 @@ static void bc_lex_lineComment(void)
2748{ 2747{
2749 BcParse *p = &G.prs; 2748 BcParse *p = &G.prs;
2750 // Try: echo -n '#foo' | bc 2749 // Try: echo -n '#foo' | bc
2751 size_t i;
2752 p->lex = XC_LEX_WHITESPACE; 2750 p->lex = XC_LEX_WHITESPACE;
2753 i = p->lex_i; 2751 while (p->lex_inbuf < p->lex_end && *p->lex_inbuf != '\n')
2754 while (i < p->lex_len && p->lex_inbuf[i] != '\n') 2752 p->lex_inbuf++;
2755 i++;
2756 p->lex_i = i;
2757} 2753}
2758 2754
2759static void bc_lex_whitespace(void) 2755static void bc_lex_whitespace(void)
@@ -2761,19 +2757,19 @@ static void bc_lex_whitespace(void)
2761 BcParse *p = &G.prs; 2757 BcParse *p = &G.prs;
2762 p->lex = XC_LEX_WHITESPACE; 2758 p->lex = XC_LEX_WHITESPACE;
2763 for (;;) { 2759 for (;;) {
2764 char c = p->lex_inbuf[p->lex_i]; 2760 char c = *p->lex_inbuf;
2765 if (c == '\n') // this is XC_LEX_NLINE, not XC_LEX_WHITESPACE 2761 if (c == '\n') // this is XC_LEX_NLINE, not XC_LEX_WHITESPACE
2766 break; 2762 break;
2767 if (!isspace(c)) 2763 if (!isspace(c))
2768 break; 2764 break;
2769 p->lex_i++; 2765 p->lex_inbuf++;
2770 } 2766 }
2771} 2767}
2772 2768
2773static BC_STATUS zbc_lex_number(char start) 2769static BC_STATUS zbc_lex_number(char start)
2774{ 2770{
2775 BcParse *p = &G.prs; 2771 BcParse *p = &G.prs;
2776 const char *buf = p->lex_inbuf + p->lex_i; 2772 const char *buf = p->lex_inbuf;
2777 size_t len, i, ccnt; 2773 size_t len, i, ccnt;
2778 bool pt; 2774 bool pt;
2779 2775
@@ -2803,7 +2799,7 @@ static BC_STATUS zbc_lex_number(char start)
2803 //ccnt is the number of chars in the number string, excluding possible 2799 //ccnt is the number of chars in the number string, excluding possible
2804 //trailing "[\<newline>].[\<newline>]" (with any number of \<NL> repetitions). 2800 //trailing "[\<newline>].[\<newline>]" (with any number of \<NL> repetitions).
2805 //i is buf[i] index of the first not-yet-parsed char after that. 2801 //i is buf[i] index of the first not-yet-parsed char after that.
2806 p->lex_i += i; 2802 p->lex_inbuf += i;
2807 2803
2808 // This might overestimate the size, if there are "\<NL>"'s 2804 // This might overestimate the size, if there are "\<NL>"'s
2809 // in the number. Subtracting number_of_backslashes*2 correctly 2805 // in the number. Subtracting number_of_backslashes*2 correctly
@@ -2850,7 +2846,7 @@ static void bc_lex_name(void)
2850 p->lex = XC_LEX_NAME; 2846 p->lex = XC_LEX_NAME;
2851 2847
2852 i = 0; 2848 i = 0;
2853 buf = p->lex_inbuf + p->lex_i - 1; 2849 buf = p->lex_inbuf - 1;
2854 for (;;) { 2850 for (;;) {
2855 char c = buf[i]; 2851 char c = buf[i];
2856 if ((c < 'a' || c > 'z') && !isdigit(c) && c != '_') break; 2852 if ((c < 'a' || c > 'z') && !isdigit(c) && c != '_') break;
@@ -2867,7 +2863,7 @@ static void bc_lex_name(void)
2867 bc_vec_string(&p->lex_strnumbuf, i, buf); 2863 bc_vec_string(&p->lex_strnumbuf, i, buf);
2868 2864
2869 // Increment the index. We minus 1 because it has already been incremented. 2865 // Increment the index. We minus 1 because it has already been incremented.
2870 p->lex_i += i - 1; 2866 p->lex_inbuf += i - 1;
2871 2867
2872 //return BC_STATUS_SUCCESS; 2868 //return BC_STATUS_SUCCESS;
2873} 2869}
@@ -2954,11 +2950,10 @@ static bool bc_lex_more_input(void)
2954 } 2950 }
2955 2951
2956 p->lex_inbuf = G.input_buffer.v; 2952 p->lex_inbuf = G.input_buffer.v;
2957 p->lex_i = 0;
2958// bb_error_msg("G.input_buffer.len:%d '%s'", G.input_buffer.len, G.input_buffer.v); 2953// bb_error_msg("G.input_buffer.len:%d '%s'", G.input_buffer.len, G.input_buffer.v);
2959 p->lex_len = G.input_buffer.len - 1; // do not include NUL 2954 p->lex_end = p->lex_inbuf + G.input_buffer.len - 1; // do not include NUL
2960 2955
2961 return p->lex_len != 0; 2956 return G.input_buffer.len > 1;
2962} 2957}
2963 2958
2964IF_BC(static BC_STATUS zbc_lex_token(void);) 2959IF_BC(static BC_STATUS zbc_lex_token(void);)
@@ -2983,7 +2978,7 @@ static BC_STATUS zbc_lex_next(void)
2983 // Comments are also XC_LEX_WHITESPACE tokens and eaten here. 2978 // Comments are also XC_LEX_WHITESPACE tokens and eaten here.
2984 s = BC_STATUS_SUCCESS; 2979 s = BC_STATUS_SUCCESS;
2985 do { 2980 do {
2986 if (p->lex_i == p->lex_len) { 2981 if (p->lex_inbuf == p->lex_end) {
2987 p->lex = XC_LEX_EOF; 2982 p->lex = XC_LEX_EOF;
2988 if (!G.prs.lex_input_fp) 2983 if (!G.prs.lex_input_fp)
2989 RETURN_STATUS(BC_STATUS_SUCCESS); 2984 RETURN_STATUS(BC_STATUS_SUCCESS);
@@ -2991,9 +2986,9 @@ static BC_STATUS zbc_lex_next(void)
2991 G.prs.lex_input_fp = NULL; 2986 G.prs.lex_input_fp = NULL;
2992 RETURN_STATUS(BC_STATUS_SUCCESS); 2987 RETURN_STATUS(BC_STATUS_SUCCESS);
2993 } 2988 }
2994 // here it's guaranteed that p->lex_i is below p->lex_len 2989 // here it's guaranteed that p->lex_ibuf is below p->lex_end
2995 } 2990 }
2996 p->lex_next_at = p->lex_inbuf + p->lex_i; 2991 p->lex_next_at = p->lex_inbuf;
2997 dbg_lex("next string to parse:'%.*s'", 2992 dbg_lex("next string to parse:'%.*s'",
2998 (int)(strchrnul(p->lex_next_at, '\n') - p->lex_next_at), 2993 (int)(strchrnul(p->lex_next_at, '\n') - p->lex_next_at),
2999 p->lex_next_at 2994 p->lex_next_at
@@ -3034,8 +3029,7 @@ static BC_STATUS zbc_lex_next_and_skip_NLINE(void)
3034static BC_STATUS zbc_lex_text_init(const char *text) 3029static BC_STATUS zbc_lex_text_init(const char *text)
3035{ 3030{
3036 G.prs.lex_inbuf = text; 3031 G.prs.lex_inbuf = text;
3037 G.prs.lex_i = 0; 3032 G.prs.lex_end = text + strlen(text);
3038 G.prs.lex_len = strlen(text);
3039 G.prs.lex = G.prs.lex_last = XC_LEX_INVALID; 3033 G.prs.lex = G.prs.lex_last = XC_LEX_INVALID;
3040 RETURN_STATUS(zbc_lex_next()); 3034 RETURN_STATUS(zbc_lex_next());
3041} 3035}
@@ -3047,7 +3041,7 @@ static BC_STATUS zbc_lex_identifier(void)
3047 BcParse *p = &G.prs; 3041 BcParse *p = &G.prs;
3048 BcStatus s; 3042 BcStatus s;
3049 unsigned i; 3043 unsigned i;
3050 const char *buf = p->lex_inbuf + p->lex_i - 1; 3044 const char *buf = p->lex_inbuf - 1;
3051 3045
3052 for (i = 0; i < ARRAY_SIZE(bc_lex_kws); ++i) { 3046 for (i = 0; i < ARRAY_SIZE(bc_lex_kws); ++i) {
3053 const char *keyword8 = bc_lex_kws[i].name8; 3047 const char *keyword8 = bc_lex_kws[i].name8;
@@ -3069,7 +3063,7 @@ static BC_STATUS zbc_lex_identifier(void)
3069 } 3063 }
3070 3064
3071 // We minus 1 because the index has already been incremented. 3065 // We minus 1 because the index has already been incremented.
3072 p->lex_i += j - 1; 3066 p->lex_inbuf += j - 1;
3073 RETURN_STATUS(BC_STATUS_SUCCESS); 3067 RETURN_STATUS(BC_STATUS_SUCCESS);
3074 } 3068 }
3075 3069
@@ -3097,11 +3091,11 @@ static BC_STATUS zbc_lex_string(void)
3097 p->lex = XC_LEX_STR; 3091 p->lex = XC_LEX_STR;
3098 3092
3099 nls = 0; 3093 nls = 0;
3100 i = p->lex_i; 3094 i = 0;
3101 for (;;) { 3095 for (;;) {
3102 char c = p->lex_inbuf[i]; 3096 char c = p->lex_inbuf[i];
3103 if (c == '\0') { 3097 if (c == '\0') {
3104 p->lex_i = i; 3098 p->lex_inbuf += i;
3105 RETURN_STATUS(bc_error("unterminated string")); 3099 RETURN_STATUS(bc_error("unterminated string"));
3106 } 3100 }
3107 if (c == '"') 3101 if (c == '"')
@@ -3110,15 +3104,15 @@ static BC_STATUS zbc_lex_string(void)
3110 i++; 3104 i++;
3111 } 3105 }
3112 3106
3113 len = i - p->lex_i; 3107 len = i;
3114 // This check makes sense only if size_t is (much) larger than BC_MAX_STRING. 3108 // This check makes sense only if size_t is (much) larger than BC_MAX_STRING.
3115 if (SIZE_MAX > (BC_MAX_STRING | 0xff)) { 3109 if (SIZE_MAX > (BC_MAX_STRING | 0xff)) {
3116 if (len > BC_MAX_STRING) 3110 if (len > BC_MAX_STRING)
3117 RETURN_STATUS(bc_error("string too long: must be [1,"BC_MAX_STRING_STR"]")); 3111 RETURN_STATUS(bc_error("string too long: must be [1,"BC_MAX_STRING_STR"]"));
3118 } 3112 }
3119 bc_vec_string(&p->lex_strnumbuf, len, p->lex_inbuf + p->lex_i); 3113 bc_vec_string(&p->lex_strnumbuf, len, p->lex_inbuf);
3120 3114
3121 p->lex_i = i + 1; 3115 p->lex_inbuf += i + 1;
3122 p->lex_line += nls; 3116 p->lex_line += nls;
3123 G.err_line = p->lex_line; 3117 G.err_line = p->lex_line;
3124 3118
@@ -3129,8 +3123,8 @@ static BC_STATUS zbc_lex_string(void)
3129static void bc_lex_assign(unsigned with_and_without) 3123static void bc_lex_assign(unsigned with_and_without)
3130{ 3124{
3131 BcParse *p = &G.prs; 3125 BcParse *p = &G.prs;
3132 if (p->lex_inbuf[p->lex_i] == '=') { 3126 if (*p->lex_inbuf == '=') {
3133 p->lex_i++; 3127 p->lex_inbuf++;
3134 with_and_without >>= 8; // store "with" value 3128 with_and_without >>= 8; // store "with" value
3135 } // else store "without" value 3129 } // else store "without" value
3136 p->lex = (with_and_without & 0xff); 3130 p->lex = (with_and_without & 0xff);
@@ -3145,7 +3139,7 @@ static BC_STATUS zbc_lex_comment(void)
3145 const char *buf = p->lex_inbuf; 3139 const char *buf = p->lex_inbuf;
3146 3140
3147 p->lex = XC_LEX_WHITESPACE; 3141 p->lex = XC_LEX_WHITESPACE;
3148 i = p->lex_i; /* here buf[p->lex_i] is the '*' of opening comment delimiter */ 3142 i = 0; /* here lex_inbuf[0] is the '*' of opening comment delimiter */
3149 for (;;) { 3143 for (;;) {
3150 char c = buf[++i]; 3144 char c = buf[++i];
3151 check_star: 3145 check_star:
@@ -3156,13 +3150,13 @@ static BC_STATUS zbc_lex_comment(void)
3156 goto check_star; 3150 goto check_star;
3157 } 3151 }
3158 if (c == '\0') { 3152 if (c == '\0') {
3159 p->lex_i = i; 3153 p->lex_inbuf += i;
3160 RETURN_STATUS(bc_error("unterminated comment")); 3154 RETURN_STATUS(bc_error("unterminated comment"));
3161 } 3155 }
3162 nls += (c == '\n'); 3156 nls += (c == '\n');
3163 } 3157 }
3164 3158
3165 p->lex_i = i + 1; 3159 p->lex_inbuf += i + 1;
3166 p->lex_line += nls; 3160 p->lex_line += nls;
3167 G.err_line = p->lex_line; 3161 G.err_line = p->lex_line;
3168 3162
@@ -3175,12 +3169,13 @@ static BC_STATUS zbc_lex_token(void)
3175{ 3169{
3176 BcParse *p = &G.prs; 3170 BcParse *p = &G.prs;
3177 BcStatus s = BC_STATUS_SUCCESS; 3171 BcStatus s = BC_STATUS_SUCCESS;
3178 char c = p->lex_inbuf[p->lex_i++], c2; 3172 char c = *p->lex_inbuf++;
3173 char c2;
3179 3174
3180 // This is the workhorse of the lexer. 3175 // This is the workhorse of the lexer.
3181 switch (c) { 3176 switch (c) {
3182// case '\0': // probably never reached 3177// case '\0': // probably never reached
3183// p->lex_i--; 3178// p->lex_inbuf--;
3184// p->lex = XC_LEX_EOF; 3179// p->lex = XC_LEX_EOF;
3185// p->lex_newline = true; 3180// p->lex_newline = true;
3186// break; 3181// break;
@@ -3214,11 +3209,11 @@ static BC_STATUS zbc_lex_token(void)
3214 bc_lex_assign(BC_LEX_OP_ASSIGN_MODULUS, XC_LEX_OP_MODULUS); 3209 bc_lex_assign(BC_LEX_OP_ASSIGN_MODULUS, XC_LEX_OP_MODULUS);
3215 break; 3210 break;
3216 case '&': 3211 case '&':
3217 c2 = p->lex_inbuf[p->lex_i]; 3212 c2 = *p->lex_inbuf;
3218 if (c2 == '&') { 3213 if (c2 == '&') {
3219 s = zbc_POSIX_does_not_allow_bool_ops_this_is_bad("&&"); 3214 s = zbc_POSIX_does_not_allow_bool_ops_this_is_bad("&&");
3220 if (s) RETURN_STATUS(s); 3215 if (s) RETURN_STATUS(s);
3221 p->lex_i++; 3216 p->lex_inbuf++;
3222 p->lex = BC_LEX_OP_BOOL_AND; 3217 p->lex = BC_LEX_OP_BOOL_AND;
3223 } else { 3218 } else {
3224 p->lex = XC_LEX_INVALID; 3219 p->lex = XC_LEX_INVALID;
@@ -3233,9 +3228,9 @@ static BC_STATUS zbc_lex_token(void)
3233 bc_lex_assign(BC_LEX_OP_ASSIGN_MULTIPLY, XC_LEX_OP_MULTIPLY); 3228 bc_lex_assign(BC_LEX_OP_ASSIGN_MULTIPLY, XC_LEX_OP_MULTIPLY);
3234 break; 3229 break;
3235 case '+': 3230 case '+':
3236 c2 = p->lex_inbuf[p->lex_i]; 3231 c2 = *p->lex_inbuf;
3237 if (c2 == '+') { 3232 if (c2 == '+') {
3238 p->lex_i++; 3233 p->lex_inbuf++;
3239 p->lex = BC_LEX_OP_INC; 3234 p->lex = BC_LEX_OP_INC;
3240 } else 3235 } else
3241 bc_lex_assign(BC_LEX_OP_ASSIGN_PLUS, XC_LEX_OP_PLUS); 3236 bc_lex_assign(BC_LEX_OP_ASSIGN_PLUS, XC_LEX_OP_PLUS);
@@ -3244,15 +3239,15 @@ static BC_STATUS zbc_lex_token(void)
3244 p->lex = BC_LEX_COMMA; 3239 p->lex = BC_LEX_COMMA;
3245 break; 3240 break;
3246 case '-': 3241 case '-':
3247 c2 = p->lex_inbuf[p->lex_i]; 3242 c2 = *p->lex_inbuf;
3248 if (c2 == '-') { 3243 if (c2 == '-') {
3249 p->lex_i++; 3244 p->lex_inbuf++;
3250 p->lex = BC_LEX_OP_DEC; 3245 p->lex = BC_LEX_OP_DEC;
3251 } else 3246 } else
3252 bc_lex_assign(BC_LEX_OP_ASSIGN_MINUS, XC_LEX_OP_MINUS); 3247 bc_lex_assign(BC_LEX_OP_ASSIGN_MINUS, XC_LEX_OP_MINUS);
3253 break; 3248 break;
3254 case '.': 3249 case '.':
3255 if (isdigit(p->lex_inbuf[p->lex_i])) 3250 if (isdigit(*p->lex_inbuf))
3256 s = zbc_lex_number(c); 3251 s = zbc_lex_number(c);
3257 else { 3252 else {
3258 p->lex = BC_LEX_KEY_LAST; 3253 p->lex = BC_LEX_KEY_LAST;
@@ -3260,7 +3255,7 @@ static BC_STATUS zbc_lex_token(void)
3260 } 3255 }
3261 break; 3256 break;
3262 case '/': 3257 case '/':
3263 c2 = p->lex_inbuf[p->lex_i]; 3258 c2 = *p->lex_inbuf;
3264 if (c2 == '*') 3259 if (c2 == '*')
3265 s = zbc_lex_comment(); 3260 s = zbc_lex_comment();
3266 else 3261 else
@@ -3301,9 +3296,9 @@ static BC_STATUS zbc_lex_token(void)
3301 p->lex = (BcLexType)(c - '[' + BC_LEX_LBRACKET); 3296 p->lex = (BcLexType)(c - '[' + BC_LEX_LBRACKET);
3302 break; 3297 break;
3303 case '\\': 3298 case '\\':
3304 if (p->lex_inbuf[p->lex_i] == '\n') { 3299 if (*p->lex_inbuf == '\n') {
3305 p->lex = XC_LEX_WHITESPACE; 3300 p->lex = XC_LEX_WHITESPACE;
3306 p->lex_i++; 3301 p->lex_inbuf++;
3307 } else 3302 } else
3308 s = bc_error_bad_character(c); 3303 s = bc_error_bad_character(c);
3309 break; 3304 break;
@@ -3343,11 +3338,11 @@ static BC_STATUS zbc_lex_token(void)
3343 p->lex = (BcLexType)(c - '{' + BC_LEX_LBRACE); 3338 p->lex = (BcLexType)(c - '{' + BC_LEX_LBRACE);
3344 break; 3339 break;
3345 case '|': 3340 case '|':
3346 c2 = p->lex_inbuf[p->lex_i]; 3341 c2 = *p->lex_inbuf;
3347 if (c2 == '|') { 3342 if (c2 == '|') {
3348 s = zbc_POSIX_does_not_allow_bool_ops_this_is_bad("||"); 3343 s = zbc_POSIX_does_not_allow_bool_ops_this_is_bad("||");
3349 if (s) RETURN_STATUS(s); 3344 if (s) RETURN_STATUS(s);
3350 p->lex_i++; 3345 p->lex_inbuf++;
3351 p->lex = BC_LEX_OP_BOOL_OR; 3346 p->lex = BC_LEX_OP_BOOL_OR;
3352 } else { 3347 } else {
3353 p->lex = XC_LEX_INVALID; 3348 p->lex = XC_LEX_INVALID;
@@ -3369,13 +3364,13 @@ static BC_STATUS zbc_lex_token(void)
3369static BC_STATUS zdc_lex_register(void) 3364static BC_STATUS zdc_lex_register(void)
3370{ 3365{
3371 BcParse *p = &G.prs; 3366 BcParse *p = &G.prs;
3372 if (G_exreg && isspace(p->lex_inbuf[p->lex_i])) { 3367 if (G_exreg && isspace(*p->lex_inbuf)) {
3373 bc_lex_whitespace(); // eats whitespace (but not newline) 3368 bc_lex_whitespace(); // eats whitespace (but not newline)
3374 p->lex_i++; // bc_lex_name() expects this 3369 p->lex_inbuf++; // bc_lex_name() expects this
3375 bc_lex_name(); 3370 bc_lex_name();
3376 } else { 3371 } else {
3377 bc_vec_pop_all(&p->lex_strnumbuf); 3372 bc_vec_pop_all(&p->lex_strnumbuf);
3378 bc_vec_push(&p->lex_strnumbuf, &p->lex_inbuf[p->lex_i++]); 3373 bc_vec_push(&p->lex_strnumbuf, p->lex_inbuf++);
3379 bc_vec_pushZeroByte(&p->lex_strnumbuf); 3374 bc_vec_pushZeroByte(&p->lex_strnumbuf);
3380 p->lex = XC_LEX_NAME; 3375 p->lex = XC_LEX_NAME;
3381 } 3376 }
@@ -3394,15 +3389,15 @@ static BC_STATUS zdc_lex_string(void)
3394 3389
3395 nls = 0; 3390 nls = 0;
3396 depth = 1; 3391 depth = 1;
3397 i = p->lex_i; 3392 i = 0;
3398 for (;;) { 3393 for (;;) {
3399 char c = p->lex_inbuf[i]; 3394 char c = p->lex_inbuf[i];
3400 if (c == '\0') { 3395 if (c == '\0') {
3401 p->lex_i = i; 3396 p->lex_inbuf += i;
3402 RETURN_STATUS(bc_error("string end could not be found")); 3397 RETURN_STATUS(bc_error("string end could not be found"));
3403 } 3398 }
3404 nls += (c == '\n'); 3399 nls += (c == '\n');
3405 if (i == p->lex_i || p->lex_inbuf[i - 1] != '\\') { 3400 if (i == 0 || p->lex_inbuf[i - 1] != '\\') {
3406 if (c == '[') depth++; 3401 if (c == '[') depth++;
3407 if (c == ']') 3402 if (c == ']')
3408 if (--depth == 0) 3403 if (--depth == 0)
@@ -3416,11 +3411,11 @@ static BC_STATUS zdc_lex_string(void)
3416 bc_vec_pushZeroByte(&p->lex_strnumbuf); 3411 bc_vec_pushZeroByte(&p->lex_strnumbuf);
3417 // This check makes sense only if size_t is (much) larger than BC_MAX_STRING. 3412 // This check makes sense only if size_t is (much) larger than BC_MAX_STRING.
3418 if (SIZE_MAX > (BC_MAX_STRING | 0xff)) { 3413 if (SIZE_MAX > (BC_MAX_STRING | 0xff)) {
3419 if (i - p->lex_i > BC_MAX_STRING) 3414 if (i > BC_MAX_STRING)
3420 RETURN_STATUS(bc_error("string too long: must be [1,"BC_MAX_STRING_STR"]")); 3415 RETURN_STATUS(bc_error("string too long: must be [1,"BC_MAX_STRING_STR"]"));
3421 } 3416 }
3422 3417
3423 p->lex_i = i; 3418 p->lex_inbuf += i;
3424 p->lex_line += nls; 3419 p->lex_line += nls;
3425 G.err_line = p->lex_line; 3420 G.err_line = p->lex_line;
3426 3421
@@ -3451,7 +3446,7 @@ static BC_STATUS zdc_lex_token(void)
3451 } 3446 }
3452 3447
3453 s = BC_STATUS_SUCCESS; 3448 s = BC_STATUS_SUCCESS;
3454 c = p->lex_inbuf[p->lex_i++]; 3449 c = *p->lex_inbuf++;
3455 if (c >= '%' && c <= '~' 3450 if (c >= '%' && c <= '~'
3456 && (p->lex = dc_char_to_LEX[c - '%']) != XC_LEX_INVALID 3451 && (p->lex = dc_char_to_LEX[c - '%']) != XC_LEX_INVALID
3457 ) { 3452 ) {
@@ -3484,7 +3479,7 @@ static BC_STATUS zdc_lex_token(void)
3484 bc_lex_whitespace(); 3479 bc_lex_whitespace();
3485 break; 3480 break;
3486 case '!': 3481 case '!':
3487 c2 = p->lex_inbuf[p->lex_i]; 3482 c2 = *p->lex_inbuf;
3488 if (c2 == '=') 3483 if (c2 == '=')
3489 p->lex = XC_LEX_OP_REL_NE; 3484 p->lex = XC_LEX_OP_REL_NE;
3490 else if (c2 == '<') 3485 else if (c2 == '<')
@@ -3493,13 +3488,13 @@ static BC_STATUS zdc_lex_token(void)
3493 p->lex = XC_LEX_OP_REL_GE; 3488 p->lex = XC_LEX_OP_REL_GE;
3494 else 3489 else
3495 RETURN_STATUS(bc_error_bad_character(c)); 3490 RETURN_STATUS(bc_error_bad_character(c));
3496 p->lex_i++; 3491 p->lex_inbuf++;
3497 break; 3492 break;
3498 case '#': 3493 case '#':
3499 bc_lex_lineComment(); 3494 bc_lex_lineComment();
3500 break; 3495 break;
3501 case '.': 3496 case '.':
3502 if (isdigit(p->lex_inbuf[p->lex_i])) 3497 if (isdigit(*p->lex_inbuf))
3503 s = zbc_lex_number(c); 3498 s = zbc_lex_number(c);
3504 else 3499 else
3505 s = bc_error_bad_character(c); 3500 s = bc_error_bad_character(c);
@@ -3651,7 +3646,7 @@ static void bc_parse_reset(void)
3651 p->func = bc_program_func_BC_PROG_MAIN(); 3646 p->func = bc_program_func_BC_PROG_MAIN();
3652 } 3647 }
3653 3648
3654 p->lex_i = p->lex_len; 3649 p->lex_inbuf = p->lex_end;
3655 p->lex = XC_LEX_EOF; 3650 p->lex = XC_LEX_EOF;
3656 3651
3657 IF_BC(bc_vec_pop_all(&p->exits);) 3652 IF_BC(bc_vec_pop_all(&p->exits);)