diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-05 00:22:34 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-05 15:43:35 +0100 |
commit | 51fb8aa5c132446b188196cd6b3d55ff255461dd (patch) | |
tree | 2c51c216ddd48d2901748093f3b55de1a8ffcf23 | |
parent | cb9a99f3bb883e319e674a45f906fd3a85c235f7 (diff) | |
download | busybox-w32-51fb8aa5c132446b188196cd6b3d55ff255461dd.tar.gz busybox-w32-51fb8aa5c132446b188196cd6b3d55ff255461dd.tar.bz2 busybox-w32-51fb8aa5c132446b188196cd6b3d55ff255461dd.zip |
bc: store library in ASCII, shrink keyword parsing code
Also, use ARRAY_SIZE() where appropriate
function old new delta
bc_lib 1878 1877 -1
bc_program_index 66 64 -2
bc_lex_token 1282 1266 -16
bc_lex_kws 220 160 -60
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/4 up/down: 0/-79) Total: -79 bytes
text data bss dec hex filename
987518 485 7296 995299 f2fe3 busybox_old
987440 485 7296 995221 f2f95 busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | miscutils/bc.c | 403 |
1 files changed, 263 insertions, 140 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index 7a11e63de..45680c139 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
@@ -445,19 +445,21 @@ typedef enum BcLexType { | |||
445 | BC_LEX_NAME, | 445 | BC_LEX_NAME, |
446 | BC_LEX_NUMBER, | 446 | BC_LEX_NUMBER, |
447 | 447 | ||
448 | BC_LEX_KEY_AUTO, | 448 | BC_LEX_KEY_1st_keyword, |
449 | BC_LEX_KEY_AUTO = BC_LEX_KEY_1st_keyword, | ||
449 | BC_LEX_KEY_BREAK, | 450 | BC_LEX_KEY_BREAK, |
450 | BC_LEX_KEY_CONTINUE, | 451 | BC_LEX_KEY_CONTINUE, |
451 | BC_LEX_KEY_DEFINE, | 452 | BC_LEX_KEY_DEFINE, |
452 | BC_LEX_KEY_ELSE, | 453 | BC_LEX_KEY_ELSE, |
453 | BC_LEX_KEY_FOR, | 454 | BC_LEX_KEY_FOR, |
454 | BC_LEX_KEY_HALT, | 455 | BC_LEX_KEY_HALT, |
455 | BC_LEX_KEY_IBASE, | 456 | // code uses "type - BC_LEX_KEY_IBASE + BC_INST_IBASE" construct, |
457 | BC_LEX_KEY_IBASE, // relative order should match for: BC_INST_IBASE | ||
456 | BC_LEX_KEY_IF, | 458 | BC_LEX_KEY_IF, |
457 | BC_LEX_KEY_LAST, | 459 | BC_LEX_KEY_LAST, // relative order should match for: BC_INST_LAST |
458 | BC_LEX_KEY_LENGTH, | 460 | BC_LEX_KEY_LENGTH, |
459 | BC_LEX_KEY_LIMITS, | 461 | BC_LEX_KEY_LIMITS, |
460 | BC_LEX_KEY_OBASE, | 462 | BC_LEX_KEY_OBASE, // relative order should match for: BC_INST_OBASE |
461 | BC_LEX_KEY_PRINT, | 463 | BC_LEX_KEY_PRINT, |
462 | BC_LEX_KEY_QUIT, | 464 | BC_LEX_KEY_QUIT, |
463 | BC_LEX_KEY_READ, | 465 | BC_LEX_KEY_READ, |
@@ -494,8 +496,68 @@ typedef enum BcLexType { | |||
494 | BC_LEX_NQUIT, | 496 | BC_LEX_NQUIT, |
495 | BC_LEX_SCALE_FACTOR, | 497 | BC_LEX_SCALE_FACTOR, |
496 | #endif | 498 | #endif |
497 | |||
498 | } BcLexType; | 499 | } BcLexType; |
500 | // must match order of BC_LEX_KEY_foo etc above | ||
501 | #if ENABLE_BC | ||
502 | struct BcLexKeyword { | ||
503 | char name8[8]; | ||
504 | }; | ||
505 | #define BC_LEX_KW_ENTRY(a, b, c) \ | ||
506 | { .name8 = a /*, .len = b, .posix = c*/ } | ||
507 | static const struct BcLexKeyword bc_lex_kws[20] = { | ||
508 | BC_LEX_KW_ENTRY("auto" , 4, 1), // 0 | ||
509 | BC_LEX_KW_ENTRY("break" , 5, 1), // 1 | ||
510 | BC_LEX_KW_ENTRY("continue", 8, 0), // 2 note: this one has no terminating NUL | ||
511 | BC_LEX_KW_ENTRY("define" , 6, 1), // 3 | ||
512 | |||
513 | BC_LEX_KW_ENTRY("else" , 4, 0), // 4 | ||
514 | BC_LEX_KW_ENTRY("for" , 3, 1), // 5 | ||
515 | BC_LEX_KW_ENTRY("halt" , 4, 0), // 6 | ||
516 | BC_LEX_KW_ENTRY("ibase" , 5, 1), // 7 | ||
517 | |||
518 | BC_LEX_KW_ENTRY("if" , 2, 1), // 8 | ||
519 | BC_LEX_KW_ENTRY("last" , 4, 0), // 9 | ||
520 | BC_LEX_KW_ENTRY("length" , 6, 1), // 10 | ||
521 | BC_LEX_KW_ENTRY("limits" , 6, 0), // 11 | ||
522 | |||
523 | BC_LEX_KW_ENTRY("obase" , 5, 1), // 12 | ||
524 | BC_LEX_KW_ENTRY("print" , 5, 0), // 13 | ||
525 | BC_LEX_KW_ENTRY("quit" , 4, 1), // 14 | ||
526 | BC_LEX_KW_ENTRY("read" , 4, 0), // 15 | ||
527 | |||
528 | BC_LEX_KW_ENTRY("return" , 6, 1), // 16 | ||
529 | BC_LEX_KW_ENTRY("scale" , 5, 1), // 17 | ||
530 | BC_LEX_KW_ENTRY("sqrt" , 4, 1), // 18 | ||
531 | BC_LEX_KW_ENTRY("while" , 5, 1), // 19 | ||
532 | }; | ||
533 | enum { | ||
534 | POSIX_KWORD_MASK = 0 | ||
535 | | (1 << 0) | ||
536 | | (1 << 1) | ||
537 | | (0 << 2) | ||
538 | | (1 << 3) | ||
539 | \ | ||
540 | | (0 << 4) | ||
541 | | (1 << 5) | ||
542 | | (0 << 6) | ||
543 | | (1 << 7) | ||
544 | \ | ||
545 | | (1 << 8) | ||
546 | | (0 << 9) | ||
547 | | (1 << 10) | ||
548 | | (0 << 11) | ||
549 | \ | ||
550 | | (1 << 12) | ||
551 | | (0 << 13) | ||
552 | | (1 << 14) | ||
553 | | (0 << 15) | ||
554 | \ | ||
555 | | (1 << 16) | ||
556 | | (1 << 17) | ||
557 | | (1 << 18) | ||
558 | | (1 << 19) | ||
559 | }; | ||
560 | #endif | ||
499 | 561 | ||
500 | struct BcLex; | 562 | struct BcLex; |
501 | typedef BcStatus (*BcLexNext)(struct BcLex *); | 563 | typedef BcStatus (*BcLexNext)(struct BcLex *); |
@@ -611,17 +673,6 @@ typedef struct BcParse { | |||
611 | 673 | ||
612 | #if ENABLE_BC | 674 | #if ENABLE_BC |
613 | 675 | ||
614 | typedef struct BcLexKeyword { | ||
615 | const char name[9]; | ||
616 | const char len; | ||
617 | const bool posix; | ||
618 | } BcLexKeyword; | ||
619 | |||
620 | #define BC_LEX_KW_ENTRY(a, b, c) \ | ||
621 | { \ | ||
622 | .name = a, .len = (b), .posix = (c) \ | ||
623 | } | ||
624 | |||
625 | static BcStatus bc_lex_token(BcLex *l); | 676 | static BcStatus bc_lex_token(BcLex *l); |
626 | 677 | ||
627 | #define BC_PARSE_TOP_OP(p) (*((BcLexType *) bc_vec_top(&(p)->ops))) | 678 | #define BC_PARSE_TOP_OP(p) (*((BcLexType *) bc_vec_top(&(p)->ops))) |
@@ -755,28 +806,6 @@ struct globals { | |||
755 | static void bc_vm_info(void); | 806 | static void bc_vm_info(void); |
756 | 807 | ||
757 | #if ENABLE_BC | 808 | #if ENABLE_BC |
758 | static const BcLexKeyword bc_lex_kws[20] = { | ||
759 | BC_LEX_KW_ENTRY("auto", 4, true), | ||
760 | BC_LEX_KW_ENTRY("break", 5, true), | ||
761 | BC_LEX_KW_ENTRY("continue", 8, false), | ||
762 | BC_LEX_KW_ENTRY("define", 6, true), | ||
763 | BC_LEX_KW_ENTRY("else", 4, false), | ||
764 | BC_LEX_KW_ENTRY("for", 3, true), | ||
765 | BC_LEX_KW_ENTRY("halt", 4, false), | ||
766 | BC_LEX_KW_ENTRY("ibase", 5, true), | ||
767 | BC_LEX_KW_ENTRY("if", 2, true), | ||
768 | BC_LEX_KW_ENTRY("last", 4, false), | ||
769 | BC_LEX_KW_ENTRY("length", 6, true), | ||
770 | BC_LEX_KW_ENTRY("limits", 6, false), | ||
771 | BC_LEX_KW_ENTRY("obase", 5, true), | ||
772 | BC_LEX_KW_ENTRY("print", 5, false), | ||
773 | BC_LEX_KW_ENTRY("quit", 4, true), | ||
774 | BC_LEX_KW_ENTRY("read", 4, false), | ||
775 | BC_LEX_KW_ENTRY("return", 6, true), | ||
776 | BC_LEX_KW_ENTRY("scale", 5, true), | ||
777 | BC_LEX_KW_ENTRY("sqrt", 4, true), | ||
778 | BC_LEX_KW_ENTRY("while", 5, true), | ||
779 | }; | ||
780 | 809 | ||
781 | // This is an array that corresponds to token types. An entry is | 810 | // This is an array that corresponds to token types. An entry is |
782 | // true if the token is valid in an expression, false otherwise. | 811 | // true if the token is valid in an expression, false otherwise. |
@@ -825,8 +854,6 @@ static const BcLexType dc_lex_regs[] = { | |||
825 | BC_LEX_STORE_PUSH, | 854 | BC_LEX_STORE_PUSH, |
826 | }; | 855 | }; |
827 | 856 | ||
828 | static const size_t dc_lex_regs_len = sizeof(dc_lex_regs) / sizeof(BcLexType); | ||
829 | |||
830 | static const BcLexType dc_lex_tokens[] = { | 857 | static const BcLexType dc_lex_tokens[] = { |
831 | BC_LEX_OP_MODULUS, BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_LPAREN, | 858 | BC_LEX_OP_MODULUS, BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_LPAREN, |
832 | BC_LEX_INVALID, BC_LEX_OP_MULTIPLY, BC_LEX_OP_PLUS, BC_LEX_INVALID, | 859 | BC_LEX_INVALID, BC_LEX_OP_MULTIPLY, BC_LEX_OP_PLUS, BC_LEX_INVALID, |
@@ -892,86 +919,178 @@ static const char bc_program_stdin_name[] = "<stdin>"; | |||
892 | static const char *bc_lib_name = "gen/lib.bc"; | 919 | static const char *bc_lib_name = "gen/lib.bc"; |
893 | 920 | ||
894 | static const char bc_lib[] = { | 921 | static const char bc_lib[] = { |
895 | 115,99,97,108,101,61,50,48,10,100,101,102,105,110,101,32,101,40,120,41,123, | 922 | "scale=20" |
896 | 10,9,97,117,116,111,32,98,44,115,44,110,44,114,44,100,44,105,44,112,44,102, | 923 | "\ndefine e(x){" |
897 | 44,118,10,9,98,61,105,98,97,115,101,10,9,105,98,97,115,101,61,65,10,9,105,102, | 924 | "\n auto b,s,n,r,d,i,p,f,v" |
898 | 40,120,60,48,41,123,10,9,9,110,61,49,10,9,9,120,61,45,120,10,9,125,10,9,115, | 925 | "\n b=ibase" |
899 | 61,115,99,97,108,101,10,9,114,61,54,43,115,43,48,46,52,52,42,120,10,9,115,99, | 926 | "\n ibase=A" |
900 | 97,108,101,61,115,99,97,108,101,40,120,41,43,49,10,9,119,104,105,108,101,40, | 927 | "\n if(x<0){" |
901 | 120,62,49,41,123,10,9,9,100,43,61,49,10,9,9,120,47,61,50,10,9,9,115,99,97,108, | 928 | "\n n=1" |
902 | 101,43,61,49,10,9,125,10,9,115,99,97,108,101,61,114,10,9,114,61,120,43,49,10, | 929 | "\n x=-x" |
903 | 9,112,61,120,10,9,102,61,118,61,49,10,9,102,111,114,40,105,61,50,59,118,33, | 930 | "\n }" |
904 | 61,48,59,43,43,105,41,123,10,9,9,112,42,61,120,10,9,9,102,42,61,105,10,9,9, | 931 | "\n s=scale" |
905 | 118,61,112,47,102,10,9,9,114,43,61,118,10,9,125,10,9,119,104,105,108,101,40, | 932 | "\n r=6+s+0.44*x" |
906 | 40,100,45,45,41,33,61,48,41,114,42,61,114,10,9,115,99,97,108,101,61,115,10, | 933 | "\n scale=scale(x)+1" |
907 | 9,105,98,97,115,101,61,98,10,9,105,102,40,110,33,61,48,41,114,101,116,117,114, | 934 | "\n while(x>1){" |
908 | 110,40,49,47,114,41,10,9,114,101,116,117,114,110,40,114,47,49,41,10,125,10, | 935 | "\n d+=1" |
909 | 100,101,102,105,110,101,32,108,40,120,41,123,10,9,97,117,116,111,32,98,44,115, | 936 | "\n x/=2" |
910 | 44,114,44,112,44,97,44,113,44,105,44,118,10,9,98,61,105,98,97,115,101,10,9, | 937 | "\n scale+=1" |
911 | 105,98,97,115,101,61,65,10,9,105,102,40,120,60,61,48,41,123,10,9,9,114,61,40, | 938 | "\n }" |
912 | 49,45,49,48,94,115,99,97,108,101,41,47,49,10,9,9,105,98,97,115,101,61,98,10, | 939 | "\n scale=r" |
913 | 9,9,114,101,116,117,114,110,40,114,41,10,9,125,10,9,115,61,115,99,97,108,101, | 940 | "\n r=x+1" |
914 | 10,9,115,99,97,108,101,43,61,54,10,9,112,61,50,10,9,119,104,105,108,101,40, | 941 | "\n p=x" |
915 | 120,62,61,50,41,123,10,9,9,112,42,61,50,10,9,9,120,61,115,113,114,116,40,120, | 942 | "\n f=v=1" |
916 | 41,10,9,125,10,9,119,104,105,108,101,40,120,60,61,48,46,53,41,123,10,9,9,112, | 943 | "\n for(i=2;v!=0;++i){" |
917 | 42,61,50,10,9,9,120,61,115,113,114,116,40,120,41,10,9,125,10,9,114,61,97,61, | 944 | "\n p*=x" |
918 | 40,120,45,49,41,47,40,120,43,49,41,10,9,113,61,97,42,97,10,9,118,61,49,10,9, | 945 | "\n f*=i" |
919 | 102,111,114,40,105,61,51,59,118,33,61,48,59,105,43,61,50,41,123,10,9,9,97,42, | 946 | "\n v=p/f" |
920 | 61,113,10,9,9,118,61,97,47,105,10,9,9,114,43,61,118,10,9,125,10,9,114,42,61, | 947 | "\n r+=v" |
921 | 112,10,9,115,99,97,108,101,61,115,10,9,105,98,97,115,101,61,98,10,9,114,101, | 948 | "\n }" |
922 | 116,117,114,110,40,114,47,49,41,10,125,10,100,101,102,105,110,101,32,115,40, | 949 | "\n while((d--)!=0)r*=r" |
923 | 120,41,123,10,9,97,117,116,111,32,98,44,115,44,114,44,110,44,97,44,113,44,105, | 950 | "\n scale=s" |
924 | 10,9,98,61,105,98,97,115,101,10,9,105,98,97,115,101,61,65,10,9,115,61,115,99, | 951 | "\n ibase=b" |
925 | 97,108,101,10,9,115,99,97,108,101,61,49,46,49,42,115,43,50,10,9,97,61,97,40, | 952 | "\n if(n!=0)return(1/r)" |
926 | 49,41,10,9,105,102,40,120,60,48,41,123,10,9,9,110,61,49,10,9,9,120,61,45,120, | 953 | "\n return(r/1)" |
927 | 10,9,125,10,9,115,99,97,108,101,61,48,10,9,113,61,40,120,47,97,43,50,41,47, | 954 | "\n}" |
928 | 52,10,9,120,61,120,45,52,42,113,42,97,10,9,105,102,40,113,37,50,33,61,48,41, | 955 | "\ndefine l(x){" |
929 | 120,61,45,120,10,9,115,99,97,108,101,61,115,43,50,10,9,114,61,97,61,120,10, | 956 | "\n auto b,s,r,p,a,q,i,v" |
930 | 9,113,61,45,120,42,120,10,9,102,111,114,40,105,61,51,59,97,33,61,48,59,105, | 957 | "\n b=ibase" |
931 | 43,61,50,41,123,10,9,9,97,42,61,113,47,40,105,42,40,105,45,49,41,41,10,9,9, | 958 | "\n ibase=A" |
932 | 114,43,61,97,10,9,125,10,9,115,99,97,108,101,61,115,10,9,105,98,97,115,101, | 959 | "\n if(x<=0){" |
933 | 61,98,10,9,105,102,40,110,33,61,48,41,114,101,116,117,114,110,40,45,114,47, | 960 | "\n r=(1-10^scale)/1" |
934 | 49,41,10,9,114,101,116,117,114,110,40,114,47,49,41,10,125,10,100,101,102,105, | 961 | "\n ibase=b" |
935 | 110,101,32,99,40,120,41,123,10,9,97,117,116,111,32,98,44,115,10,9,98,61,105, | 962 | "\n return(r)" |
936 | 98,97,115,101,10,9,105,98,97,115,101,61,65,10,9,115,61,115,99,97,108,101,10, | 963 | "\n }" |
937 | 9,115,99,97,108,101,42,61,49,46,50,10,9,120,61,115,40,50,42,97,40,49,41,43, | 964 | "\n s=scale" |
938 | 120,41,10,9,115,99,97,108,101,61,115,10,9,105,98,97,115,101,61,98,10,9,114, | 965 | "\n scale+=6" |
939 | 101,116,117,114,110,40,120,47,49,41,10,125,10,100,101,102,105,110,101,32,97, | 966 | "\n p=2" |
940 | 40,120,41,123,10,9,97,117,116,111,32,98,44,115,44,114,44,110,44,97,44,109,44, | 967 | "\n while(x>=2){" |
941 | 116,44,102,44,105,44,117,10,9,98,61,105,98,97,115,101,10,9,105,98,97,115,101, | 968 | "\n p*=2" |
942 | 61,65,10,9,110,61,49,10,9,105,102,40,120,60,48,41,123,10,9,9,110,61,45,49,10, | 969 | "\n x=sqrt(x)" |
943 | 9,9,120,61,45,120,10,9,125,10,9,105,102,40,120,61,61,49,41,123,10,9,9,105,102, | 970 | "\n }" |
944 | 40,115,99,97,108,101,60,54,53,41,123,10,9,9,9,114,101,116,117,114,110,40,46, | 971 | "\n while(x<=0.5){" |
945 | 55,56,53,51,57,56,49,54,51,51,57,55,52,52,56,51,48,57,54,49,53,54,54,48,56, | 972 | "\n p*=2" |
946 | 52,53,56,49,57,56,55,53,55,50,49,48,52,57,50,57,50,51,52,57,56,52,51,55,55, | 973 | "\n x=sqrt(x)" |
947 | 54,52,53,53,50,52,51,55,51,54,49,52,56,48,47,110,41,10,9,9,125,10,9,125,10, | 974 | "\n }" |
948 | 9,105,102,40,120,61,61,46,50,41,123,10,9,9,105,102,40,115,99,97,108,101,60, | 975 | "\n r=a=(x-1)/(x+1)" |
949 | 54,53,41,123,10,9,9,9,114,101,116,117,114,110,40,46,49,57,55,51,57,53,53,53, | 976 | "\n q=a*a" |
950 | 57,56,52,57,56,56,48,55,53,56,51,55,48,48,52,57,55,54,53,49,57,52,55,57,48, | 977 | "\n v=1" |
951 | 50,57,51,52,52,55,53,56,53,49,48,51,55,56,55,56,53,50,49,48,49,53,49,55,54, | 978 | "\n for(i=3;v!=0;i+=2){" |
952 | 56,56,57,52,48,50,47,110,41,10,9,9,125,10,9,125,10,9,115,61,115,99,97,108,101, | 979 | "\n a*=q" |
953 | 10,9,105,102,40,120,62,46,50,41,123,10,9,9,115,99,97,108,101,43,61,53,10,9, | 980 | "\n v=a/i" |
954 | 9,97,61,97,40,46,50,41,10,9,125,10,9,115,99,97,108,101,61,115,43,51,10,9,119, | 981 | "\n r+=v" |
955 | 104,105,108,101,40,120,62,46,50,41,123,10,9,9,109,43,61,49,10,9,9,120,61,40, | 982 | "\n }" |
956 | 120,45,46,50,41,47,40,49,43,46,50,42,120,41,10,9,125,10,9,114,61,117,61,120, | 983 | "\n r*=p" |
957 | 10,9,102,61,45,120,42,120,10,9,116,61,49,10,9,102,111,114,40,105,61,51,59,116, | 984 | "\n scale=s" |
958 | 33,61,48,59,105,43,61,50,41,123,10,9,9,117,42,61,102,10,9,9,116,61,117,47,105, | 985 | "\n ibase=b" |
959 | 10,9,9,114,43,61,116,10,9,125,10,9,115,99,97,108,101,61,115,10,9,105,98,97, | 986 | "\n return(r/1)" |
960 | 115,101,61,98,10,9,114,101,116,117,114,110,40,40,109,42,97,43,114,41,47,110, | 987 | "\n}" |
961 | 41,10,125,10,100,101,102,105,110,101,32,106,40,110,44,120,41,123,10,9,97,117, | 988 | "\ndefine s(x){" |
962 | 116,111,32,98,44,115,44,111,44,97,44,105,44,118,44,102,10,9,98,61,105,98,97, | 989 | "\n auto b,s,r,n,a,q,i" |
963 | 115,101,10,9,105,98,97,115,101,61,65,10,9,115,61,115,99,97,108,101,10,9,115, | 990 | "\n b=ibase" |
964 | 99,97,108,101,61,48,10,9,110,47,61,49,10,9,105,102,40,110,60,48,41,123,10,9, | 991 | "\n ibase=A" |
965 | 9,110,61,45,110,10,9,9,105,102,40,110,37,50,61,61,49,41,111,61,49,10,9,125, | 992 | "\n s=scale" |
966 | 10,9,97,61,49,10,9,102,111,114,40,105,61,50,59,105,60,61,110,59,43,43,105,41, | 993 | "\n scale=1.1*s+2" |
967 | 97,42,61,105,10,9,115,99,97,108,101,61,49,46,53,42,115,10,9,97,61,40,120,94, | 994 | "\n a=a(1)" |
968 | 110,41,47,50,94,110,47,97,10,9,114,61,118,61,49,10,9,102,61,45,120,42,120,47, | 995 | "\n if(x<0){" |
969 | 52,10,9,115,99,97,108,101,61,115,99,97,108,101,43,108,101,110,103,116,104,40, | 996 | "\n n=1" |
970 | 97,41,45,115,99,97,108,101,40,97,41,10,9,102,111,114,40,105,61,49,59,118,33, | 997 | "\n x=-x" |
971 | 61,48,59,43,43,105,41,123,10,9,9,118,61,118,42,102,47,105,47,40,110,43,105, | 998 | "\n }" |
972 | 41,10,9,9,114,43,61,118,10,9,125,10,9,115,99,97,108,101,61,115,10,9,105,98, | 999 | "\n scale=0" |
973 | 97,115,101,61,98,10,9,105,102,40,111,33,61,48,41,97,61,45,97,10,9,114,101,116, | 1000 | "\n q=(x/a+2)/4" |
974 | 117,114,110,40,97,42,114,47,49,41,10,125,10,0 | 1001 | "\n x=x-4*q*a" |
1002 | "\n if(q%2!=0)x=-x" | ||
1003 | "\n scale=s+2" | ||
1004 | "\n r=a=x" | ||
1005 | "\n q=-x*x" | ||
1006 | "\n for(i=3;a!=0;i+=2){" | ||
1007 | "\n a*=q/(i*(i-1))" | ||
1008 | "\n r+=a" | ||
1009 | "\n }" | ||
1010 | "\n scale=s" | ||
1011 | "\n ibase=b" | ||
1012 | "\n if(n!=0)return(-r/1)" | ||
1013 | "\n return(r/1)" | ||
1014 | "\n}" | ||
1015 | "\ndefine c(x){" | ||
1016 | "\n auto b,s" | ||
1017 | "\n b=ibase" | ||
1018 | "\n ibase=A" | ||
1019 | "\n s=scale" | ||
1020 | "\n scale*=1.2" | ||
1021 | "\n x=s(2*a(1)+x)" | ||
1022 | "\n scale=s" | ||
1023 | "\n ibase=b" | ||
1024 | "\n return(x/1)" | ||
1025 | "\n}" | ||
1026 | "\ndefine a(x){" | ||
1027 | "\n auto b,s,r,n,a,m,t,f,i,u" | ||
1028 | "\n b=ibase" | ||
1029 | "\n ibase=A" | ||
1030 | "\n n=1" | ||
1031 | "\n if(x<0){" | ||
1032 | "\n n=-1" | ||
1033 | "\n x=-x" | ||
1034 | "\n }" | ||
1035 | "\n if(x==1){" | ||
1036 | "\n if(scale<65){" | ||
1037 | "\n return(.7853981633974483096156608458198757210492923498437764552437361480/n)" | ||
1038 | "\n }" | ||
1039 | "\n }" | ||
1040 | "\n if(x==.2){" | ||
1041 | "\n if(scale<65){" | ||
1042 | "\n return(.1973955598498807583700497651947902934475851037878521015176889402/n)" | ||
1043 | "\n }" | ||
1044 | "\n }" | ||
1045 | "\n s=scale" | ||
1046 | "\n if(x>.2){" | ||
1047 | "\n scale+=5" | ||
1048 | "\n a=a(.2)" | ||
1049 | "\n }" | ||
1050 | "\n scale=s+3" | ||
1051 | "\n while(x>.2){" | ||
1052 | "\n m+=1" | ||
1053 | "\n x=(x-.2)/(1+.2*x)" | ||
1054 | "\n }" | ||
1055 | "\n r=u=x" | ||
1056 | "\n f=-x*x" | ||
1057 | "\n t=1" | ||
1058 | "\n for(i=3;t!=0;i+=2){" | ||
1059 | "\n u*=f" | ||
1060 | "\n t=u/i" | ||
1061 | "\n r+=t" | ||
1062 | "\n }" | ||
1063 | "\n scale=s" | ||
1064 | "\n ibase=b" | ||
1065 | "\n return((m*a+r)/n)" | ||
1066 | "\n}" | ||
1067 | "\ndefine j(n,x){" | ||
1068 | "\n auto b,s,o,a,i,v,f" | ||
1069 | "\n b=ibase" | ||
1070 | "\n ibase=A" | ||
1071 | "\n s=scale" | ||
1072 | "\n scale=0" | ||
1073 | "\n n/=1" | ||
1074 | "\n if(n<0){" | ||
1075 | "\n n=-n" | ||
1076 | "\n if(n%2==1)o=1" | ||
1077 | "\n }" | ||
1078 | "\n a=1" | ||
1079 | "\n for(i=2;i<=n;++i)a*=i" | ||
1080 | "\n scale=1.5*s" | ||
1081 | "\n a=(x^n)/2^n/a" | ||
1082 | "\n r=v=1" | ||
1083 | "\n f=-x*x/4" | ||
1084 | "\n scale=scale+length(a)-scale(a)" | ||
1085 | "\n for(i=1;v!=0;++i){" | ||
1086 | "\n v=v*f/i/(n+i)" | ||
1087 | "\n r+=v" | ||
1088 | "\n }" | ||
1089 | "\n scale=s" | ||
1090 | "\n ibase=b" | ||
1091 | "\n if(o!=0)a=-a" | ||
1092 | "\n return(a*r/1)" | ||
1093 | "\n}" | ||
975 | }; | 1094 | }; |
976 | #endif // ENABLE_BC | 1095 | #endif // ENABLE_BC |
977 | 1096 | ||
@@ -2913,32 +3032,35 @@ static BcStatus bc_lex_text(BcLex *l, const char *text) | |||
2913 | static BcStatus bc_lex_identifier(BcLex *l) | 3032 | static BcStatus bc_lex_identifier(BcLex *l) |
2914 | { | 3033 | { |
2915 | BcStatus s; | 3034 | BcStatus s; |
2916 | size_t i; | 3035 | unsigned i; |
2917 | const char *buf = l->buf + l->i - 1; | 3036 | const char *buf = l->buf + l->i - 1; |
2918 | 3037 | ||
2919 | for (i = 0; i < sizeof(bc_lex_kws) / sizeof(bc_lex_kws[0]); ++i) { | 3038 | for (i = 0; i < ARRAY_SIZE(bc_lex_kws); ++i) { |
2920 | 3039 | const char *keyword8 = bc_lex_kws[i].name8; | |
2921 | unsigned long len = (unsigned long) bc_lex_kws[i].len; | 3040 | unsigned j = 0; |
2922 | 3041 | while (buf[j] != '\0' && buf[j] == keyword8[j]) { | |
2923 | if (strncmp(buf, bc_lex_kws[i].name, len) == 0) { | 3042 | j++; |
2924 | 3043 | if (j == 8) goto match; | |
2925 | l->t.t = BC_LEX_KEY_AUTO + (BcLexType) i; | 3044 | } |
2926 | 3045 | if (keyword8[j] != '\0') | |
2927 | if (!bc_lex_kws[i].posix) { | 3046 | continue; |
2928 | s = bc_posix_error("POSIX does not allow the following keyword:"); // bc_lex_kws[i].name | 3047 | match: |
2929 | if (s) return s; | 3048 | // buf starts with keyword bc_lex_kws[i] |
2930 | } | 3049 | l->t.t = BC_LEX_KEY_1st_keyword + i; |
2931 | 3050 | if ((1 << i) & POSIX_KWORD_MASK) { | |
2932 | // We minus 1 because the index has already been incremented. | 3051 | s = bc_posix_error("POSIX does not allow the following keyword:"); // bc_lex_kws[i].name8 |
2933 | l->i += len - 1; | 3052 | if (s) return s; |
2934 | return BC_STATUS_SUCCESS; | ||
2935 | } | 3053 | } |
3054 | |||
3055 | // We minus 1 because the index has already been incremented. | ||
3056 | l->i += j - 1; | ||
3057 | return BC_STATUS_SUCCESS; | ||
2936 | } | 3058 | } |
2937 | 3059 | ||
2938 | s = bc_lex_name(l); | 3060 | s = bc_lex_name(l); |
2939 | if (s) return s; | 3061 | if (s) return s; |
2940 | 3062 | ||
2941 | if (l->t.v.len - 1 > 1) | 3063 | if (l->t.v.len > 2) |
2942 | s = bc_posix_error("POSIX only allows one character names; the following is bad:"); // buf | 3064 | s = bc_posix_error("POSIX only allows one character names; the following is bad:"); // buf |
2943 | 3065 | ||
2944 | return s; | 3066 | return s; |
@@ -3351,8 +3473,9 @@ static BcStatus dc_lex_token(BcLex *l) | |||
3351 | char c = l->buf[l->i++], c2; | 3473 | char c = l->buf[l->i++], c2; |
3352 | size_t i; | 3474 | size_t i; |
3353 | 3475 | ||
3354 | for (i = 0; i < dc_lex_regs_len; ++i) { | 3476 | for (i = 0; i < ARRAY_SIZE(dc_lex_regs); ++i) { |
3355 | if (l->t.last == dc_lex_regs[i]) return dc_lex_register(l); | 3477 | if (l->t.last == dc_lex_regs[i]) |
3478 | return dc_lex_register(l); | ||
3356 | } | 3479 | } |
3357 | 3480 | ||
3358 | if (c >= '%' && c <= '~' && | 3481 | if (c >= '%' && c <= '~' && |