/************************************* * C02 Input File Parsing Routines * *************************************/ #include #include #include #include #include #include "common.h" #include "files.h" #include "parse.h" char opstr[2]; //Operator as a String /* Various tests against nxtchr */ int match(char c) {return TF(nxtchr == c);} int inbtwn(char mn, char mx) {return TF(nxtchr >= mn && nxtchr <= mx);} int isprnt() {return isprint(nxtchr);} int isalph() {return isalpha(nxtchr);} int isanum() {return isalnum(nxtchr);} int isdec() {return inbtwn('0', '9');} int ishexd() {return TF(isdec() || inbtwn('A', 'Z'));} int isbin() {return inbtwn('0', '1');} int isnl() {return TF(match('\n') || match('\r'));} int isspc() {return isspace(nxtchr);} int isnpre() {return TF(isdec() || match('$') || match('%'));} int isapos() {return match('\'');} int iscpre() {return TF(isnpre() || isapos());} int isvpre() {return TF(isalph() || iscpre());} int isoper() {return TF(strchr("+-&|^", nxtchr));} int ispopr() {return TF(strchr("+-<>", nxtchr));} /* if Word is s then return TRUE else return FALSE*/ int wordis(char *s) { return strcmp(word, s) == 0; } /* Get Next Character from Current Input File * * Uses: inpfil - Input File Handle * * Sets: nxtchr - Next Character in Source File */ char getnxt() { int i; int wascr = match('\r'); char c = nxtchr; //if (nxtwrd[nxtptr]) //If nxtwrd is set // nxtchr = nxtwrd[nxtptr++]; // Pop First Character from nxtwrd //else nxtchr = fgetc(inpfil); nxtupc = toupper(nxtchr); if (wascr && match('\n')) return c; //Skip NL after CR if (isnl()) curcol=1; else curcol++; if (curcol == 1) curlin++; return c; } /* Advance Input File to next printable character */ void skpspc() { DEBUG("Skipping Spaces\n", 0); while (isspc()) getnxt(); } /* Check if the next printable character is c * * and advance past it if it is * * Returns TRUE is character is found, * * otherwise FALSE */ int look(char c) { int found; skpspc(); found = match(c); if (found) { skpchr(); CCMNT(c); } return found; } /* if next printable character is c then skip, else generate error */ void expect(char c) { if (look(c)) return; else { printf("Expected Character '%c', but found '%c'\n", c, nxtchr); exterr(EXIT_FAILURE); } } /* Advance Input File to next printable character */ void skpchr() {char skip = getnxt();} /* Advance Input File to end of line */ void skpeol() {while (!isnl()) getnxt();} /* Advance Source File to end of comment * * Recognizes both C and C++ style comments */ void skpcmt() { DEBUG("Skipping Comment\n", 0); skpchr(); //skip initial / if (match('/')) //if C style comment skpeol(); // skip rest of line else if (match('*')) //if C++ style comment while (TRUE) // skip to */ { skpchr(); if (!match('*')) continue; while (match('*')) skpchr(); if (!match('/')) continue; skpchr(); break; //todo: add code to catch unterminated comment } else //if neither expctd("/ or *"); // error out } /* Reads next Word in current Input File, where * * a Word is a sequence of AlphaNumeric characters * * Sets: word - the Word read from the source file */ void getwrd() { int wrdlen = 0; skpspc(); if (!isalph()) expctd("Alphabetic Character"); while (isanum()) { word[wrdlen++] = getnxt(); } word[wrdlen] = 0; } /* Get Definition Text */ void getdef() { int wrdlen = 0; skpspc(); while (isprnt()) { word[wrdlen++] = getnxt(); } word[wrdlen] = 0; } /* Process define directive */ void prsdef() { getwrd(); //get defined identifier DEBUG("Defining '%s'\n", word); strncpy(defnam[defcnt], word, VARLEN); getdef(); DEBUG("Defined as '%s'\n", word); strncat(deftxt[defcnt], word, DEFLEN); defcnt++; } /* Check for and Expand DEFINE * * Sets: nxtwrd, nxtchr, nxtupr * * if match is found */ void expdef() { int i; if (!isalph()) return; DEBUG("Checking for definition '%s'\n", word); nxtptr = 0; for (i=0; i maxval) { ERROR("Out of bounds constant '%d';\n", number, EXIT_FAILURE); } if (maxval > 255) sprintf(value, "$%04X", number); else sprintf(value, "$%02X", number); return number; } /* Parse numeric constant * * Args: maxval - maximum allowed value * * Sets: value - the constant (as a string) * * valtyp - value type (CONSTANT) */ void prscon(int maxval) { cnstnt = prsnum(maxval); valtyp = CONSTANT; if (maxval > 255) sprintf(value, "#$%04X", cnstnt); else sprintf(value, "#$%02X", cnstnt); DEBUG("Generated constant '%s'\n", value); } /* Get Value Type */ int gettyp() { if (match('(')) return FUNCTION; else if (match('[')) return ARRAY; else return VARIABLE; } /* Parse next word as variable or function name * * Sets: value - Identifier Name * * valtyp - Identifier Type */ void prsvar() { getwrd(); valtyp = gettyp(); if (valtyp != FUNCTION) chksym(word); strcpy(value, word); DEBUG("Parsed variable '%s'\n", value); } /* Parse arithmetic or bitwise operator */ void prsopr() { if (!isoper) expctd("Arithmetic or bitwise operator"); oper = getnxt(); DEBUG("Parsed operator '%c'\n", oper); opstr[0] = oper; opstr[1] = 0; ACMNT(opstr); skpspc(); }