home *** CD-ROM | disk | FTP | other *** search
/ APDL Public Domain 1 / APDL_PD1A.iso / program / assembler / as / src / c / decode < prev    next >
Encoding:
Text File  |  1993-02-03  |  14.7 KB  |  380 lines

  1.  
  2. /*
  3.  * decode.c
  4.  * Copyright © 1992 Niklas Röjemo
  5.  */
  6.  
  7. #include <ctype.h>
  8. #include "decode.h"
  9. #include "input.h"
  10. #include "commands.h"
  11. #include "mnemonics.h"
  12. #include "storage.h"
  13. #include "option.h"
  14. #include "error.h"
  15. #include "filestack.h"
  16.  
  17. extern FILE *asmfile;   /* in input.c */
  18.  
  19.  
  20. BOOL notinput(char *str)
  21. {
  22.   int c;
  23.   for(;*str;) {
  24.      c = inputGet();
  25.     if(isupper(c))
  26.       c = tolower(c);
  27.     if(*str++ != c)
  28.       return TRUE;
  29.   }
  30.   return FALSE;
  31. }
  32.  
  33. int returnvalue = 0;
  34.  
  35. extern int verbose;
  36.  
  37. void c_end(void)
  38. {
  39.   FILE *fp;
  40.  
  41.   fp = pop_file();
  42.   if (!fp)
  43.     returnvalue = 1;
  44.   else {
  45.     fclose(asmfile);
  46.     asmfile = fp;
  47.     if(verbose)
  48.       printf("Returning from include file\n");
  49.   }
  50. }
  51.  
  52. #define C_FINISH_STR(string,fun)                \
  53.         if(notinput(string)                     \
  54.            || !isspace(inputGet()))             \
  55.           goto illegal;                         \
  56.         skipblanks();                           \
  57.         fun();                                  \
  58.         break;
  59.  
  60. #define C_FINISH_CHR(chr,fun)                   \
  61.         c=inputGet();                           \
  62.         if(isupper(c))                          \
  63.           c = tolower(c);                       \
  64.         if(c != chr || !isspace(inputGet()))    \
  65.           goto illegal;                         \
  66.         skipblanks();                           \
  67.         fun();                                  \
  68.         break;
  69.  
  70. #define C_FINISH(fun)                           \
  71.         if(!isspace(inputGet()))                \
  72.           goto illegal;                         \
  73.         skipblanks();                           \
  74.         fun();                                  \
  75.         break;
  76.  
  77. #define C_FINISH_SYMBOL(fun)                    \
  78.         if(!isspace(inputGet()))                \
  79.           goto illegal;                         \
  80.         skipblanks();                           \
  81.         fun(symbol);                            \
  82.         break;
  83.  
  84. #define C_FINISH_CHR_SYMBOL(chr,fun)            \
  85.         c=inputGet();                           \
  86.         if(isupper(c))                          \
  87.           c = tolower(c);                       \
  88.         if(c != chr || !isspace(inputGet()))    \
  89.           goto illegal;                         \
  90.         skipblanks();                           \
  91.         fun(symbol);                            \
  92.         break;
  93.  
  94. #define M_FINISH_STR(string,fun,opt)            \
  95.         if(notinput(string))                    \
  96.           goto illegal;                         \
  97.         if(optionError == (option = opt()))     \
  98.           goto illegal;                         \
  99.         skipblanks();                           \
  100.         fun(option);                            \
  101.         break;
  102.  
  103. #define M_FINISH_CHR(chr,fun,opt)               \
  104.         c=inputGet();                           \
  105.         if(isupper(c))                          \
  106.           c = tolower(c);                       \
  107.         if(c != chr)                            \
  108.           goto illegal;                         \
  109.         if(optionError == (option = opt()))     \
  110.           goto illegal;                         \
  111.         skipblanks();                           \
  112.         fun(option);                            \
  113.         break;
  114.  
  115. #define M_FINISH(fun,opt)                       \
  116.         if(optionError == (option = opt()))     \
  117.           goto illegal;                         \
  118.         skipblanks();                           \
  119.         fun(option);                            \
  120.         break;
  121.  
  122. int decode(Symbol *symbol)
  123. {
  124.   int c;
  125.   WORD option;
  126.   inputMark();
  127.   switch(inputGet()) {
  128.     case '%': C_FINISH(c_reserve);         /* reserve space */
  129.     case '*': C_FINISH_SYMBOL(c_equ);      /* equ */
  130.     case '&': C_FINISH(c_dcd);             /* DCD    32 */
  131.     case '=': C_FINISH(c_dcb);             /* DCB     8 */
  132.     case '^': C_FINISH(c_record);          /* start of new record layout */
  133.     case '#': C_FINISH_SYMBOL(c_alloc);    /* reserve space in the current record */
  134.     case 'a':case 'A':
  135.       switch(inputGet()) {
  136.         case 'b':case 'B': M_FINISH_CHR('s',m_abs,optionCondPrecRound); /* abs CC P R */
  137.         case 'c':case 'C': M_FINISH_CHR('s',m_acs,optionCondPrecRound); /* acs CC P R */
  138.         case 'd':case 'D':
  139.           switch(inputGet()) {
  140.             case 'c':case 'C': M_FINISH(m_adc,optionCondS); /* adc CC s */
  141.             case 'd':case 'D': M_FINISH(m_add,optionCondS); /* add CC s */
  142.             case 'f':case 'F': M_FINISH(m_adf,optionCondPrecRound); /* adf CC P R */
  143.             case 'r':case 'R': M_FINISH(m_adr,optionCond); /* adr CC */
  144.             default:  goto illegal;
  145.           } break;
  146.         case 'n':case 'N': M_FINISH_CHR('d',m_and,optionCondS); /* and CC S */
  147.         case 'l':case 'L': C_FINISH_STR("ign",c_align); /* .align */
  148.         case 'r':case 'R': C_FINISH_STR("ea",c_area); /* AREA */
  149.         case 's':case 'S': M_FINISH_CHR('n',m_asn,optionCondPrecRound); /* asn CC P R */
  150.         case 't':case 'T': M_FINISH_CHR('n',m_atn,optionCondPrecRound); /* atn CC P R */
  151.         default:  goto illegal;
  152.       } break;
  153.     case 'b':case 'B':
  154.       switch(c=inputGet()) {
  155.         case 'i':case 'I': M_FINISH_CHR('c',m_bic,optionCondS); /* bic CC s */
  156.         default:  inputUnGet(c); M_FINISH(m_branch,optionLinkCond); /* bl and b */
  157.       } break;
  158.     case 'c':case 'C':
  159.       switch(inputGet()) {
  160.         case 'd':case 'D': M_FINISH_CHR('p',m_cdp,optionCond); /* cdp CC */
  161.         case 'm':case 'M':
  162.           switch(inputGet()) {
  163.             case 'f':case 'F': M_FINISH(m_cmf,optionExceptionCond); /* cmf CC  or cmfe CC */
  164.             case 'n':case 'N': M_FINISH(m_cmn,optionCondSP); /* cmn CC SP */
  165.             case 'p':case 'P': M_FINISH(m_cmp,optionCondSP); /* cmp CC sp */
  166.             default:  goto illegal;
  167.           } break;
  168.         case 'n':case 'N':
  169.           switch(c=inputGet()) {
  170.             case 'f':case 'F': M_FINISH(m_cnf,optionExceptionCond); /* cnf CC or cnfe CC */
  171.             default: inputUnGet(c); C_FINISH_SYMBOL(c_cn); /* CN */
  172.           } break;
  173.         case 'o':case 'O':
  174.           switch(inputGet()) {
  175.             case 's':case 'S': M_FINISH(m_cos,optionCondPrecRound);       /* cos CC P R */
  176.             default:  goto illegal;
  177.           } break;
  178.         default:  goto illegal;
  179.       } break; 
  180.     case 'd':case 'D':
  181.       switch(inputGet()) {
  182.         case 'v':case 'V': M_FINISH_CHR('f',m_dvf,optionCondPrecRound); /* dvf CC s */
  183.         case 'c':case 'C':
  184.           switch(inputGet()) {
  185.             case 'b':case 'B': C_FINISH(c_dcb); /* DCB    8 */
  186.             case 'd':case 'D': C_FINISH(c_dcd); /* DCD    32 */
  187.             case 'f':case 'F':
  188.               switch(inputGet()) {
  189.                 case 'd':case 'D': C_FINISH(c_dcfd); /* DCFD   64 float */
  190.                 case 'e':case 'E': C_FINISH(c_dcfe); /* DCFE   80 float */
  191.                 case 'p':case 'P': C_FINISH(c_dcfp); /* DCFP   80 packed bcd */
  192.                 case 's':case 'S': C_FINISH(c_dcfs); /* DCFS   32 float */
  193.               } break;
  194.             case 'w':case 'W': C_FINISH(c_dcw); /* DCW    16 */
  195.             default:    goto illegal;
  196.           } break;
  197.         default:  goto illegal;
  198.       } break;
  199.     case 'e':case 'E':
  200.       switch(inputGet()) {
  201.         case 'n':case 'N':
  202.           switch(inputGet()) {
  203.             case 'd':case 'D': C_FINISH(c_end);     /* END */
  204.             case 't':case 'T': C_FINISH_STR("ry",c_entry); /* entry */
  205.             default:  goto illegal;
  206.           } break;
  207.         case 'o':case 'O': M_FINISH_CHR('r',m_eor,optionCondS); /* eor CC s */
  208.         case 'q':case 'Q': C_FINISH_CHR_SYMBOL('u',c_equ); /* equ */
  209.         case 'x':case 'X':
  210.           switch(inputGet()) {
  211.             case 'p':case'P':
  212.               switch(c=inputGet()) {
  213.                 case 'o':case 'O': C_FINISH_STR("rt",c_globl); /* EXPORT */
  214.                 default: inputUnGet(c); M_FINISH(m_exp,optionCondPrecRound); /* exp CC P R */
  215.               } break;
  216.             default:  goto illegal;
  217.           } break;
  218.         default:  goto illegal;
  219.       }
  220.       break;
  221.     case 'f':case 'F':
  222.       switch(inputGet()) {
  223.         case 'd':case 'D': M_FINISH_CHR('v',m_fdv,optionCondPrecRound); /* fdv CC P R */
  224.         case 'i':case 'I': M_FINISH_CHR('x',m_fix,optionCondPrecRound); /* fix CC P R */
  225.         case 'l':case 'L': M_FINISH_CHR('t',m_flt,optionCondPrecRound); /* flt CC P R */
  226.         case 'm':case 'M': M_FINISH_CHR('l',m_fml,optionCondPrecRound); /* fml CC P R */
  227.         case 'n':case 'N': C_FINISH_SYMBOL(c_fn);              /* FN */
  228.         case 'r':case 'R': M_FINISH_CHR('d',m_frd,optionCondPrecRound); /* frd CC P R */
  229.         default:  goto illegal;
  230.       }
  231.       break;
  232.     case 'g':case 'G':
  233.       switch(inputGet()) {
  234.         case 'e':case 'E':  C_FINISH_CHR('t', c_get);
  235.         case 'l':case 'L':  C_FINISH_STR("obl",c_globl);   /* globl  */
  236.         default:  goto illegal;
  237.       }
  238.       break;
  239.     case 'i':case 'I': C_FINISH_STR("mport",c_globl); /* IMPORT */
  240.     case 'l':case 'L':
  241.       switch(inputGet()) {
  242.         case 'd':case 'D':
  243.           switch(inputGet()) {
  244.             case 'c':case 'C': M_FINISH(m_ldc,optionCondL); /* ldc CC l */
  245.             case 'f':case 'F': M_FINISH(m_ldf,optionCondPrec_P); /* ldf CC P */
  246.             case 'm':case 'M': M_FINISH(m_ldm,optionCondDirLdm); /* ldm CC TYPE */
  247.             case 'r':case 'R': M_FINISH(m_ldr,optionCondBT); /* ldr CC BYTE */
  248.             default:  goto illegal;
  249.           }
  250.           break;
  251.         case 'g':case 'G': M_FINISH_CHR('n',m_lgn,optionCondPrecRound); /* lgn CC P R */
  252.         case 'n':case 'N': C_FINISH_CHR('k', c_lnk);               /* lnk */
  253.         case 'o':case 'O': M_FINISH_CHR('g',m_log,optionCondPrecRound); /* log CC P R */
  254.         case 't':case 'T': C_FINISH_STR("org",c_ltorg);                 /* ltorg */
  255.         default:  goto illegal;
  256.       }
  257.       break;
  258.     case 'm':case 'M':
  259.       switch(inputGet()) {
  260.         case 'c':case 'C': M_FINISH_CHR('r',m_mcr,optionCond); /* mcr CC */
  261.         case 'l':case 'L': M_FINISH_CHR('a',m_mla,optionCondS); /* mla CC s */
  262.         case 'n':case 'N': M_FINISH_CHR('f',m_mnf,optionCondPrecRound); /* mnf CC P R */
  263.         case 'o':case 'O': M_FINISH_CHR('v',m_mov,optionCondS); /* mov CC s */
  264.         case 'r':case 'R': M_FINISH_CHR('c',m_mrc,optionCond); /* mrc CC */
  265.         case 'u':case 'U':
  266.           switch(inputGet()) {
  267.             case 'f':case 'F': M_FINISH(m_muf,optionCondPrecRound); /* muf CC P R */
  268.             case 'l':case 'L': M_FINISH(m_mul,optionCondS); /* mul CC s */
  269.           default:  goto illegal;
  270.           }
  271.           break;
  272.         case 'v':case 'V':
  273.           switch(inputGet()) {
  274.             case 'f':case 'F': M_FINISH(m_mvf,optionCondPrecRound); /* mvf CC P R */
  275.             case 'n':case 'N': M_FINISH(m_mvn,optionCondS); /* mvn CC s */
  276.             default:  goto illegal;
  277.           }
  278.           break;
  279.         default:  goto illegal;
  280.       }
  281.       break;
  282.  
  283.     case 'o':case 'O': M_FINISH_STR("rr",m_orr,optionCondS); /* orr CC s */
  284.     case 'p':case 'P':
  285.       switch(inputGet()) {
  286.         case 'o':case 'O':
  287.           switch(inputGet()) {
  288.             case 'l':case 'L': M_FINISH(m_pol,optionCondPrecRound); /* pol CC P R */
  289.             case 'w':case 'W': M_FINISH(m_pow,optionCondPrecRound); /* pow CC P R */
  290.           default:  goto illegal;
  291.           }
  292.           break;
  293.         default:  goto illegal;
  294.       }
  295.       break;
  296.     case 'r':case 'R':
  297.       switch(inputGet()) {
  298.         case 'd':case 'D': M_FINISH_CHR('f',m_rdf,optionCondPrecRound); /* rdf CC P R */
  299.         case 'f':case 'F':
  300.           switch(inputGet()) {
  301.             case 'c':case 'C': M_FINISH(m_rfc,optionCond); /* rfc CC */
  302.             case 's':case 'S': M_FINISH(m_rfs,optionCond); /* rfs CC */
  303.             default:  goto illegal;
  304.           } break;
  305.         case 'm':case 'M': M_FINISH_CHR('f',m_rmf,optionCondPrecRound); /* rmf CC P R */
  306.         case 'n':case 'N':
  307.           switch(c=inputGet()) {
  308.             case 'd':case 'D': M_FINISH(m_rnd,optionCondPrecRound); /* rnd CC P R */
  309.             default: inputUnGet(c); C_FINISH_SYMBOL(c_rn); /* RN */
  310.           } break;
  311.         case 'p':case 'P': M_FINISH_CHR('w',m_rpw,optionCondPrecRound); /* rpw CC P R */
  312.         case 's':case 'S':
  313.           switch(inputGet()) {
  314.             case 'b':case 'B': M_FINISH(m_rsb,optionCondS); /* rsb CC s */
  315.             case 'c':case 'C': M_FINISH(m_rsc,optionCondS); /* rsc CC s */
  316.             case 'f':case 'F': M_FINISH(m_rsf,optionCondPrecRound); /* rsf CC P R */
  317.             default:  goto illegal;
  318.           }
  319.           break;
  320.         default:  goto illegal;
  321.       }
  322.       break;
  323.     case 's':case 'S':
  324.       switch(inputGet()) {
  325.         case 'b':case 'B': M_FINISH_CHR('c',m_sbc,optionCondS); /* sbc CC s */
  326.         case 'i':case 'I': M_FINISH_CHR('n',m_sin,optionCondPrecRound); /* sin CC P R */
  327.         case 'q':case 'Q': M_FINISH_CHR('t',m_sqt,optionCondPrecRound); /* sqt CC P R */
  328.         case 't':case 'T':
  329.           switch(inputGet()) {
  330.             case 'c':case 'C': M_FINISH(m_stc,optionCondL); /* stc CC l */
  331.             case 'f':case 'F': M_FINISH(m_stf,optionCondPrec_P); /* stf CC P */
  332.             case 'm':case 'M': M_FINISH(m_stm,optionCondDirStm); /* stm CC TYPE */
  333.             case 'r':case 'R': M_FINISH(m_str,optionCondBT); /* str CC BYTE */
  334.             default:  goto illegal;
  335.           } break;
  336.         case 'u':case 'U':
  337.           switch(inputGet()) {
  338.             case 'b':case 'B': M_FINISH(m_sub,optionCondS); /* sub CC s */
  339.             case 'f':case 'F': M_FINISH(m_suf,optionCondPrecRound); /* suf CC P R */
  340.             default:  goto illegal;
  341.           } break;
  342.         case 'w':case 'W':
  343.           switch(inputGet()) {
  344.             case 'i':case 'I': M_FINISH(m_swi,optionCond); /* swi CC */
  345.             case 'p':case 'P': M_FINISH(m_swp,optionCondB); /* swp CC BYTE */
  346.             default:  goto illegal;
  347.           } break;
  348.         default:  goto illegal;
  349.       } break;
  350.     case 't':case 'T':
  351.       switch(inputGet()) {
  352.         case 'a':case 'A': M_FINISH_CHR('n',m_tan,optionCondPrecRound); /* tan CC P R */
  353.         case 'e':case 'E': 
  354.           switch(inputGet()) {
  355.             case 'q':case 'Q': M_FINISH(m_teq,optionCondSP);                /* teq CC sp */
  356.             default:  goto illegal;
  357.           } break;
  358.         case 's':case 'S': M_FINISH_CHR('t',m_tst,optionCondSP); /* tst CC sp */
  359.         default:  goto illegal;
  360.       } break;
  361.     case 'w':case 'W':
  362.       switch(inputGet()) {
  363.         case 'f':case 'F':
  364.           switch(inputGet()) {
  365.             case 'c':case 'C': M_FINISH(m_wfc,optionCond); /* wfc CC */
  366.             case 's':case 'S': M_FINISH(m_wfs,optionCond); /* wfs CC */
  367.             default:  goto illegal;
  368.           } break;
  369.         default:  goto illegal;
  370.       } break;
  371.     default:
  372. illegal:
  373.       inputRollback();
  374.       error(ErrorError,FALSE,"Illegal line \"%s\".",inputRest());
  375.   }
  376.   skipblanks();
  377.   if(inputLook() && inputLook()!= ';') { error(ErrorError,FALSE,"Skipping extra characters '%s'.",inputRest()); }
  378.   return returnvalue;
  379. }
  380.