DavidsonDFGL

maybev2.c

Aug 23rd, 2020 (edited)
836
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.51 KB | None | 0 0
  1. /* Match flags. */
  2. #define M_NI  0 /* Unconditionally not increment.     */
  3. #define M_I   1 /* Unconditionally increment.         */
  4. #define M_IC  2 /* Increment conditionally (if true.) */
  5. #define M_NS  1 /* Not suppress error msgs.           */
  6. #define M_S   0 /* Suppress error messages.           */
  7.  
  8. /**
  9.  *
  10.  */
  11. static inline void skip_whitespace(char **s)
  12. {
  13.     char *p = *s;
  14.     while (isblank(*p))
  15.         p++;
  16.     *s = p;
  17. }
  18.  
  19. /**
  20.  *
  21.  */
  22. static inline int match(char **s, char c, int inc, int supr)
  23. {
  24.     int ret = 0;
  25.     char *p = *s;
  26.  
  27.     if (tolower(*p) == c)
  28.         ret = 1;
  29.     else
  30.     {
  31.         if (supr)
  32.             fprintf(stderr, "file.c:%d: Error: expected '%c', found '%c'\n",
  33.                 current_line, c, *p);
  34.     }
  35.     /* Increment. */
  36.     if (inc == M_I)
  37.         *s = p + 1;
  38.     else if (inc == M_IC && ret)
  39.         *s = p + 1;
  40.     return (ret);
  41. }
  42.  
  43. /**
  44.  *
  45.  */
  46. static inline int match_lt(char **s, char c, int inc, int supr)
  47. {
  48.     int ret = 0;
  49.     char *p = *s;
  50.  
  51.     if (*p < c)
  52.         ret = 1;
  53.     else
  54.     {
  55.         if (supr)
  56.             fprintf(stderr, "file.c:%d: Error: expected '%c' < '%c'\n",
  57.                 current_line, c, *p);
  58.     }
  59.     if (inc == M_I)
  60.         *s = p + 1;
  61.     else if (inc == M_IC && ret)
  62.         *s = p + 1;
  63.     return (ret);
  64. }
  65.  
  66. /**
  67.  *
  68.  */
  69. static inline int match_gt(char **s, char c, int inc, int supr)
  70. {
  71.     int ret = 0;
  72.     char *p = *s;
  73.  
  74.     if (*p > c)
  75.         ret = 1;
  76.     else
  77.     {
  78.         if (supr)
  79.             fprintf(stderr, "file.c:%d: Error: expected '%c' > '%c'\n",
  80.                 current_line, c, *p);
  81.     }
  82.     if (inc == M_I)
  83.         *s = p + 1;
  84.     else if (inc == M_IC && ret)
  85.         *s = p + 1;
  86.     return (ret);
  87. }
  88.  
  89. /**
  90.  *
  91.  */
  92. static inline long read_number(char **s)
  93. {
  94.     long number;
  95.     char *nptr = NULL;
  96.     char *p = *s;
  97.  
  98.     number = strtol(p, &nptr, 0);
  99.     if (p != nptr && errno == 0)
  100.     {
  101.         *s = nptr;
  102.         return (number);
  103.     }
  104.     fprintf(stderr, "file.c:%d: Error: invalid number\n",
  105.         current_line);
  106.  
  107.     return (LONG_MAX);
  108. }
  109.  
  110. /**
  111.  *
  112.  */
  113. static int read_first_operand(char **insn, struct insn_tbl *tbl)
  114. {
  115.     if (!match(insn, 'r', M_I, M_NS))
  116.         goto err;
  117.  
  118.     if (match_lt(insn, '0', M_NI, M_S) ||
  119.         match_gt(insn, '7', M_I,  M_S))
  120.     {
  121.         goto err;
  122.     }
  123.     return (1);
  124. err:
  125.     fprintf(stderr, "file.c:%d: Error: first operand of instruction"
  126.         " '%s' is invalid!\n", current_line, tbl->name);
  127.     return (0);
  128. }
  129.  
  130. /**
  131.  *
  132.  */
  133. static int read_second_operand(char **insn, struct insn_tbl *tbl)
  134. {
  135.     long imm;
  136.  
  137.     if (!match(insn, ',', M_I, M_NS))
  138.         goto err;
  139.  
  140.     skip_whitespace(insn);
  141.  
  142.     /* If Reg/Reg. */
  143.     if (match(insn, 'r', M_IC, M_S))
  144.     {
  145.         if (match_lt(insn, '0', M_NI, M_S) || match_gt(insn, '7', M_I, M_S))
  146.             goto err;
  147.  
  148.         skip_whitespace(insn);
  149.  
  150.         if (!match(insn, '#',  M_NI, M_S) && !match(insn, ';',  M_IC,  M_S) &&
  151.             !match(insn, '\n', M_NI, M_S) && !match(insn, '\0', M_NI, M_S))
  152.         {
  153.             goto err;
  154.         }
  155.     }
  156.  
  157.     /* Reg/Imm. */
  158.     else
  159.     {
  160.         imm = read_number(insn);
  161.         if (imm == LONG_MAX)
  162.             goto err;
  163.  
  164.         skip_whitespace(insn);
  165.  
  166.         if (!match(insn, '#',  M_NI, M_S) && !match(insn, ';',  M_IC,  M_S) &&
  167.             !match(insn, '\n', M_NI, M_S) && !match(insn, '\0', M_NI, M_S))
  168.         {
  169.             goto err;
  170.         }
  171.  
  172.         printf("num: %ld\n", imm);
  173.     }
  174.  
  175.     return (1);
  176. err:
  177.     fprintf(stderr, "file.c:%d: Error: second operand of instruction"
  178.         " '%s' is invalid!\n", current_line, tbl->name);
  179.     return (0);
  180. }
  181.  
  182. /**
  183.  *
  184.  */
  185. static int insn_two_params(char **insn, struct insn_tbl *tbl)
  186. {
  187.     long number;
  188.     char *nptr = NULL;
  189.     char *p = *insn;
  190.  
  191.     if (!read_first_operand(&p, tbl))
  192.         return (-1);
  193.  
  194.     skip_whitespace(&p);
  195.  
  196.     if (!read_second_operand(&p, tbl))
  197.         return (-1);
  198.  
  199.     /* Update the pointer. */
  200.     *insn = p;
  201.     return (0);
  202. }
Add Comment
Please, Sign In to add comment