aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-12-05 00:22:34 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-12-05 15:43:35 +0100
commit51fb8aa5c132446b188196cd6b3d55ff255461dd (patch)
tree2c51c216ddd48d2901748093f3b55de1a8ffcf23
parentcb9a99f3bb883e319e674a45f906fd3a85c235f7 (diff)
downloadbusybox-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.c403
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
502struct BcLexKeyword {
503 char name8[8];
504};
505#define BC_LEX_KW_ENTRY(a, b, c) \
506 { .name8 = a /*, .len = b, .posix = c*/ }
507static 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};
533enum {
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
500struct BcLex; 562struct BcLex;
501typedef BcStatus (*BcLexNext)(struct BcLex *); 563typedef BcStatus (*BcLexNext)(struct BcLex *);
@@ -611,17 +673,6 @@ typedef struct BcParse {
611 673
612#if ENABLE_BC 674#if ENABLE_BC
613 675
614typedef 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
625static BcStatus bc_lex_token(BcLex *l); 676static 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 {
755static void bc_vm_info(void); 806static void bc_vm_info(void);
756 807
757#if ENABLE_BC 808#if ENABLE_BC
758static 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
828static const size_t dc_lex_regs_len = sizeof(dc_lex_regs) / sizeof(BcLexType);
829
830static const BcLexType dc_lex_tokens[] = { 857static 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>";
892static const char *bc_lib_name = "gen/lib.bc"; 919static const char *bc_lib_name = "gen/lib.bc";
893 920
894static const char bc_lib[] = { 921static 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)
2913static BcStatus bc_lex_identifier(BcLex *l) 3032static 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 <= '~' &&