aboutsummaryrefslogtreecommitdiff
path: root/miscutils
diff options
context:
space:
mode:
Diffstat (limited to 'miscutils')
-rw-r--r--miscutils/bc.c151
1 files changed, 16 insertions, 135 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c
index e3e8198b7..70db2ce3d 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -2994,7 +2994,7 @@ static BcStatus bc_lex_identifier(BcLex *l)
2994 l->t.t = BC_LEX_KEY_1st_keyword + i; 2994 l->t.t = BC_LEX_KEY_1st_keyword + i;
2995 if (!bc_lex_kws_POSIX(i)) { 2995 if (!bc_lex_kws_POSIX(i)) {
2996 s = bc_posix_error_fmt("%sthe '%.8s' keyword", "POSIX does not allow ", bc_lex_kws[i].name8); 2996 s = bc_posix_error_fmt("%sthe '%.8s' keyword", "POSIX does not allow ", bc_lex_kws[i].name8);
2997 if (s) return s; 2997 ERROR_RETURN(if (s) return s;)
2998 } 2998 }
2999 2999
3000 // We minus 1 because the index has already been incremented. 3000 // We minus 1 because the index has already been incremented.
@@ -3096,123 +3096,75 @@ static FAST_FUNC BcStatus bc_lex_token(BcLex *l)
3096 3096
3097 // This is the workhorse of the lexer. 3097 // This is the workhorse of the lexer.
3098 switch (c) { 3098 switch (c) {
3099
3100 case '\0': 3099 case '\0':
3101 case '\n': 3100 case '\n':
3102 {
3103 l->newline = true; 3101 l->newline = true;
3104 l->t.t = !c ? BC_LEX_EOF : BC_LEX_NLINE; 3102 l->t.t = !c ? BC_LEX_EOF : BC_LEX_NLINE;
3105 break; 3103 break;
3106 }
3107
3108 case '\t': 3104 case '\t':
3109 case '\v': 3105 case '\v':
3110 case '\f': 3106 case '\f':
3111 case '\r': 3107 case '\r':
3112 case ' ': 3108 case ' ':
3113 {
3114 bc_lex_whitespace(l); 3109 bc_lex_whitespace(l);
3115 break; 3110 break;
3116 }
3117
3118 case '!': 3111 case '!':
3119 {
3120 bc_lex_assign(l, BC_LEX_OP_REL_NE, BC_LEX_OP_BOOL_NOT); 3112 bc_lex_assign(l, BC_LEX_OP_REL_NE, BC_LEX_OP_BOOL_NOT);
3121
3122 if (l->t.t == BC_LEX_OP_BOOL_NOT) { 3113 if (l->t.t == BC_LEX_OP_BOOL_NOT) {
3123 s = bc_POSIX_does_not_allow_bool_ops_this_is_bad("!"); 3114 s = bc_POSIX_does_not_allow_bool_ops_this_is_bad("!");
3124 if (s) return s; 3115 ERROR_RETURN(if (s) return s;)
3125 } 3116 }
3126
3127 break; 3117 break;
3128 }
3129
3130 case '"': 3118 case '"':
3131 {
3132 s = bc_lex_string(l); 3119 s = bc_lex_string(l);
3133 break; 3120 break;
3134 }
3135
3136 case '#': 3121 case '#':
3137 {
3138 s = bc_POSIX_does_not_allow("'#' script comments"); 3122 s = bc_POSIX_does_not_allow("'#' script comments");
3139 if (s) return s; 3123 ERROR_RETURN(if (s) return s;)
3140
3141 bc_lex_lineComment(l); 3124 bc_lex_lineComment(l);
3142
3143 break; 3125 break;
3144 }
3145
3146 case '%': 3126 case '%':
3147 {
3148 bc_lex_assign(l, BC_LEX_OP_ASSIGN_MODULUS, BC_LEX_OP_MODULUS); 3127 bc_lex_assign(l, BC_LEX_OP_ASSIGN_MODULUS, BC_LEX_OP_MODULUS);
3149 break; 3128 break;
3150 }
3151
3152 case '&': 3129 case '&':
3153 {
3154 c2 = l->buf[l->i]; 3130 c2 = l->buf[l->i];
3155 if (c2 == '&') { 3131 if (c2 == '&') {
3156
3157 s = bc_POSIX_does_not_allow_bool_ops_this_is_bad("&&"); 3132 s = bc_POSIX_does_not_allow_bool_ops_this_is_bad("&&");
3158 if (s) return s; 3133 ERROR_RETURN(if (s) return s;)
3159
3160 ++l->i; 3134 ++l->i;
3161 l->t.t = BC_LEX_OP_BOOL_AND; 3135 l->t.t = BC_LEX_OP_BOOL_AND;
3162 } 3136 } else {
3163 else {
3164 l->t.t = BC_LEX_INVALID; 3137 l->t.t = BC_LEX_INVALID;
3165 s = bc_error_bad_character('&'); 3138 s = bc_error_bad_character('&');
3166 } 3139 }
3167
3168 break; 3140 break;
3169 }
3170
3171 case '(': 3141 case '(':
3172 case ')': 3142 case ')':
3173 {
3174 l->t.t = (BcLexType)(c - '(' + BC_LEX_LPAREN); 3143 l->t.t = (BcLexType)(c - '(' + BC_LEX_LPAREN);
3175 break; 3144 break;
3176 }
3177
3178 case '*': 3145 case '*':
3179 {
3180 bc_lex_assign(l, BC_LEX_OP_ASSIGN_MULTIPLY, BC_LEX_OP_MULTIPLY); 3146 bc_lex_assign(l, BC_LEX_OP_ASSIGN_MULTIPLY, BC_LEX_OP_MULTIPLY);
3181 break; 3147 break;
3182 }
3183
3184 case '+': 3148 case '+':
3185 {
3186 c2 = l->buf[l->i]; 3149 c2 = l->buf[l->i];
3187 if (c2 == '+') { 3150 if (c2 == '+') {
3188 ++l->i; 3151 ++l->i;
3189 l->t.t = BC_LEX_OP_INC; 3152 l->t.t = BC_LEX_OP_INC;
3190 } 3153 } else
3191 else
3192 bc_lex_assign(l, BC_LEX_OP_ASSIGN_PLUS, BC_LEX_OP_PLUS); 3154 bc_lex_assign(l, BC_LEX_OP_ASSIGN_PLUS, BC_LEX_OP_PLUS);
3193 break; 3155 break;
3194 }
3195
3196 case ',': 3156 case ',':
3197 {
3198 l->t.t = BC_LEX_COMMA; 3157 l->t.t = BC_LEX_COMMA;
3199 break; 3158 break;
3200 }
3201
3202 case '-': 3159 case '-':
3203 {
3204 c2 = l->buf[l->i]; 3160 c2 = l->buf[l->i];
3205 if (c2 == '-') { 3161 if (c2 == '-') {
3206 ++l->i; 3162 ++l->i;
3207 l->t.t = BC_LEX_OP_DEC; 3163 l->t.t = BC_LEX_OP_DEC;
3208 } 3164 } else
3209 else
3210 bc_lex_assign(l, BC_LEX_OP_ASSIGN_MINUS, BC_LEX_OP_MINUS); 3165 bc_lex_assign(l, BC_LEX_OP_ASSIGN_MINUS, BC_LEX_OP_MINUS);
3211 break; 3166 break;
3212 }
3213
3214 case '.': 3167 case '.':
3215 {
3216 if (isdigit(l->buf[l->i])) 3168 if (isdigit(l->buf[l->i]))
3217 s = zbc_lex_number(l, c); 3169 s = zbc_lex_number(l, c);
3218 else { 3170 else {
@@ -3220,18 +3172,13 @@ static FAST_FUNC BcStatus bc_lex_token(BcLex *l)
3220 s = bc_POSIX_does_not_allow("a period ('.') as a shortcut for the last result"); 3172 s = bc_POSIX_does_not_allow("a period ('.') as a shortcut for the last result");
3221 } 3173 }
3222 break; 3174 break;
3223 }
3224
3225 case '/': 3175 case '/':
3226 {
3227 c2 = l->buf[l->i]; 3176 c2 = l->buf[l->i];
3228 if (c2 == '*') 3177 if (c2 == '*')
3229 s = zbc_lex_comment(l); 3178 s = zbc_lex_comment(l);
3230 else 3179 else
3231 bc_lex_assign(l, BC_LEX_OP_ASSIGN_DIVIDE, BC_LEX_OP_DIVIDE); 3180 bc_lex_assign(l, BC_LEX_OP_ASSIGN_DIVIDE, BC_LEX_OP_DIVIDE);
3232 break; 3181 break;
3233 }
3234
3235 case '0': 3182 case '0':
3236 case '1': 3183 case '1':
3237 case '2': 3184 case '2':
@@ -3248,59 +3195,34 @@ static FAST_FUNC BcStatus bc_lex_token(BcLex *l)
3248 case 'D': 3195 case 'D':
3249 case 'E': 3196 case 'E':
3250 case 'F': 3197 case 'F':
3251 {
3252 s = zbc_lex_number(l, c); 3198 s = zbc_lex_number(l, c);
3253 break; 3199 break;
3254 }
3255
3256 case ';': 3200 case ';':
3257 {
3258 l->t.t = BC_LEX_SCOLON; 3201 l->t.t = BC_LEX_SCOLON;
3259 break; 3202 break;
3260 }
3261
3262 case '<': 3203 case '<':
3263 {
3264 bc_lex_assign(l, BC_LEX_OP_REL_LE, BC_LEX_OP_REL_LT); 3204 bc_lex_assign(l, BC_LEX_OP_REL_LE, BC_LEX_OP_REL_LT);
3265 break; 3205 break;
3266 }
3267
3268 case '=': 3206 case '=':
3269 {
3270 bc_lex_assign(l, BC_LEX_OP_REL_EQ, BC_LEX_OP_ASSIGN); 3207 bc_lex_assign(l, BC_LEX_OP_REL_EQ, BC_LEX_OP_ASSIGN);
3271 break; 3208 break;
3272 }
3273
3274 case '>': 3209 case '>':
3275 {
3276 bc_lex_assign(l, BC_LEX_OP_REL_GE, BC_LEX_OP_REL_GT); 3210 bc_lex_assign(l, BC_LEX_OP_REL_GE, BC_LEX_OP_REL_GT);
3277 break; 3211 break;
3278 }
3279
3280 case '[': 3212 case '[':
3281 case ']': 3213 case ']':
3282 {
3283 l->t.t = (BcLexType)(c - '[' + BC_LEX_LBRACKET); 3214 l->t.t = (BcLexType)(c - '[' + BC_LEX_LBRACKET);
3284 break; 3215 break;
3285 }
3286
3287 case '\\': 3216 case '\\':
3288 {
3289 if (l->buf[l->i] == '\n') { 3217 if (l->buf[l->i] == '\n') {
3290 l->t.t = BC_LEX_WHITESPACE; 3218 l->t.t = BC_LEX_WHITESPACE;
3291 ++l->i; 3219 ++l->i;
3292 } 3220 } else
3293 else
3294 s = bc_error_bad_character(c); 3221 s = bc_error_bad_character(c);
3295 break; 3222 break;
3296 }
3297
3298 case '^': 3223 case '^':
3299 {
3300 bc_lex_assign(l, BC_LEX_OP_ASSIGN_POWER, BC_LEX_OP_POWER); 3224 bc_lex_assign(l, BC_LEX_OP_ASSIGN_POWER, BC_LEX_OP_POWER);
3301 break; 3225 break;
3302 }
3303
3304 case 'a': 3226 case 'a':
3305 case 'b': 3227 case 'b':
3306 case 'c': 3228 case 'c':
@@ -3327,43 +3249,28 @@ static FAST_FUNC BcStatus bc_lex_token(BcLex *l)
3327 case 'x': 3249 case 'x':
3328 case 'y': 3250 case 'y':
3329 case 'z': 3251 case 'z':
3330 {
3331 s = bc_lex_identifier(l); 3252 s = bc_lex_identifier(l);
3332 break; 3253 break;
3333 }
3334
3335 case '{': 3254 case '{':
3336 case '}': 3255 case '}':
3337 {
3338 l->t.t = (BcLexType)(c - '{' + BC_LEX_LBRACE); 3256 l->t.t = (BcLexType)(c - '{' + BC_LEX_LBRACE);
3339 break; 3257 break;
3340 }
3341
3342 case '|': 3258 case '|':
3343 {
3344 c2 = l->buf[l->i]; 3259 c2 = l->buf[l->i];
3345
3346 if (c2 == '|') { 3260 if (c2 == '|') {
3347 s = bc_POSIX_does_not_allow_bool_ops_this_is_bad("||"); 3261 s = bc_POSIX_does_not_allow_bool_ops_this_is_bad("||");
3348 if (s) return s; 3262 ERROR_RETURN(if (s) return s;)
3349
3350 ++l->i; 3263 ++l->i;
3351 l->t.t = BC_LEX_OP_BOOL_OR; 3264 l->t.t = BC_LEX_OP_BOOL_OR;
3352 } 3265 } else {
3353 else {
3354 l->t.t = BC_LEX_INVALID; 3266 l->t.t = BC_LEX_INVALID;
3355 s = bc_error_bad_character(c); 3267 s = bc_error_bad_character(c);
3356 } 3268 }
3357
3358 break; 3269 break;
3359 }
3360
3361 default: 3270 default:
3362 {
3363 l->t.t = BC_LEX_INVALID; 3271 l->t.t = BC_LEX_INVALID;
3364 s = bc_error_bad_character(c); 3272 s = bc_error_bad_character(c);
3365 break; 3273 break;
3366 }
3367 } 3274 }
3368 3275
3369 return s; 3276 return s;
@@ -3443,37 +3350,28 @@ static FAST_FUNC BcStatus dc_lex_token(BcLex *l)
3443 return zdc_lex_register(l); 3350 return zdc_lex_register(l);
3444 } 3351 }
3445 3352
3446 if (c >= '%' && c <= '~' && 3353 if (c >= '%' && c <= '~'
3447 (l->t.t = dc_lex_tokens[(c - '%')]) != BC_LEX_INVALID) 3354 && (l->t.t = dc_lex_tokens[(c - '%')]) != BC_LEX_INVALID
3448 { 3355 ) {
3449 return s; 3356 return s;
3450 } 3357 }
3451 3358
3452 // This is the workhorse of the lexer. 3359 // This is the workhorse of the lexer.
3453 switch (c) { 3360 switch (c) {
3454
3455 case '\0': 3361 case '\0':
3456 {
3457 l->t.t = BC_LEX_EOF; 3362 l->t.t = BC_LEX_EOF;
3458 break; 3363 break;
3459 }
3460
3461 case '\n': 3364 case '\n':
3462 case '\t': 3365 case '\t':
3463 case '\v': 3366 case '\v':
3464 case '\f': 3367 case '\f':
3465 case '\r': 3368 case '\r':
3466 case ' ': 3369 case ' ':
3467 {
3468 l->newline = (c == '\n'); 3370 l->newline = (c == '\n');
3469 bc_lex_whitespace(l); 3371 bc_lex_whitespace(l);
3470 break; 3372 break;
3471 }
3472
3473 case '!': 3373 case '!':
3474 {
3475 c2 = l->buf[l->i]; 3374 c2 = l->buf[l->i];
3476
3477 if (c2 == '=') 3375 if (c2 == '=')
3478 l->t.t = BC_LEX_OP_REL_NE; 3376 l->t.t = BC_LEX_OP_REL_NE;
3479 else if (c2 == '<') 3377 else if (c2 == '<')
@@ -3482,26 +3380,17 @@ static FAST_FUNC BcStatus dc_lex_token(BcLex *l)
3482 l->t.t = BC_LEX_OP_REL_GE; 3380 l->t.t = BC_LEX_OP_REL_GE;
3483 else 3381 else
3484 return bc_error_bad_character(c); 3382 return bc_error_bad_character(c);
3485
3486 ++l->i; 3383 ++l->i;
3487 break; 3384 break;
3488 }
3489
3490 case '#': 3385 case '#':
3491 {
3492 bc_lex_lineComment(l); 3386 bc_lex_lineComment(l);
3493 break; 3387 break;
3494 }
3495
3496 case '.': 3388 case '.':
3497 {
3498 if (isdigit(l->buf[l->i])) 3389 if (isdigit(l->buf[l->i]))
3499 s = zbc_lex_number(l, c); 3390 s = zbc_lex_number(l, c);
3500 else 3391 else
3501 s = bc_error_bad_character(c); 3392 s = bc_error_bad_character(c);
3502 break; 3393 break;
3503 }
3504
3505 case '0': 3394 case '0':
3506 case '1': 3395 case '1':
3507 case '2': 3396 case '2':
@@ -3518,23 +3407,15 @@ static FAST_FUNC BcStatus dc_lex_token(BcLex *l)
3518 case 'D': 3407 case 'D':
3519 case 'E': 3408 case 'E':
3520 case 'F': 3409 case 'F':
3521 {
3522 s = zbc_lex_number(l, c); 3410 s = zbc_lex_number(l, c);
3523 break; 3411 break;
3524 }
3525
3526 case '[': 3412 case '[':
3527 {
3528 s = zdc_lex_string(l); 3413 s = zdc_lex_string(l);
3529 break; 3414 break;
3530 }
3531
3532 default: 3415 default:
3533 {
3534 l->t.t = BC_LEX_INVALID; 3416 l->t.t = BC_LEX_INVALID;
3535 s = bc_error_bad_character(c); 3417 s = bc_error_bad_character(c);
3536 break; 3418 break;
3537 }
3538 } 3419 }
3539 3420
3540 return s; 3421 return s;
@@ -4112,7 +3993,7 @@ static BcStatus bc_parse_return(BcParse *p)
4112 3993
4113 if (!paren || p->l.t.last != BC_LEX_RPAREN) { 3994 if (!paren || p->l.t.last != BC_LEX_RPAREN) {
4114 s = bc_POSIX_requires("parentheses around return expressions"); 3995 s = bc_POSIX_requires("parentheses around return expressions");
4115 if (s) return s; 3996 ERROR_RETURN(if (s) return s;)
4116 } 3997 }
4117 3998
4118 bc_parse_push(p, BC_INST_RET); 3999 bc_parse_push(p, BC_INST_RET);
@@ -5013,11 +4894,11 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags, BcParseNext ne
5013 4894
5014 if (!(flags & BC_PARSE_REL) && nrelops) { 4895 if (!(flags & BC_PARSE_REL) && nrelops) {
5015 s = bc_POSIX_does_not_allow("comparison operators outside if or loops"); 4896 s = bc_POSIX_does_not_allow("comparison operators outside if or loops");
5016 if (s) return s; 4897 ERROR_RETURN(if (s) return s;)
5017 } 4898 }
5018 else if ((flags & BC_PARSE_REL) && nrelops > 1) { 4899 else if ((flags & BC_PARSE_REL) && nrelops > 1) {
5019 s = bc_POSIX_requires("exactly one comparison operator per condition"); 4900 s = bc_POSIX_requires("exactly one comparison operator per condition");
5020 if (s) return s; 4901 ERROR_RETURN(if (s) return s;)
5021 } 4902 }
5022 4903
5023 if (flags & BC_PARSE_PRINT) { 4904 if (flags & BC_PARSE_PRINT) {