bc: separate many bc and dc LEX constants
authorDenys Vlasenko <vda.linux@googlemail.com>
Mon, 24 Dec 2018 14:00:56 +0000 (15:00 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Mon, 24 Dec 2018 14:00:56 +0000 (15:00 +0100)
function                                             old     new   delta
zdc_parse_expr                                       510     516      +6
bc_parse_expr_empty_ok                              1963    1966      +3
dc_LEX_to_INST                                        83      56     -27
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/1 up/down: 9/-27)             Total: -18 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
miscutils/bc.c

index f9d654afbd8b1cda083cd70ece08b70623189387..a67cfbfcda84d96fa86e6e61c91fe52a5d73c4e8 100644 (file)
@@ -260,7 +260,7 @@ typedef enum BcInst {
        XC_INST_PLUS,           // for
        XC_INST_MINUS,          // these
 
-       XC_INST_REL_EQ,         // opeartions
+       XC_INST_REL_EQ,         // operations
        XC_INST_REL_LE,         // |
        XC_INST_REL_GE,         // |
        XC_INST_REL_NE,         // |
@@ -388,11 +388,16 @@ typedef struct BcInstPtr {
        IF_BC(size_t results_len_before_call;)
 } BcInstPtr;
 
-// XC_LEX_NEG is not used in lexing; it is only for parsing.
 typedef enum BcLexType {
        XC_LEX_EOF,
        XC_LEX_INVALID,
 
+       BC_LEX_NLINE,
+       BC_LEX_WHITESPACE,
+       BC_LEX_STR,
+       BC_LEX_NAME,
+       BC_LEX_NUMBER,
+
        XC_LEX_1st_op,
        XC_LEX_NEG = XC_LEX_1st_op,     // order
 
@@ -403,13 +408,14 @@ typedef enum BcLexType {
        XC_LEX_OP_PLUS,                 // for
        XC_LEX_OP_MINUS,                // these
 
-       XC_LEX_OP_REL_EQ,               // opeartions
+       XC_LEX_OP_REL_EQ,               // operations
        XC_LEX_OP_REL_LE,               // |
        XC_LEX_OP_REL_GE,               // |
        XC_LEX_OP_REL_NE,               // |
        XC_LEX_OP_REL_LT,               // |
        XC_LEX_OP_REL_GT,               // |
-
+       XC_LEX_OP_last = XC_LEX_OP_REL_GT,
+#if ENABLE_BC
        BC_LEX_OP_BOOL_NOT,             // |
        BC_LEX_OP_BOOL_OR,              // |
        BC_LEX_OP_BOOL_AND,             // |
@@ -426,9 +432,6 @@ typedef enum BcLexType {
        BC_LEX_OP_INC,
        BC_LEX_OP_DEC,
 
-       BC_LEX_NLINE,
-       BC_LEX_WHITESPACE,
-
        BC_LEX_LPAREN,
        BC_LEX_RPAREN,
 
@@ -440,10 +443,6 @@ typedef enum BcLexType {
        BC_LEX_SCOLON,
        BC_LEX_RBRACE, // should be LBRACE+2: code uses (c - '{' + BC_LEX_LBRACE)
 
-       BC_LEX_STR,
-       BC_LEX_NAME,
-       BC_LEX_NUMBER,
-
        BC_LEX_KEY_1st_keyword,
        BC_LEX_KEY_AUTO = BC_LEX_KEY_1st_keyword,
        BC_LEX_KEY_BREAK,
@@ -466,8 +465,24 @@ typedef enum BcLexType {
        BC_LEX_KEY_SCALE,
        BC_LEX_KEY_SQRT,
        BC_LEX_KEY_WHILE,
+#endif // ENABLE_BC
 
 #if ENABLE_DC
+       DC_LEX_OP_BOOL_NOT = XC_LEX_OP_last + 1,
+       DC_LEX_OP_ASSIGN,
+
+       DC_LEX_LPAREN,
+       DC_LEX_SCOLON,
+       DC_LEX_READ,
+       DC_LEX_IBASE,
+       DC_LEX_SCALE,
+       DC_LEX_OBASE,
+       DC_LEX_LENGTH,
+       DC_LEX_PRINT,
+       DC_LEX_QUIT,
+       DC_LEX_SQRT,
+       DC_LEX_LBRACE,
+
        DC_LEX_EQ_NO_REG,
        DC_LEX_OP_MODEXP,
        DC_LEX_OP_DIVMOD,
@@ -566,11 +581,11 @@ enum {
 #define EXBITS(a,b,c,d,e,f,g,h) \
        ((uint64_t)((a << 0)+(b << 1)+(c << 2)+(d << 3)+(e << 4)+(f << 5)+(g << 6)+(h << 7)))
        BC_PARSE_EXPRS_BITS = 0              // corresponding BC_LEX_xyz:
-       + (EXBITS(0,0,1,1,1,1,1,1) << (0*8)) //  0: eof    inval  -      ^      *      /      %      +
-       + (EXBITS(1,1,1,1,1,1,1,1) << (1*8)) //  8: -      ==     <=     >=     !=     <      >      !
-       + (EXBITS(1,1,1,1,1,1,1,1) << (2*8)) // 16: ||     &&     ^=     *=     /=     %=     +=     -=
-       + (EXBITS(1,1,1,0,0,1,1,0) << (3*8)) // 24: =      ++     --     NL     WS     (      )      [
-       + (EXBITS(0,0,0,0,0,0,1,1) << (4*8)) // 32: ,      ]      {      ;      }      STR    NAME   NUM
+       + (EXBITS(0,0,0,0,0,1,1,1) << (0*8)) //  0: EOF    INVAL  NL     WS     STR    NAME   NUM    -
+       + (EXBITS(1,1,1,1,1,1,1,1) << (1*8)) //  8: ^      *      /      %      +      -      ==     <=
+       + (EXBITS(1,1,1,1,1,1,1,1) << (2*8)) // 16: >=     !=     <      >      !      ||     &&     ^=
+       + (EXBITS(1,1,1,1,1,1,1,1) << (3*8)) // 24: *=     /=     %=     +=     -=     =      ++     --
+       + (EXBITS(1,1,0,0,0,0,0,0) << (4*8)) // 32: (      )      [      ,      ]      {      ;      }
        + (EXBITS(0,0,0,0,0,0,0,1) << (5*8)) // 40: auto   break  cont   define else   for    halt   ibase
        + (EXBITS(1,0,1,1,0,0,0,1) << (6*8)) // 48: obase  if     last   length limits print  quit   read
        + (EXBITS(0,1,1,0,0,0,0,0) << (7*8)) // 56: return scale  sqrt   while
@@ -617,7 +632,7 @@ static const //BcLexType - should be this type
 uint8_t
 dc_char_to_LEX[] = {
        /* %&'( */
-       XC_LEX_OP_MODULUS, XC_LEX_INVALID, XC_LEX_INVALID, BC_LEX_LPAREN,
+       XC_LEX_OP_MODULUS, XC_LEX_INVALID, XC_LEX_INVALID, DC_LEX_LPAREN,
        /* )*+, */
        XC_LEX_INVALID, XC_LEX_OP_MULTIPLY, XC_LEX_OP_PLUS, XC_LEX_INVALID,
        /* -./ */
@@ -627,19 +642,19 @@ dc_char_to_LEX[] = {
        XC_LEX_INVALID, XC_LEX_INVALID, XC_LEX_INVALID, XC_LEX_INVALID,
        XC_LEX_INVALID, XC_LEX_INVALID,
        /* :;<=>?@ */
-       DC_LEX_COLON, BC_LEX_SCOLON, XC_LEX_OP_REL_GT, XC_LEX_OP_REL_EQ,
-       XC_LEX_OP_REL_LT, BC_LEX_KEY_READ, XC_LEX_INVALID,
+       DC_LEX_COLON, DC_LEX_SCOLON, XC_LEX_OP_REL_GT, XC_LEX_OP_REL_EQ,
+       XC_LEX_OP_REL_LT, DC_LEX_READ, XC_LEX_INVALID,
        /* ABCDEFGH */
        XC_LEX_INVALID, XC_LEX_INVALID, XC_LEX_INVALID, XC_LEX_INVALID,
        XC_LEX_INVALID, XC_LEX_INVALID, DC_LEX_EQ_NO_REG, XC_LEX_INVALID,
        /* IJKLMNOP */
-       BC_LEX_KEY_IBASE, XC_LEX_INVALID, BC_LEX_KEY_SCALE, DC_LEX_LOAD_POP,
-       XC_LEX_INVALID, BC_LEX_OP_BOOL_NOT, BC_LEX_KEY_OBASE, DC_LEX_PRINT_STREAM,
+       DC_LEX_IBASE, XC_LEX_INVALID, DC_LEX_SCALE, DC_LEX_LOAD_POP,
+       XC_LEX_INVALID, DC_LEX_OP_BOOL_NOT, DC_LEX_OBASE, DC_LEX_PRINT_STREAM,
        /* QRSTUVWXY */
        DC_LEX_NQUIT, DC_LEX_POP, DC_LEX_STORE_PUSH, XC_LEX_INVALID, XC_LEX_INVALID,
        XC_LEX_INVALID, XC_LEX_INVALID, DC_LEX_SCALE_FACTOR, XC_LEX_INVALID,
        /* Z[\] */
-       BC_LEX_KEY_LENGTH, XC_LEX_INVALID, XC_LEX_INVALID, XC_LEX_INVALID,
+       DC_LEX_LENGTH, XC_LEX_INVALID, XC_LEX_INVALID, XC_LEX_INVALID,
        /* ^_` */
        XC_LEX_OP_POWER, XC_LEX_NEG, XC_LEX_INVALID,
        /* abcdefgh */
@@ -647,43 +662,48 @@ dc_char_to_LEX[] = {
        DC_LEX_ELSE, DC_LEX_PRINT_STACK, XC_LEX_INVALID, XC_LEX_INVALID,
        /* ijklmnop */
        DC_LEX_STORE_IBASE, XC_LEX_INVALID, DC_LEX_STORE_SCALE, DC_LEX_LOAD,
-       XC_LEX_INVALID, DC_LEX_PRINT_POP, DC_LEX_STORE_OBASE, BC_LEX_KEY_PRINT,
+       XC_LEX_INVALID, DC_LEX_PRINT_POP, DC_LEX_STORE_OBASE, DC_LEX_PRINT,
        /* qrstuvwx */
-       BC_LEX_KEY_QUIT, DC_LEX_SWAP, BC_LEX_OP_ASSIGN, XC_LEX_INVALID,
-       XC_LEX_INVALID, BC_LEX_KEY_SQRT, XC_LEX_INVALID, DC_LEX_EXECUTE,
+       DC_LEX_QUIT, DC_LEX_SWAP, DC_LEX_OP_ASSIGN, XC_LEX_INVALID,
+       XC_LEX_INVALID, DC_LEX_SQRT, XC_LEX_INVALID, DC_LEX_EXECUTE,
        /* yz */
        XC_LEX_INVALID, DC_LEX_STACK_LEVEL,
        /* {|}~ */
-       BC_LEX_LBRACE, DC_LEX_OP_MODEXP, XC_LEX_INVALID, DC_LEX_OP_DIVMOD,
+       DC_LEX_LBRACE, DC_LEX_OP_MODEXP, XC_LEX_INVALID, DC_LEX_OP_DIVMOD,
 };
 static const //BcInst - should be this type. Using signed narrow type since DC_INST_INVALID is -1
 int8_t
-dc_LEX_to_INST[] = { // (so many INVALIDs b/c dc parser does not generate these LEXs) // corresponding BC_LEX_xyz:
+dc_LEX_to_INST[] = { // (so many INVALIDs b/c dc parser does not generate these LEXs) // corresponding XC/DC_LEX_xyz:
        DC_INST_INVALID, DC_INST_INVALID,                                    // EOF          INVALID
+       DC_INST_INVALID, DC_INST_INVALID,                                    // NLINE        WHITESPACE
+       DC_INST_INVALID, DC_INST_INVALID,  DC_INST_INVALID,                  // STR          NAME         NUMBER
        DC_INST_INVALID,                                                     // NEG
-       XC_INST_POWER, XC_INST_MULTIPLY, XC_INST_DIVIDE,                     // OP_POWER     OP_MULTIPLY  OP_DIVIDE
-       XC_INST_MODULUS, XC_INST_PLUS, XC_INST_MINUS,                        // OP_MODULUS   OP_PLUS      OP_MINUS
-       DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID,  // OP_REL_EQ    OP_REL_LE    OP_REL_GE    OP_REL_NE
+       XC_INST_POWER,   XC_INST_MULTIPLY, XC_INST_DIVIDE,                   // OP_POWER     OP_MULTIPLY  OP_DIVIDE
+       XC_INST_MODULUS, XC_INST_PLUS,     XC_INST_MINUS,                    // OP_MODULUS   OP_PLUS      OP_MINUS
+       DC_INST_INVALID, DC_INST_INVALID,  DC_INST_INVALID, DC_INST_INVALID, // OP_REL_EQ    OP_REL_LE    OP_REL_GE    OP_REL_NE
        DC_INST_INVALID, DC_INST_INVALID,                                    // OP_REL_LT    OP_REL_GT
-       XC_INST_BOOL_NOT, DC_INST_INVALID, DC_INST_INVALID,                  // OP_BOOL_NOT  OP_BOOL_OR   OP_BOOL_AND
-       DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID,  // OP_ASSIGN_POWER OP_ASSIGN_MULTIPLY OP_ASSIGN_DIVIDE OP_ASSIGN_MODULUS
-       DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID,                   // OP_ASSIGN_PLUS OP_ASSIGN_MINUS         OP_ASSIGN
-       DC_INST_INVALID, XC_INST_REL_GE,                                     // OP_INC       OP_DEC
-       DC_INST_INVALID, DC_INST_INVALID, XC_INST_REL_GT, DC_INST_INVALID,   // NLINE        WHITESPACE   LPAREN       RPAREN
-       DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, XC_INST_REL_GE,   // LBRACKET     COMMA        RBRACKET     LBRACE
-       DC_INST_INVALID, DC_INST_INVALID,                                    // SCOLON       RBRACE
-       DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID,                   // STR          NAME         NUMBER
-       DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID,  // KEY_AUTO     KEY_BREAK    KEY_CONTINUE KEY_DEFINE
-       DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, XC_INST_IBASE,    // KEY_ELSE     KEY_FOR      KEY_HALT     KEY_IBASE
-       XC_INST_OBASE, DC_INST_INVALID, IF_BC(DC_INST_INVALID,) XC_INST_LENGTH,//KEY_OBASE   KEY_IF       KEY_LAST(bc) KEY_LENGTH
-       DC_INST_INVALID, XC_INST_PRINT, DC_INST_QUIT, DC_INST_INVALID,       // KEY_LIMITS   KEY_PRINT    KEY_QUIT     KEY_READ
-       DC_INST_INVALID, XC_INST_SCALE, XC_INST_SQRT, DC_INST_INVALID,       // KEY_RETURN   KEY_SCALE    KEY_SQRT     KEY_WHILE
+       XC_INST_BOOL_NOT, // DC_LEX_OP_BOOL_NOT
+       DC_INST_INVALID,  // DC_LEX_OP_ASSIGN
+       XC_INST_REL_GT,   // DC_LEX_LPAREN
+       DC_INST_INVALID,  // DC_LEX_SCOLON
+       DC_INST_INVALID,  // DC_LEX_READ
+       XC_INST_IBASE,    // DC_LEX_IBASE
+       XC_INST_SCALE,    // DC_LEX_SCALE
+       XC_INST_OBASE,    // DC_LEX_OBASE
+       XC_INST_LENGTH,   // DC_LEX_LENGTH
+       XC_INST_PRINT,    // DC_LEX_PRINT
+       DC_INST_QUIT,     // DC_LEX_QUIT
+       XC_INST_SQRT,     // DC_LEX_SQRT
+       XC_INST_REL_GE,   // DC_LEX_LBRACE
        XC_INST_REL_EQ, DC_INST_MODEXP, DC_INST_DIVMOD, DC_INST_INVALID,     // EQ_NO_REG    OP_MODEXP    OP_DIVMOD    COLON
        DC_INST_INVALID, DC_INST_EXECUTE, DC_INST_PRINT_STACK, DC_INST_CLEAR_STACK, //ELSE   EXECUTE      PRINT_STACK  CLEAR_STACK
        DC_INST_STACK_LEN, DC_INST_DUPLICATE, DC_INST_SWAP, XC_INST_POP,     // STACK_LEVEL  DUPLICATE    SWAP         POP
        DC_INST_ASCIIFY, DC_INST_PRINT_STREAM, DC_INST_INVALID, DC_INST_INVALID, //ASCIIFY   PRINT_STREAM STORE_IBASE  STORE_OBASE
        DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID,  // STORE_SCALE  LOAD         LOAD_POP     STORE_PUSH
        XC_INST_PRINT, DC_INST_NQUIT, XC_INST_SCALE_FUNC,                    // PRINT_POP    NQUIT        SCALE_FACTOR
+       // DC_INST_INVALID in this table either means that corresponding LEX
+       // is not possible for dc, or that it does not compile one-to-one
+       // to a single INST.
 };
 #endif // ENABLE_DC
 
@@ -3397,8 +3417,8 @@ static BC_STATUS zdc_lex_token(BcLex *l)
        uint8_t
        dc_lex_regs[] = {
                XC_LEX_OP_REL_EQ, XC_LEX_OP_REL_LE, XC_LEX_OP_REL_GE, XC_LEX_OP_REL_NE,
-               XC_LEX_OP_REL_LT, XC_LEX_OP_REL_GT, BC_LEX_SCOLON, DC_LEX_COLON,
-               DC_LEX_ELSE, DC_LEX_LOAD, DC_LEX_LOAD_POP, BC_LEX_OP_ASSIGN,
+               XC_LEX_OP_REL_LT, XC_LEX_OP_REL_GT, DC_LEX_SCOLON, DC_LEX_COLON,
+               DC_LEX_ELSE, DC_LEX_LOAD, DC_LEX_LOAD_POP, DC_LEX_OP_ASSIGN,
                DC_LEX_STORE_PUSH,
        };
 
@@ -4923,7 +4943,7 @@ static BC_STATUS zdc_parse_token(BcParse *p, BcLexType t)
                        s = zdc_parse_cond(p, t - XC_LEX_OP_REL_EQ + XC_INST_REL_EQ);
                        get_token = false;
                        break;
-               case BC_LEX_SCOLON:
+               case DC_LEX_SCOLON:
                case DC_LEX_COLON:
                        dbg_lex("%s:%d LEX_[S]COLON", __func__, __LINE__);
                        s = zdc_parse_mem(p, XC_INST_ARRAY_ELEM, true, t == DC_LEX_COLON);
@@ -4945,14 +4965,14 @@ static BC_STATUS zdc_parse_token(BcParse *p, BcLexType t)
                        dbg_lex("%s:%d LEX_NUMBER", __func__, __LINE__);
                        bc_parse_pushNUM(p);
                        break;
-               case BC_LEX_KEY_READ:
+               case DC_LEX_READ:
                        dbg_lex("%s:%d LEX_KEY_READ", __func__, __LINE__);
                        bc_parse_push(p, XC_INST_READ);
                        break;
-               case BC_LEX_OP_ASSIGN:
+               case DC_LEX_OP_ASSIGN:
                case DC_LEX_STORE_PUSH:
                        dbg_lex("%s:%d LEX_OP_ASSIGN/STORE_PUSH", __func__, __LINE__);
-                       assign = t == BC_LEX_OP_ASSIGN;
+                       assign = (t == DC_LEX_OP_ASSIGN);
                        inst = assign ? XC_INST_VAR : DC_INST_PUSH_TO_VAR;
                        s = zdc_parse_mem(p, inst, true, assign);
                        break;