diff --git a/src/cond.c b/src/cond.c index ce46885..d84a8c1 100644 --- a/src/cond.c +++ b/src/cond.c @@ -79,7 +79,7 @@ void prscmp(int revrse) { if (cmpenc != 0) cmprtr = cmprtr | cmpenc; //Combine Encoded Comparator } skpspc(); - if (cmprtr) prstrm(); + if (cmprtr) prstrm(FALSE); //prccmp(); - Do after check for logical operator DEBUG("Parsed comparator %d\n", cmprtr) } diff --git a/src/dclrtn.c b/src/dclrtn.c index bebf479..268d914 100644 --- a/src/dclrtn.c +++ b/src/dclrtn.c @@ -17,10 +17,16 @@ #include "stmnt.h" #include "dclrtn.h" -void addprm(char* prmtr) { +int addprm(char* prmtr) { reqvar(FALSE); //Get Variable Name + if (vartyp[varidx] == VTINT) { + strcpy(prmtrx, value); + strcpy(prmtry, value); + strcat(prmtry, "+1"); + return TRUE; + } strcpy(prmtr, value); //Copy to Parameter Variable - prmcnt++; //Increment # of Parameters + return FALSE; } /* Add Function Definition */ @@ -28,25 +34,28 @@ void addfnc(void) { if (infunc) ERROR("Nested Function Definitions Not Allowed\n", 0, EXIT_FAILURE) expect('('); strcpy(fncnam, word); //Save Function Name - prmcnt = 0; //Initialze Number of Parameters + prmtra[0] = 0; //Initialze Parameters + prmtry[0] = 0; + prmtrx[0] = 0; skpspc(); //Skip Spaces - if (isalph()) { //Parse Parameters - addprm(prmtra); //Get First Parameter + if (isalph() || match('*')) { //Parse Parameters + if (!look('*')) {if (addprm(prmtra)) goto addfne;} //Get First Parameter if (look(',')) { //Look for Comma - addprm(prmtry); //Get Second Parameter + if (addprm(prmtry)) goto addfne; //Get Second Parameter if (look(',')) { //Look for Comma addprm(prmtrx); //Get Third Parameter } } } + addfne: expect(')'); if (look(';')) return; //Forward Definition infunc = TRUE; //Set Inside Function Definition Flag DEBUG("Set infunc to %d\n", infunc) setlbl(fncnam); //Set Function Entry Point - if (prmcnt > 0) asmlin("STA", prmtra); //Store First Parameter - if (prmcnt > 1) asmlin("STY", prmtry); //Store Second Parameter - if (prmcnt > 2) asmlin("STX", prmtrx); //Store Third Parameter + if (prmtra[0]) asmlin("STA", prmtra); //Store First Parameter + if (prmtry[0]) asmlin("STY", prmtry); //Store Second Parameter + if (prmtrx[0]) asmlin("STX", prmtrx); //Store Third Parameter endlbl[0] = 0; //Create Dummy End Label pshlbl(LTFUNC, endlbl); //and Push onto Stack bgnblk('{'); //Start Program Block @@ -67,18 +76,22 @@ void addcon(int numval) { if (!alcvar) SCMNT(""); //Clear Comment } -/* Parse Enum Declaration*/ -void penum(int m) { - int enmval = 0; - DEBUG("Processing Enum Declarations\n", 0) +/* Parse Enum Declaration +*/ +void penum(int m, int bitmsk) { + int enmval = (bitmsk) ? 1 : 0; + DEBUG("Processing Enum Declarations with BITMSK %d\n", bitmsk) if (m != MTNONE) ERROR("Illegal Modifier %d in Enum Definition", m, EXIT_FAILURE) expect('{'); do { getwrd(); //get defined identifier DEBUG("Enumerating '%s'\n", word) + if (enmval > 0xFF) ERROR("Maximum ENUM or BITMASK value exceeded\n", 0, EXIT_FAILURE) strncpy(defnam, word, VARLEN); sprintf(value, "%d", enmval); - addcon(enmval++); + addcon(enmval); + if (bitmsk) enmval = enmval << 1; + else enmval++; } while (look(',')); expect('}'); expect(';'); @@ -115,11 +128,12 @@ void pdecl(int m, int t) { * Args: m - Modifier Type */ int ptype(int m) { int reslt = TRUE; - if (wordis("STRUCT")) pstrct(m); //Parse 'const' declaration - else if (wordis("ENUM")) penum(m); //Parse 'enum' declaration - else if (wordis("CHAR")) pdecl(m, VTCHAR); //Parse 'char' declaration - else if (wordis("INT")) pdecl(m, VTINT); //Parse 'int' declaration - else if (wordis("VOID")) pdecl(m, VTVOID); //Parse 'void' declaration + if (wordis("STRUCT")) pstrct(m); //Parse 'struct' declaration + else if (wordis("ENUM")) penum(m, FALSE); //Parse 'enum' declaration + else if (wordis("BITMASK")) penum(m, TRUE); //Parse 'enum' declaration + else if (wordis("CHAR")) pdecl(m, VTCHAR); //Parse 'char' declaration + else if (wordis("INT")) pdecl(m, VTINT); //Parse 'int' declaration + else if (wordis("VOID")) pdecl(m, VTVOID); //Parse 'void' declaration else reslt = FALSE; return reslt; } diff --git a/src/dclrtn.h b/src/dclrtn.h index 61f5446..2992551 100644 --- a/src/dclrtn.h +++ b/src/dclrtn.h @@ -5,7 +5,7 @@ char fncnam[VARLEN+1]; //Function Name char prmtra[VARLEN+1]; //Function Parameter A char prmtrx[VARLEN+1]; //Function Parameter X -char prmtry[VARLEN+1]; //Function Parameter Y +char prmtry[VARLEN+3]; //Function Parameter Y int prmcnt; //Number of Parameters //int lpemtd; //Location Prefix Emitted diff --git a/src/expr.c b/src/expr.c index 9148ff9..2488a06 100644 --- a/src/expr.c +++ b/src/expr.c @@ -85,7 +85,7 @@ void prcsix(void) { void prcxix(void) { pshtrm(); //Push Array Variable onto Term Stack if (trmcnt) asmlin("PHA", ""); //Save Accumulator if not first term - prcftm(); //Process First Term of Expression + prcftm(FALSE); //Process First Term of Expression prsrxp(']'); //Parse Rest of Expression asmlin("TAX", ""); //Transfer Result of Expression to Index Register if (trmcnt) asmlin("PLA", ""); //Restore Accumator if not first term @@ -112,14 +112,20 @@ void chkidx(void) { /* Parse Term in Expression * * Sets: term - the term (as a string) */ -void prstrm(void) { +int prstrm(int alwint) { DEBUG("Parsing term\n", 0) prsval(FALSE, TRUE); //Parse Term - Disallow Registers if (valtyp == FUNCTION) ERROR("Function call only allowed in first term\n", 0, EXIT_FAILURE) strcpy(term, value); + if (valtyp == VARIABLE && vartyp[varidx] == VTINT) { + if (!alwint) ERROR("Illegal Use of Integer Variable %s\n", term, EXIT_FAILURE) + prcvri(); //Process Integer Variable + return TRUE; + } DEBUG("Parsed term %s\n", term) chkidx(); //Check for Array Index skpspc(); + return FALSE; } /* Process Address Reference @@ -178,6 +184,22 @@ int chkadr(int adract, int alwstr) { return result; } +/* Parse Function Parameters or Return Values */ +void prsfpr(char trmntr) { + if (!chkadr(ADLDYX, TRUE) && isxpre() || match('*')) { + if (!look('*')) {if (prsxpf(0)) goto prsfne;} + if (look(',') && !chkadr(ADLDYX, TRUE)) { + if (!look('*')) { + if (prstrm(TRUE)) goto prsfne; + asmlin("LDY", term); + } + if (look(',')) { prsval(FALSE, TRUE); asmlin("LDX", value); } + } + } + prsfne: + expect(trmntr); +} + /* Parse function call */ void prsfnc(char trmntr) { DEBUG("Processing Function Call '%s'\n", term) @@ -185,38 +207,43 @@ void prsfnc(char trmntr) { pshtrm(); //Push Function Name onto Term Stack skpchr(); //skip open paren CCMNT('('); - if (!chkadr(ADLDYX, TRUE) && isxpre() || match('*')) { - if (!look('*')) prsxpr(0); - if (look(',') && !chkadr(ADLDYX, TRUE)) { - if (!look('*')) { - prstrm(); asmlin("LDY", term); - } - if (look(',')) { prsval(FALSE, TRUE); asmlin("LDX", value); } - } - } - expect(')'); + prsfpr(')'); //Parse Function Parameters expect(trmntr); poptrm(); //Pop Function Name off Term Stack asmlin("JSR", term); skpspc(); } +/* Process Integer Variable */ +void prcvri(void) { + DEBUG("Processing Integer Variable '%s'\n", value) + asmlin("LDX", value); + strcat(value, "+1"); + asmlin("LDY", value); +} + /* Process first term of expression */ -void prcftm(void) { +int prcftm(int alwint) { DEBUG("Processing first term '%s'\n", value) strcpy(term, value); + if (valtyp == VARIABLE && vartyp[varidx] == VTINT) { + if (!alwint) ERROR("Illegal Use of Integer Variable %s\n", word, EXIT_FAILURE) + prcvri(); + return TRUE; + } if (valtyp == FUNCTION) prsfnc(0); //Parse Expression Function - else if (wordis("A")) return; + else if (wordis("A")) return FALSE; else if (wordis("X")) asmlin("TXA", ""); else if (wordis("Y")) asmlin("TYA", ""); else { chkidx(); asmlin("LDA", term); } + return FALSE; } /* Parse first term of expession * * First term can include function calls */ -void prsftm(void) { +int prsftm(int alwint) { prsval(TRUE, TRUE); //Parse Value, Allowing Registers - prcftm(); + return prcftm(alwint); } /* Process Arithmetic or Bitwise Operator * @@ -241,19 +268,56 @@ void prsrxp(char trmntr) { while (isoper()) { trmcnt++; //Increment Expression Depth prsopr(); //Parse Operator - prstrm(); //Parse Term + prstrm(FALSE); //Parse Term prcopr(); //Process Operator trmcnt--; //Decrement Expression Depth } expect(trmntr); } -/* Parse and compile expression */ -void prsxpr(char trmntr) { +int prsxpp(char trmntr, int alwint) { DEBUG("Parsing expression\n", 0) skpspc(); trmcnt = 0; //Initialize Expression Depth if (match('-')) prcmns(); //Process Unary Minus - else prsftm(); //Parse First Term + else if (prsftm(alwint)) return TRUE; //Parse First Term prsrxp(trmntr); //Parse Remainder of Express + return FALSE; +} + +/* Parse and compile expression */ +void prsxpr(char trmntr) { + prsxpp(trmntr, FALSE); +} + +/* Parse and compile function parameter expression * + * Returns: TRUE if Integer Expression */ +int prsxpf(char trmntr) { + return prsxpp(trmntr, TRUE); +} + +/* Parse and compile integer expression */ +void prsxpi(char trmntr) { + skpspc(); + if (!chkadr(TRUE, FALSE)) { + if (isnpre()) { + DEBUG("Parsing Integer Literal\n", 0) + int number = prsnum(0xFFFF); + sprintf(value, "%d", number & 0xFF); asmlin("LDX", value); + sprintf(value, "%d", number >> 8); asmlin("LDY", value); + } else if (isalph()) { + prsvar(FALSE, TRUE); + if (valtyp == FUNCTION) { + strcpy(term, value); + prsfnc(0); //Parse Expression Function + } else if (valtyp == VARIABLE && vartyp[varidx] == VTINT) { + prcvri(); //Process Integer Variable + } else { + ERROR("Illegal Variable %s In Integer Expression", value, EXIT_FAILURE) + } + } else { + ERROR("Expected Integer Value or Function\n", 0, EXIT_FAILURE); + } + } + expect(trmntr); } diff --git a/src/expr.h b/src/expr.h index a8f5de9..2a1261d 100644 --- a/src/expr.h +++ b/src/expr.h @@ -14,12 +14,15 @@ int trmcnt; //Number of total terms in current expression int chkadr(int adract, int alwstr); //Check for and Process Address or String void chkidx(); //Check for, Parse, and Process Index -void prcftm(); //Process First Term +int prcftm(int alwint); //Process First Term +void prcvri(void); //Process Integer Variable void prsadr(int adract); //Parse and Compile Address of Operator +void prsval(int alwreg, int alwcon); //Parse Value void prsfnc(char trmntr); //Parse function call +void prsfpr(char trmntr); //Parse Function Paraeters or Return void prsidx(); //Parse Array Index -void prstrm(); //Parse Term in Expression -void prsrxp(char trmntr); //Parse Rest of Expression +int prstrm(int alwint); //Parse Term in Expression +void prsrxp(char trmntr); //Parse Rest of Expression +int prsxpf(char trmntr); //Parse Expression in Function Call void prsxpr(char trmntr); //Parse Expression - - +void prsxpi(char trmntr); //Parse Integer Expression diff --git a/src/parse.c b/src/parse.c index 3eb4dfd..aaca7da 100644 --- a/src/parse.c +++ b/src/parse.c @@ -12,11 +12,13 @@ #include "files.h" #include "asm.h" #include "parse.h" +#include "label.h" /* Various tests against nxtchr */ int match(char c) {return TF(nxtchr == c);} int inbtwn(char mn, char mx) {return TF(nxtupc >= mn && nxtupc <= mx);} int isalph(void) {return isalpha(nxtchr);} +int isalst(void) {return TF(isalph() || match('*'));} int isanum(void) {return isalnum(nxtchr);} int isapos(void) {return match('\'');} int isbin(void) {return inbtwn('0', '1');} @@ -354,8 +356,10 @@ void poperr(char* name) { } /* Process Post Operator */ -void prcpst(char* name, char *index) { +void prcpst(int isint, char* name, char *index) { DEBUG("Processing post operation '%c'\n", oper) + char name1[VARLEN+3]; + strcpy(name1, name); strcat(name1, "+1"); if (strlen(index)) { asmlin("LDX", index); strcat(name,",X"); @@ -365,25 +369,48 @@ void prcpst(char* name, char *index) { if (strcmp(name, "X")==0) asmlin("INX", ""); else if (strcmp(name, "Y")==0) asmlin("INY", ""); else if (strcmp(name, "A")==0) poperr(name); //65C02 supports implicit INC, 6502 does not - else asmlin("INC", name); - break; + else { + asmlin("INC", name); + if (isint) { + newlbl(skplbl); + asmlin("BNE", skplbl); + asmlin("INC", name1); + setlbl(skplbl); + } + } + break; case '-': if (strcmp(name, "X")==0) asmlin("DEX", ""); else if (strcmp(name, "Y")==0) asmlin("DEY", ""); else if (strcmp(name, "A")==0) poperr(name); //65C02 supports implicit DEC, 6502 does not - else asmlin("DEC", name); + else { + if (isint) { + newlbl(skplbl); + asmlin("LDA", name); + asmlin("BNE", skplbl); + asmlin("DEC", name1); + setlbl(skplbl); + } + asmlin("DEC", name); + } break; case '<': if (strcmp(name, "X")==0) poperr(name); //Index Register Shift not Supported else if (strcmp(name, "Y")==0) poperr(name); //Index Register Shift not Supported else if (strcmp(name, "A")==0) asmlin("ASL", ""); - else asmlin("ASL", name); + else { + asmlin("ASL", name); + if (isint) asmlin("ROL", name1); + } break; case '>': if (strcmp(name, "X")==0) poperr(name); //Index Register Shift not Supported else if (strcmp(name, "Y")==0) poperr(name); //Index Register Shift not Supported else if (strcmp(name, "A")==0) asmlin("LSR", ""); - else asmlin("LSR", name); + else { + asmlin("LSR", name); + if (isint) asmlin("ROR", name1); + } break; default: ERROR("Unrecognized post operator '%c'\n", oper, EXIT_FAILURE) @@ -391,7 +418,7 @@ void prcpst(char* name, char *index) { } /* Parse Post Operator */ -int prspst(char trmntr, char* name, char* index) { +int prspst(char trmntr, int isint, char* name, char* index) { oper = getnxt(); CCMNT(oper); DEBUG("Checking for post operation '%c'\n", oper) @@ -399,7 +426,7 @@ int prspst(char trmntr, char* name, char* index) { skpchr(); CCMNT(oper); expect(trmntr); - prcpst(name, index); //Process Post-Op + prcpst(isint, name, index); //Process Post-Op return 0; } DEBUG("Not a post operation\n", 0) diff --git a/src/parse.h b/src/parse.h index bfadb46..312e35e 100644 --- a/src/parse.h +++ b/src/parse.h @@ -25,6 +25,7 @@ int mskasc; //Set High Bit Flag int match(char c); //Does Next Character match c int isalph(); //Is Next Character Alphabetic +int isalst(); //Is Next Character Alpha or Asterisk int isanum(); //Is Next Character AlphaNumeric int isapos(); //Is Next Character an Apostrophe int isbin(); //Is Next Character a Binary Digit @@ -54,7 +55,7 @@ int prsbyt(); //Parse Numeric Byte void prslit(); //Parse Literal int prsnum(int maxval); //Parse Numeric void prsopr(); //Parse Arithmetic Operator -int prspst(char trmntr, char* name, char* index); //Parse Post Operator +int prspst(char trmntr, int isint, char* name, char* index); //Parse Post Operator int psizof(void); //Parse SizeOf Operator int pidxof(void); //Parse SizeOf Operator void skpchr(); //Skip Next Character diff --git a/src/stmnt.c b/src/stmnt.c index 0d3d399..d3928ba 100644 --- a/src/stmnt.c +++ b/src/stmnt.c @@ -77,11 +77,8 @@ void setasn(char *name) { if (wrtofs[0]) strcat(word, wrtofs); } -/* Process Assignment */ -void prcasn(char trmntr) { - expect('='); - if (look('(')) prssif(trmntr); //Parse Shortcut If - else prsxpr(trmntr); //Parse Expression +/* Process Assignment of X and Y variables */ +void prcaxy(void) { DEBUG("Processing X assignment variable '%s'\n", xsnvar) if (xsnvar[0]) { setasn(xsnvar); @@ -107,6 +104,14 @@ void prcasn(char trmntr) { asmlin("STY", word); //Store Return Value ysnvar[0] = 0; } +} + +/* Process Assignment */ +void prcasn(char trmntr) { + expect('='); + if (look('(')) prssif(trmntr); //Parse Shortcut If + else prsxpr(trmntr); //Parse Expression + prcaxy(); //Process X and Y assignments DEBUG("Checking if '%s' is a register\n", asnvar) if (strcmp(asnvar, "X")==0) asmlin("TAX", ""); else if (strcmp(asnvar, "Y")==0) asmlin("TAY", ""); @@ -117,6 +122,17 @@ void prcasn(char trmntr) { asmlin("STA", word); //Store Return Value } +/* Process Integer Assignment */ +void prcasi(char trmntr) { + DEBUG("Processing Integer Assignment\n", 0); + expect('='); + strcpy(xsnvar, word); //Set Assignment LSB + strcpy(ysnvar, word); strcat(ysnvar, "+1"); //Set Assignment MSB + ysnidx[0] = 0; //No Y Index + prsxpi(trmntr); + prcaxy(); +} + /* Parse and Return Array Index and Type */ int getidx(char* idx) { prsidx(TRUE); //Parse Array Index @@ -129,9 +145,14 @@ int getidx(char* idx) { /* Process Assignment Variable(s) */ void prcvar(char trmntr) { chksym(TRUE, FALSE, word); + if (vartyp[varidx] == VTINT) { + if (ispopr()) {if (prspst(trmntr, TRUE, word, "")) expctd("post operator");} + else prcasi(trmntr); //Process Integer Assignment + return; + } strcpy(asnvar, word); //save variable to assign to if (valtyp == VARIABLE && match('.')) prsmbr(asnvar); - asntyp = valtyp; //Set Assigned Varable Type + asntyp = valtyp; //Set Assigned Variable Type DEBUG("Set STA variable to %s\n", asnvar) if (asntyp == VARIABLE && look(';')) { asmlin("STA", asnvar); @@ -141,7 +162,7 @@ void prcvar(char trmntr) { else asnidx[0] = 0; DEBUG("Set STA index to '%s'", asnidx) DETAIL(" and type to %d\n", asnivt) if (ispopr()) { - if (prspst(trmntr, asnvar, asnidx)) expctd("post operator"); + if (prspst(trmntr, FALSE, asnvar, asnidx)) expctd("post operator"); return; } if (look(',')) { @@ -349,7 +370,8 @@ void ppush(void) { /* parse and compile return statement */ void pretrn(void) { DEBUG("Parsing RETURN statement\n", 0) - if (!look(';')) prsxpr(';'); + skpspc(); + prsfpr(';'); //Parse Function Return Valuea asmlin("RTS", ""); lsrtrn = TRUE; //Set RETURN flag } @@ -382,7 +404,7 @@ void pcase(void) { newlbl(cndlbl); //Create Conditional Label pshlbl(LTCASE, cndlbl); //and Push onto Stack while(TRUE) { - prstrm(); //Parse CASE argument + prstrm(FALSE); //Parse CASE argument if (!fcase || valtyp != LITERAL || litval) asmlin("CMP", term); //Emit Comparison if (look(',')) { diff --git a/src/vars.c b/src/vars.c index fdad259..848a8ab 100644 --- a/src/vars.c +++ b/src/vars.c @@ -198,6 +198,12 @@ void setdat(void) { dlen = 1; datvar[dsize++] = litval; } + else if (dtype == DTINT) { + DEBUG("Setting variable data to '%d'\n", litval) + dlen = 2; + datvar[dsize++] = litval & 0xFF; + datvar[dsize++] = litval >> 8; + } else if (dtype == DTARRY) { DEBUG("Setting variable data to array of length %d\n", dlen) for (i=0; i>; +m++; +n--; + +e = $5678; +e = c; +e = &$D000; +e = &s; + +b = fnb(e); +d = fnd(b,c); + +i = fni(c); +j = fnj(b,c); + +int fnb(*,yy,xx) { + return *,xx,yy; +} + +int fnd(aa,yy,xx) { + if (aa) return *,xx,yy; + else return *,yy,xx; +} + +int fni(yx) { + yx++; + return yx; +} + +int fnj(aa, yx) { + if (aa:-) yx--; + else {if (aa) yx++;} + return yx; +}