home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * decode.c
- * Copyright © 1992 Niklas Röjemo
- */
-
- #include <ctype.h>
- #include "decode.h"
- #include "input.h"
- #include "commands.h"
- #include "mnemonics.h"
- #include "storage.h"
- #include "option.h"
- #include "error.h"
- #include "filestack.h"
-
- extern FILE *asmfile; /* in input.c */
-
-
- BOOL notinput(char *str)
- {
- int c;
- for(;*str;) {
- c = inputGet();
- if(isupper(c))
- c = tolower(c);
- if(*str++ != c)
- return TRUE;
- }
- return FALSE;
- }
-
- int returnvalue = 0;
-
- extern int verbose;
-
- void c_end(void)
- {
- FILE *fp;
-
- fp = pop_file();
- if (!fp)
- returnvalue = 1;
- else {
- fclose(asmfile);
- asmfile = fp;
- if(verbose)
- printf("Returning from include file\n");
- }
- }
-
- #define C_FINISH_STR(string,fun) \
- if(notinput(string) \
- || !isspace(inputGet())) \
- goto illegal; \
- skipblanks(); \
- fun(); \
- break;
-
- #define C_FINISH_CHR(chr,fun) \
- c=inputGet(); \
- if(isupper(c)) \
- c = tolower(c); \
- if(c != chr || !isspace(inputGet())) \
- goto illegal; \
- skipblanks(); \
- fun(); \
- break;
-
- #define C_FINISH(fun) \
- if(!isspace(inputGet())) \
- goto illegal; \
- skipblanks(); \
- fun(); \
- break;
-
- #define C_FINISH_SYMBOL(fun) \
- if(!isspace(inputGet())) \
- goto illegal; \
- skipblanks(); \
- fun(symbol); \
- break;
-
- #define C_FINISH_CHR_SYMBOL(chr,fun) \
- c=inputGet(); \
- if(isupper(c)) \
- c = tolower(c); \
- if(c != chr || !isspace(inputGet())) \
- goto illegal; \
- skipblanks(); \
- fun(symbol); \
- break;
-
- #define M_FINISH_STR(string,fun,opt) \
- if(notinput(string)) \
- goto illegal; \
- if(optionError == (option = opt())) \
- goto illegal; \
- skipblanks(); \
- fun(option); \
- break;
-
- #define M_FINISH_CHR(chr,fun,opt) \
- c=inputGet(); \
- if(isupper(c)) \
- c = tolower(c); \
- if(c != chr) \
- goto illegal; \
- if(optionError == (option = opt())) \
- goto illegal; \
- skipblanks(); \
- fun(option); \
- break;
-
- #define M_FINISH(fun,opt) \
- if(optionError == (option = opt())) \
- goto illegal; \
- skipblanks(); \
- fun(option); \
- break;
-
- int decode(Symbol *symbol)
- {
- int c;
- WORD option;
- inputMark();
- switch(inputGet()) {
- case '%': C_FINISH(c_reserve); /* reserve space */
- case '*': C_FINISH_SYMBOL(c_equ); /* equ */
- case '&': C_FINISH(c_dcd); /* DCD 32 */
- case '=': C_FINISH(c_dcb); /* DCB 8 */
- case '^': C_FINISH(c_record); /* start of new record layout */
- case '#': C_FINISH_SYMBOL(c_alloc); /* reserve space in the current record */
- case 'a':case 'A':
- switch(inputGet()) {
- case 'b':case 'B': M_FINISH_CHR('s',m_abs,optionCondPrecRound); /* abs CC P R */
- case 'c':case 'C': M_FINISH_CHR('s',m_acs,optionCondPrecRound); /* acs CC P R */
- case 'd':case 'D':
- switch(inputGet()) {
- case 'c':case 'C': M_FINISH(m_adc,optionCondS); /* adc CC s */
- case 'd':case 'D': M_FINISH(m_add,optionCondS); /* add CC s */
- case 'f':case 'F': M_FINISH(m_adf,optionCondPrecRound); /* adf CC P R */
- case 'r':case 'R': M_FINISH(m_adr,optionCond); /* adr CC */
- default: goto illegal;
- } break;
- case 'n':case 'N': M_FINISH_CHR('d',m_and,optionCondS); /* and CC S */
- case 'l':case 'L': C_FINISH_STR("ign",c_align); /* .align */
- case 'r':case 'R': C_FINISH_STR("ea",c_area); /* AREA */
- case 's':case 'S': M_FINISH_CHR('n',m_asn,optionCondPrecRound); /* asn CC P R */
- case 't':case 'T': M_FINISH_CHR('n',m_atn,optionCondPrecRound); /* atn CC P R */
- default: goto illegal;
- } break;
- case 'b':case 'B':
- switch(c=inputGet()) {
- case 'i':case 'I': M_FINISH_CHR('c',m_bic,optionCondS); /* bic CC s */
- default: inputUnGet(c); M_FINISH(m_branch,optionLinkCond); /* bl and b */
- } break;
- case 'c':case 'C':
- switch(inputGet()) {
- case 'd':case 'D': M_FINISH_CHR('p',m_cdp,optionCond); /* cdp CC */
- case 'm':case 'M':
- switch(inputGet()) {
- case 'f':case 'F': M_FINISH(m_cmf,optionExceptionCond); /* cmf CC or cmfe CC */
- case 'n':case 'N': M_FINISH(m_cmn,optionCondSP); /* cmn CC SP */
- case 'p':case 'P': M_FINISH(m_cmp,optionCondSP); /* cmp CC sp */
- default: goto illegal;
- } break;
- case 'n':case 'N':
- switch(c=inputGet()) {
- case 'f':case 'F': M_FINISH(m_cnf,optionExceptionCond); /* cnf CC or cnfe CC */
- default: inputUnGet(c); C_FINISH_SYMBOL(c_cn); /* CN */
- } break;
- case 'o':case 'O':
- switch(inputGet()) {
- case 's':case 'S': M_FINISH(m_cos,optionCondPrecRound); /* cos CC P R */
- default: goto illegal;
- } break;
- default: goto illegal;
- } break;
- case 'd':case 'D':
- switch(inputGet()) {
- case 'v':case 'V': M_FINISH_CHR('f',m_dvf,optionCondPrecRound); /* dvf CC s */
- case 'c':case 'C':
- switch(inputGet()) {
- case 'b':case 'B': C_FINISH(c_dcb); /* DCB 8 */
- case 'd':case 'D': C_FINISH(c_dcd); /* DCD 32 */
- case 'f':case 'F':
- switch(inputGet()) {
- case 'd':case 'D': C_FINISH(c_dcfd); /* DCFD 64 float */
- case 'e':case 'E': C_FINISH(c_dcfe); /* DCFE 80 float */
- case 'p':case 'P': C_FINISH(c_dcfp); /* DCFP 80 packed bcd */
- case 's':case 'S': C_FINISH(c_dcfs); /* DCFS 32 float */
- } break;
- case 'w':case 'W': C_FINISH(c_dcw); /* DCW 16 */
- default: goto illegal;
- } break;
- default: goto illegal;
- } break;
- case 'e':case 'E':
- switch(inputGet()) {
- case 'n':case 'N':
- switch(inputGet()) {
- case 'd':case 'D': C_FINISH(c_end); /* END */
- case 't':case 'T': C_FINISH_STR("ry",c_entry); /* entry */
- default: goto illegal;
- } break;
- case 'o':case 'O': M_FINISH_CHR('r',m_eor,optionCondS); /* eor CC s */
- case 'q':case 'Q': C_FINISH_CHR_SYMBOL('u',c_equ); /* equ */
- case 'x':case 'X':
- switch(inputGet()) {
- case 'p':case'P':
- switch(c=inputGet()) {
- case 'o':case 'O': C_FINISH_STR("rt",c_globl); /* EXPORT */
- default: inputUnGet(c); M_FINISH(m_exp,optionCondPrecRound); /* exp CC P R */
- } break;
- default: goto illegal;
- } break;
- default: goto illegal;
- }
- break;
- case 'f':case 'F':
- switch(inputGet()) {
- case 'd':case 'D': M_FINISH_CHR('v',m_fdv,optionCondPrecRound); /* fdv CC P R */
- case 'i':case 'I': M_FINISH_CHR('x',m_fix,optionCondPrecRound); /* fix CC P R */
- case 'l':case 'L': M_FINISH_CHR('t',m_flt,optionCondPrecRound); /* flt CC P R */
- case 'm':case 'M': M_FINISH_CHR('l',m_fml,optionCondPrecRound); /* fml CC P R */
- case 'n':case 'N': C_FINISH_SYMBOL(c_fn); /* FN */
- case 'r':case 'R': M_FINISH_CHR('d',m_frd,optionCondPrecRound); /* frd CC P R */
- default: goto illegal;
- }
- break;
- case 'g':case 'G':
- switch(inputGet()) {
- case 'e':case 'E': C_FINISH_CHR('t', c_get);
- case 'l':case 'L': C_FINISH_STR("obl",c_globl); /* globl */
- default: goto illegal;
- }
- break;
- case 'i':case 'I': C_FINISH_STR("mport",c_globl); /* IMPORT */
- case 'l':case 'L':
- switch(inputGet()) {
- case 'd':case 'D':
- switch(inputGet()) {
- case 'c':case 'C': M_FINISH(m_ldc,optionCondL); /* ldc CC l */
- case 'f':case 'F': M_FINISH(m_ldf,optionCondPrec_P); /* ldf CC P */
- case 'm':case 'M': M_FINISH(m_ldm,optionCondDirLdm); /* ldm CC TYPE */
- case 'r':case 'R': M_FINISH(m_ldr,optionCondBT); /* ldr CC BYTE */
- default: goto illegal;
- }
- break;
- case 'g':case 'G': M_FINISH_CHR('n',m_lgn,optionCondPrecRound); /* lgn CC P R */
- case 'n':case 'N': C_FINISH_CHR('k', c_lnk); /* lnk */
- case 'o':case 'O': M_FINISH_CHR('g',m_log,optionCondPrecRound); /* log CC P R */
- case 't':case 'T': C_FINISH_STR("org",c_ltorg); /* ltorg */
- default: goto illegal;
- }
- break;
- case 'm':case 'M':
- switch(inputGet()) {
- case 'c':case 'C': M_FINISH_CHR('r',m_mcr,optionCond); /* mcr CC */
- case 'l':case 'L': M_FINISH_CHR('a',m_mla,optionCondS); /* mla CC s */
- case 'n':case 'N': M_FINISH_CHR('f',m_mnf,optionCondPrecRound); /* mnf CC P R */
- case 'o':case 'O': M_FINISH_CHR('v',m_mov,optionCondS); /* mov CC s */
- case 'r':case 'R': M_FINISH_CHR('c',m_mrc,optionCond); /* mrc CC */
- case 'u':case 'U':
- switch(inputGet()) {
- case 'f':case 'F': M_FINISH(m_muf,optionCondPrecRound); /* muf CC P R */
- case 'l':case 'L': M_FINISH(m_mul,optionCondS); /* mul CC s */
- default: goto illegal;
- }
- break;
- case 'v':case 'V':
- switch(inputGet()) {
- case 'f':case 'F': M_FINISH(m_mvf,optionCondPrecRound); /* mvf CC P R */
- case 'n':case 'N': M_FINISH(m_mvn,optionCondS); /* mvn CC s */
- default: goto illegal;
- }
- break;
- default: goto illegal;
- }
- break;
-
- case 'o':case 'O': M_FINISH_STR("rr",m_orr,optionCondS); /* orr CC s */
- case 'p':case 'P':
- switch(inputGet()) {
- case 'o':case 'O':
- switch(inputGet()) {
- case 'l':case 'L': M_FINISH(m_pol,optionCondPrecRound); /* pol CC P R */
- case 'w':case 'W': M_FINISH(m_pow,optionCondPrecRound); /* pow CC P R */
- default: goto illegal;
- }
- break;
- default: goto illegal;
- }
- break;
- case 'r':case 'R':
- switch(inputGet()) {
- case 'd':case 'D': M_FINISH_CHR('f',m_rdf,optionCondPrecRound); /* rdf CC P R */
- case 'f':case 'F':
- switch(inputGet()) {
- case 'c':case 'C': M_FINISH(m_rfc,optionCond); /* rfc CC */
- case 's':case 'S': M_FINISH(m_rfs,optionCond); /* rfs CC */
- default: goto illegal;
- } break;
- case 'm':case 'M': M_FINISH_CHR('f',m_rmf,optionCondPrecRound); /* rmf CC P R */
- case 'n':case 'N':
- switch(c=inputGet()) {
- case 'd':case 'D': M_FINISH(m_rnd,optionCondPrecRound); /* rnd CC P R */
- default: inputUnGet(c); C_FINISH_SYMBOL(c_rn); /* RN */
- } break;
- case 'p':case 'P': M_FINISH_CHR('w',m_rpw,optionCondPrecRound); /* rpw CC P R */
- case 's':case 'S':
- switch(inputGet()) {
- case 'b':case 'B': M_FINISH(m_rsb,optionCondS); /* rsb CC s */
- case 'c':case 'C': M_FINISH(m_rsc,optionCondS); /* rsc CC s */
- case 'f':case 'F': M_FINISH(m_rsf,optionCondPrecRound); /* rsf CC P R */
- default: goto illegal;
- }
- break;
- default: goto illegal;
- }
- break;
- case 's':case 'S':
- switch(inputGet()) {
- case 'b':case 'B': M_FINISH_CHR('c',m_sbc,optionCondS); /* sbc CC s */
- case 'i':case 'I': M_FINISH_CHR('n',m_sin,optionCondPrecRound); /* sin CC P R */
- case 'q':case 'Q': M_FINISH_CHR('t',m_sqt,optionCondPrecRound); /* sqt CC P R */
- case 't':case 'T':
- switch(inputGet()) {
- case 'c':case 'C': M_FINISH(m_stc,optionCondL); /* stc CC l */
- case 'f':case 'F': M_FINISH(m_stf,optionCondPrec_P); /* stf CC P */
- case 'm':case 'M': M_FINISH(m_stm,optionCondDirStm); /* stm CC TYPE */
- case 'r':case 'R': M_FINISH(m_str,optionCondBT); /* str CC BYTE */
- default: goto illegal;
- } break;
- case 'u':case 'U':
- switch(inputGet()) {
- case 'b':case 'B': M_FINISH(m_sub,optionCondS); /* sub CC s */
- case 'f':case 'F': M_FINISH(m_suf,optionCondPrecRound); /* suf CC P R */
- default: goto illegal;
- } break;
- case 'w':case 'W':
- switch(inputGet()) {
- case 'i':case 'I': M_FINISH(m_swi,optionCond); /* swi CC */
- case 'p':case 'P': M_FINISH(m_swp,optionCondB); /* swp CC BYTE */
- default: goto illegal;
- } break;
- default: goto illegal;
- } break;
- case 't':case 'T':
- switch(inputGet()) {
- case 'a':case 'A': M_FINISH_CHR('n',m_tan,optionCondPrecRound); /* tan CC P R */
- case 'e':case 'E':
- switch(inputGet()) {
- case 'q':case 'Q': M_FINISH(m_teq,optionCondSP); /* teq CC sp */
- default: goto illegal;
- } break;
- case 's':case 'S': M_FINISH_CHR('t',m_tst,optionCondSP); /* tst CC sp */
- default: goto illegal;
- } break;
- case 'w':case 'W':
- switch(inputGet()) {
- case 'f':case 'F':
- switch(inputGet()) {
- case 'c':case 'C': M_FINISH(m_wfc,optionCond); /* wfc CC */
- case 's':case 'S': M_FINISH(m_wfs,optionCond); /* wfs CC */
- default: goto illegal;
- } break;
- default: goto illegal;
- } break;
- default:
- illegal:
- inputRollback();
- error(ErrorError,FALSE,"Illegal line \"%s\".",inputRest());
- }
- skipblanks();
- if(inputLook() && inputLook()!= ';') { error(ErrorError,FALSE,"Skipping extra characters '%s'.",inputRest()); }
- return returnvalue;
- }
-