1
0
mirror of https://github.com/RevCurtisP/C02.git synced 2025-04-22 00:37:19 +00:00

Reformatted and refactored conditional code

This commit is contained in:
Curtis F Kaylor 2018-03-05 15:03:04 -05:00
parent 2126642205
commit cf8264f99a
10 changed files with 208 additions and 463 deletions

View File

@ -10,17 +10,12 @@
#include "common.h"
#include "files.h"
//#include "parse.h"
#include "asm.h"
/* Process comment */
void prccmt(void) {
if (strlen(cmtasm)) {
strcpy(asmcmt, ";");
strcat(asmcmt, cmtasm);
}
else
asmcmt[0] = 0;
if (strlen(cmtasm)) { strcpy(asmcmt, ";"); strcat(asmcmt, cmtasm); }
else asmcmt[0] = 0;
setcmt("");
}

View File

@ -25,19 +25,13 @@ void expctd(char *expstr) {
}
/* Print current position in file */
void prtpos(void) {
printf("(%s: %d,%d) ", inpnam, curlin, curcol);
}
void prtpos(void) { printf("(%s: %d,%d) ", inpnam, curlin, curcol); }
/* Set comment to string */
void setcmt(char *s) {
strcpy(cmtasm, s);
}
void setcmt(char *s) { strcpy(cmtasm, s); }
/* Append string to comment */
void addcmt(char *s) {
strcat(cmtasm, s);
}
void addcmt(char *s) { strcat(cmtasm, s); }
/* Append character to comment */
void chrcmt(char c) {

View File

@ -29,10 +29,7 @@ int enccmp(char c) {
case '>': e = 4; break;
default: e = 0;
}
if (e) {
CCMNT(c);
skpchr();
}
if (e) { CCMNT(c); skpchr(); }
DETAIL(", encoded as %d\n", e);
return e;
}
@ -45,37 +42,21 @@ void prccmp(void) {
DEBUG("Processing comparitor %d\n", cmprtr)
switch(cmprtr) {
case 0: // Raw Expression (Skip)
asmlin("BEQ", cndlbl);
break;
asmlin("BEQ", cndlbl); break;
case 1: // = or ==
asmlin("CMP", term);
asmlin("BNE", cndlbl);
break;
asmlin("CMP", term); asmlin("BNE", cndlbl); break;
case 2: // <
asmlin("CMP", term);
asmlin("BCS", cndlbl);
break;
asmlin("CMP", term); asmlin("BCS", cndlbl); break;
case 3: // <= or =<
asmlin("CLC", "");
asmlin("SBC", term);
asmlin("BCS", cndlbl);
break;
asmlin("CLC", ""); asmlin("SBC", term); asmlin("BCS", cndlbl); break;
case 4: // >
asmlin("CLC", "");
asmlin("SBC", term);
asmlin("BCC", cndlbl);
break;
asmlin("CLC", ""); asmlin("SBC", term); asmlin("BCC", cndlbl); break;
case 5: // >= or =>
asmlin("CMP", term);
asmlin("BCC", cndlbl);
break;
asmlin("CMP", term); asmlin("BCC", cndlbl); break;
case 6: // <> or ><
asmlin("CMP", term);
asmlin("BEQ", cndlbl);
break;
asmlin("CMP", term); asmlin("BEQ", cndlbl); break;
case 7: // Raw Expression (Normal)
asmlin("BNE", cndlbl);
break;
asmlin("BNE", cndlbl); break;
default:
ERROR("Unsupported comparison operator index %d\n", cmprtr, EXIT_FAILURE)
}
@ -88,13 +69,11 @@ void prscmp(int revrse) {
cmprtr = cmpenc; //Set Encoded Comparator
if (cmprtr) {
cmpenc = enccmp(nxtchr); //Encode Next Comparison Character
if (cmpenc != 0)
cmprtr = cmprtr | cmpenc; //Combine Encoded Comparator
if (cmpenc != 0) cmprtr = cmprtr | cmpenc; //Combine Encoded Comparator
}
skpspc();
if (cmprtr)
prstrm();
cmprtr = (cmprtr ^ revrse) & 7;
if (cmprtr) prstrm();
cmprtr = (cmprtr ^ revrse) & 7; //Apply reversal
prccmp();
DEBUG("Parsed comparator %d\n", cmprtr)
}
@ -102,18 +81,13 @@ void prscmp(int revrse) {
/* Parse Flag Operator */
void prsflg(int revrse) {
DEBUG("Parsing Flag Operator '%c'\n", nxtchr)
if (match('+'))
cmprtr = 0;
else if (match('-'))
cmprtr = 1;
else
expctd("Flag operator");
if (match('+')) cmprtr = 0;
else if (match('-')) cmprtr = 1;
else expctd("Flag operator");
skpchr();
cmprtr = (cmprtr ^ revrse) & 1;
if (cmprtr)
asmlin("BPL", cndlbl);
else
asmlin("BMI", cndlbl);
cmprtr = (cmprtr ^ revrse) & 1; //Apply Reversal
if (cmprtr) asmlin("BPL", cndlbl);
else asmlin("BMI", cndlbl);
}
/* Parse and Compile Conditional Expression *
@ -124,11 +98,8 @@ void prscnd(char trmntr, int revrse) {
revrse = (revrse) ? FALSE: TRUE;
DEBUG("Set revrse to %d\n", revrse)
}
if (!look('*'))
prsxpr(0);
if (look(':'))
prsflg(revrse); //Parse Flag Operator
else
prscmp(revrse); //Parse Comparison Operator
if (!look('*')) prsxpr(0);
if (look(':')) prsflg(revrse); //Parse Flag Operator
else prscmp(revrse); //Parse Comparison Operator
expect(trmntr);
}

View File

@ -23,6 +23,7 @@ void addfnc(void) {
strcpy(fncnam, word); //Save Function Name
prmcnt = 0; //Set Number of Parameters
skpspc(); //Skip Spaces
/* QUESTION: Eliminate this in favor of Register Assignments inside Function Call? */
if (isalph()) { //Parse Parameters
reqvar(FALSE); //Get First Parameter
strcpy(prmtra, value);
@ -39,15 +40,11 @@ void addfnc(void) {
}
}
expect(')');
if (look(';')) //Forward Definition
return;
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 (look(';')) return; //Forward Definition
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
endlbl[0] = 0; //Create Dummy End Label
pshlbl(LTFUNC, endlbl); //and Push onto Stack
bgnblk('{'); //Start Program Block
@ -56,19 +53,15 @@ void addfnc(void) {
/* (Check For and) Parse Variable Declaration*/
void pdecl(int m, int t) {
DEBUG("Processing variable declarations(s) of type %d\n", t)
while(TRUE) {
do {
getwrd();
if (match('(')) {
if (m != MTNONE)
ERROR("Illegal Modifier %d in Function Definion", m, EXIT_FAILURE)
if (m != MTNONE) ERROR("Illegal Modifier %d in Function Definition", m, EXIT_FAILURE)
addfnc(); //Add Function Call
return;
}
addvar(m, t);
if (!look(','))
break;
}
} while (look(','));
expect(';');
DEBUG("Variable Declaration Completed\n", 0)
SCMNT(""); //Clear Assembler Comment
@ -77,13 +70,9 @@ void pdecl(int m, int t) {
/* Check for and Parse Type Keyword */
int ptype(int m) {
int result = TRUE;
if (wordis("VOID"))
pdecl(m, VTVOID); //Parse 'void' declaration
else if (wordis("CHAR"))
pdecl(m, VTCHAR); //Parse 'char' declaration
else
result = FALSE;
//DEBUG("Returning %d from function ptype\n", result)'
if (wordis("VOID")) pdecl(m, VTVOID); //Parse 'void' declaration
else if (wordis("CHAR")) pdecl(m, VTCHAR); //Parse 'char' declaration
else result = FALSE;
return result;
}
@ -91,15 +80,8 @@ int ptype(int m) {
int pmodfr(void) {
DEBUG("Parsing modifier '%s'\n", word)
int result = TRUE;
if (wordis("ALIGNED")) {
getwrd();
ptype(MTALGN);
}
else if (wordis("ZEROPAGE")) {
getwrd();
ptype(MTZP);
}
else
result = FALSE;
if (wordis("ALIGNED")) { getwrd(); ptype(MTALGN); }
else if (wordis("ZEROPAGE")) { getwrd(); ptype(MTZP); }
else result = FALSE;
return result;
}

View File

@ -20,13 +20,9 @@
void prsval(int alwreg) {
DEBUG("Parsing value\n", 0)
skpspc();
if (iscpre())
prscon(); //Parse Constant
else if (isalph()) {
prsvar(alwreg); //Parse Variable
}
else
expctd("constant or variable");
if (iscpre()) prscon(); //Parse Constant
else if (isalph()) prsvar(alwreg); //Parse Variable
else expctd("constant or variable");
DEBUG("Parsed value of type %d\n", valtyp)
skpspc();
}
@ -53,10 +49,8 @@ void chkidx(void) {
else if (strcmp(value, "Y")==0)
strcat(term, ",Y");
else {
if (strcmp(value, "A")==0)
asmlin("TAX", "");
else if (strcmp(value, "X")!=0)
asmlin("LDX", value);
if (strcmp(value, "A")==0) asmlin("TAX", "");
else if (strcmp(value, "X")!=0) asmlin("LDX", value);
strcat(term, ",X");
}
}
@ -67,9 +61,7 @@ void chkidx(void) {
void prstrm(void) {
DEBUG("Parsing term\n", 0)
prsval(FALSE);
if (valtyp == FUNCTION)
ERROR("Function call only allowed in first term\n", 0, EXIT_FAILURE)
if (valtyp == FUNCTION) ERROR("Function call only allowed in first term\n", 0, EXIT_FAILURE)
strcpy(term, value);
DEBUG("Parsed term %s\n", term)
chkidx(); //Check for Array Index
@ -81,29 +73,19 @@ void prcadr(int adract, char* symbol) {
DEBUG("Processing address '%s'\n", word)
strcpy(word,"#>");
strcat(word,symbol);
if (adract == 1) {
asmlin("LDA", word);
asmlin("PHA", "");
}
else
asmlin("LDY", word);
if (adract == 1) { asmlin("LDA", word); asmlin("PHA", ""); }
else asmlin("LDY", word);
strcpy(word,"#<");
strcat(word,symbol);
if (adract == 1) {
asmlin("LDA", word);
asmlin("PHA", "");
}
else
asmlin("LDX", word);
if (adract == 1) { asmlin("LDA", word); asmlin("PHA", ""); }
else asmlin("LDX", word);
}
/* Parse and Compile Address of Operator */
void prsadr(int adract) {
DEBUG("Parsing address\n", 0)
if (isnpre())
prsnum(0xFFFF);
else
prsvar(FALSE);
if (isnpre()) prsnum(0xFFFF);
else prsvar(FALSE);
prcadr(adract, value); //Compile Address Reference
}
@ -123,12 +105,9 @@ void prsstr(int adract) {
int chkadr(int adract) {
DEBUG("Checking for Address or String\n", 0)
int result = TRUE;
if (look('&'))
prsadr(adract);
else if (match('"'))
prsstr(adract);
else
result = FALSE;
if (look('&')) prsadr(adract);
else if (match('"')) prsstr(adract);
else result = FALSE;
skpspc();
return result;
}
@ -136,26 +115,15 @@ int chkadr(int adract) {
/* Parse function call */
void prsfnc(char trmntr) {
DEBUG("Processing Function Call '%s'\n", term)
if (fnscnt >= MAXFNS)
ERROR("Maximum Function Call Depth Exceeded", 0, EXIT_FAILURE)
if (fnscnt >= MAXFNS) ERROR("Maximum Function Call Depth Exceeded", 0, EXIT_FAILURE)
strcpy(fnstck[fnscnt++], term);
skpchr(); //skip open paren
CCMNT('(');
if (!chkadr(0) && isxpre() || match('*')) {
if (!look('*')) prsxpr(0);
if (look(',')) {
if (!chkadr(0)) {
if (!look('*')) {
prstrm();
asmlin("LDY", term);
}
if (look(',')) {
if (!look('*')) {
prsval(FALSE);
asmlin("LDX", value);
}
}
}
if (look(',') && !chkadr(0)) {
if (!look('*')) { prstrm(); asmlin("LDY", term); }
if (look(',')) { prsval(FALSE); asmlin("LDX", value); }
}
}
expect(')');
@ -170,48 +138,25 @@ void prsftm(void) {
prsval(TRUE);
DEBUG("Processing first term '%s'\n", value)
strcpy(term, value);
if (valtyp == FUNCTION) {
prsfnc(0); //Parse Expression Function
return;
}
if (wordis("A"))
return;
if (wordis("X"))
asmlin("TXA", "");
else if (wordis("Y"))
asmlin("TYA", "");
else {
chkidx(); //Check for Array Index
asmlin("LDA", term);
}
if (valtyp == FUNCTION) prsfnc(0); //Parse Expression Function
else if (wordis("A")) return;
else if (wordis("X")) asmlin("TXA", "");
else if (wordis("Y")) asmlin("TYA", "");
else { chkidx(); asmlin("LDA", term); }
}
/* Process Arithmetic or Bitwise Operator *
* and the term that follows it */
void prcopr(void) {
DEBUG("Processing operator '%c'\n", oper)
switch(oper)
{
case '+':
asmlin("CLC", "");
asmlin("ADC", term);
break;
case '-':
asmlin("SEC", "");
asmlin("SBC", term);
break;
case '&':
asmlin("AND", term);
break;
case '|':
switch(oper) {
case '+': asmlin("CLC", ""); asmlin("ADC", term); break;
case '-': asmlin("SEC", ""); asmlin("SBC", term); break;
case '&': asmlin("AND", term); break;
case '!': //For systems that don't have pipe in character set
asmlin("ORA", term);
break;
case '^': //Looks like an up-arrow in some character sets
asmlin("EOR", term);
break;
default:
ERROR("Unrecognized operator '%c'\n", oper, EXIT_FAILURE)
case '|': asmlin("ORA", term); break;
case '^': asmlin("EOR", term); break;
default: ERROR("Unrecognized operator '%c'\n", oper, EXIT_FAILURE)
}
oper = 0;
}
@ -224,11 +169,9 @@ void prsxpr(char trmntr) {
DEBUG("Processing unary minus", 0)
asmlin("LDA", "#$00"); //Handle Unary Minus
}
else
prsftm(); //Parse First Term
else prsftm(); //Parse First Term
skpspc();
while (isoper())
{
while (isoper()) {
prsopr(); //Parse Operator
prstrm(); //Parse Term
prcopr(); //Process Operator

View File

@ -23,17 +23,14 @@ void extsys(char *s) {
* Sets: srcfil - Source File Handle */
void opnsrc(void) {
DEBUG("Processing Source File Name '%s'\n", srcnam)
if (strrchr(srcnam, '.') == NULL) //if no extension
strcat(srcnam, ".c02"); // add ".c02"
if (strrchr(srcnam, '.') == NULL) strcat(srcnam, ".c02"); //if no extension. add ".c02"
DEBUG("opening Source File '%s'\n", srcnam)
srcfil = fopen(srcnam, "r"); //open file
if (srcfil == NULL) extsys(srcnam);
}
/* Close Source File */
void clssrc(void) {
fclose(srcfil);
}
void clssrc(void) { fclose(srcfil); }
/* Open Output File *
* Uses: outnam - Output File Name *
@ -47,8 +44,7 @@ void opnout(void) {
if (dot != NULL) *dot = 0; //and remove it
DEBUG("Set Output File Name to '%s'\n", outnam)
}
if (strrchr(outnam, '.') == NULL) //if no extension
strcat(outnam, ".asm"); // add ".asm"
if (strrchr(outnam, '.') == NULL) strcat(outnam, ".asm"); //if no extension, add ".asm"
DEBUG("Opening Output File '%s'\n", outnam)
outfil = fopen(outnam, "w"); //open file
if (outfil == NULL) extsys(outnam);
@ -66,8 +62,8 @@ void clsout(void) {
void opnlog(void) {
strcpy(lognam, srcnam); //set Log File Name to Source File Name
char *dot = strrchr(lognam, '.'); //find file extension
if (dot != NULL) *dot = 0; //and remove it
strcat(lognam, ".log"); //add extension ".asm"
if (dot != NULL) *dot = 0; //and remove it
strcat(lognam, ".log"); //add extension ".log"
DEBUG("Opening Log File '%s'\n", lognam)
logfil = fopen(lognam, "w");
if (logfil == NULL) extsys(lognam);
@ -75,9 +71,7 @@ void opnlog(void) {
/* Close Log File *
* Uses: logfil - Log File Handle */
void clslog(void) {
fclose(logfil);
}
void clslog(void) { fclose(logfil); }
/* Open Include file *
* Uses: incnam - Include File Name *
@ -91,7 +85,4 @@ void opninc(void)
/* Close Include File *
* Uses: incfil - Include File Handle */
void clsinc(void) {
fclose(incfil);
}
void clsinc(void) { fclose(incfil); }

View File

@ -24,20 +24,15 @@ const char lblflg[] = {LFNONE, LFNONE, LFBGN, LFEND, LFBGN, LFEND, LFEND, LFNONE
int lstlbl(int lbflag) {
int i;
DEBUG("Searching for label flag %d\n", lbflag)
for (i = lblcnt - 1; i>-1; i--) {
//DEBUG("Comparing against flag %d", lblflg[lbltyp[i]])
for (i = lblcnt - 1; i>-1; i--)
if (lblflg[lbltyp[i]] == lbflag) break;
}
DEBUG("Search produced label index %d\n", i)
if (i>=0)
strcpy(tmplbl, lblnam[i]);
if (i>=0) strcpy(tmplbl, lblnam[i]);
return i;
}
/* Set Block Flag for Last Label */
void setblk(int blkflg) {
lblblk[lblcnt-1] = blkflg;
}
void setblk(int blkflg) { lblblk[lblcnt-1] = blkflg; }
/* Set label for next line of *
* Assembly Language Code *
@ -48,8 +43,7 @@ void setlbl(char *lblset) {
DEBUG("Emitting Label '%s'\n'", lblasm);
asmlin("",""); //Emit Block End Label on it's own line
}
if (strlen(lblset) > LABLEN)
ERROR("Label '%s' exceeds maximum size\n", word, EXIT_FAILURE)
if (strlen(lblset) > LABLEN) ERROR("Label '%s' exceeds maximum size\n", word, EXIT_FAILURE)
strcpy(lblasm, lblset);
}
@ -79,34 +73,23 @@ void chklbl(char* lbname) {
* if label is already set, returns that label *
* else generates new label and sets it */
void reqlbl(char* lbname) {
if (lblasm[0])
strcpy(lbname, lblasm);
else {
newlbl(lbname);
setlbl(lbname);
}
if (lblasm[0] == 0) newlbl(lbname);
setlbl(lbname);
}
/* Pop Label from Stack and Emit on Next Line */
int poplbl(void) {
int lbtype = lbltyp[--lblcnt];
DEBUG("Popped label type %d\n", lbtype)
if (lbtype == LTLOOP)
asmlin("JMP", lblnam[lblcnt--]); //Jump to Beginning of Loop
if (lbtype == LTFUNC) {
if (!lsrtrn) asmlin("RTS", ""); //Return From Subroutine
switch (lbtype) {
case LTFUNC: if (!lsrtrn) asmlin("RTS", ""); break; //Return From Subroutine
case LTDO: strcpy(loplbl, lblnam[lblcnt]); break;
case LTDWHL: strcpy(endlbl, lblnam[lblcnt]); break;
case LTCASE: strcpy(cndlbl, lblnam[lblcnt]); break;
case LTLOOP: asmlin("JMP", lblnam[lblcnt--]); //Jump to Beginning of Loop
default: setlbl(lblnam[lblcnt]); //Emit End of Loop Label
}
else if (lbtype == LTDO)
strcpy(loplbl, lblnam[lblcnt]);
else if (lbtype == LTDWHL)
strcpy(endlbl, lblnam[lblcnt]);
//strcpy(cndlbl, lblnam[lblcnt]);
else if (lbtype == LTCASE)
strcpy(cndlbl, lblnam[lblcnt]);
else
setlbl(lblnam[lblcnt]);
if (lbtype != LTCASE)
inblck = lblblk[lblcnt-1];
if (lbtype != LTCASE) inblck = lblblk[lblcnt-1];
return lbtype;
}

View File

@ -68,8 +68,7 @@ char getnxt(void) {
void skpspc(void) {
//DEBUG("Skipping Spaces\n", 0)
if (isspc()) CCMNT(' '); //Add only the first space to comments
while (isspc())
getnxt();
while (isspc()) getnxt();
}
/* Check if the next printable character is c *
@ -96,8 +95,7 @@ void expect(char c) {
/* Advance Input File to next printable character */
void skpchr(void) {
char skip = getnxt();
DEBUG("Skipped character '%c'\n", skip)
getnxt();
}
/* Advance Input File to end of line */
@ -109,8 +107,7 @@ void skpcmt(void)
{
DEBUG("Skipping Comment\n", 0)
skpchr(); //skip initial /
if (match('/')) //if C style comment
skpeol(); // skip rest of line
if (match('/')) skpeol(); //if C style comment skip rest of line
else if (match('*')) //if C++ style comment
while (TRUE) // skip to */
{
@ -122,8 +119,7 @@ void skpcmt(void)
break;
//todo: add code to catch unterminated comment
}
else //if neither
expctd("/ or *"); // error out
else expctd("/ or *"); //if neither error out
}
/* Reads next Word in current Input File, where *
@ -133,10 +129,7 @@ void getwrd(void) {
int wrdlen = 0;
skpspc();
if (!isalph()) expctd("Alphabetic Character");
while (isanum())
{
word[wrdlen++] = toupper(getnxt());
}
while (isanum()) word[wrdlen++] = toupper(getnxt());
word[wrdlen] = 0;
ACMNT(word);
}
@ -164,10 +157,8 @@ void getstr(void) {
escnxt = FALSE;
}
else {
if (match('\\'))
escnxt = TRUE;
else
word[wrdlen++] = prcchr(nxtchr);
if (match('\\')) escnxt = TRUE;
else word[wrdlen++] = prcchr(nxtchr);
skpchr();
}
}
@ -185,8 +176,7 @@ int prsbin(void) {
int wrdlen = 0;
int digit;
int number = 0;
if (!match('%'))
expctd("binary number");
if (!match('%')) expctd("binary number");
word[wrdlen++] = nxtchr;
getnxt();
while (isbin()) {
@ -228,16 +218,13 @@ int prshex(void) {
int digit;
int number = 0;
DEBUG("Parsing hexadecimal constant '", 0)
if (!match('$'))
expctd("hexadecimal number");
if (!match('$')) expctd("hexadecimal number");
word[wrdlen++] = getnxt();
while (ishexd()) {
DETAIL("%c", nxtchr);
word[wrdlen++] = nxtchr;
if (isdec())
digit = nxtchr - '0';
else
digit = nxtchr - 'A' + 10;
if (isdec()) digit = nxtchr - '0';
else digit = nxtchr - 'A' + 10;
number = number * 16 + digit;
skpchr();
}
@ -256,8 +243,7 @@ int prschr(void) {
DEBUG("Parsing character constant\n", 0)
expect('\'');
word[wrdlen++] = '\'';
if (match('\\'))
word[wrdlen++] = getnxt();
if (match('\\')) word[wrdlen++] = getnxt();
c = getnxt();
DEBUG("Extracted character %c\n", c)
word[wrdlen++] = prcchr(c);
@ -277,28 +263,16 @@ int prsnum(int maxval) {
skpspc();
if (!isbpre()) expctd("constant value");
switch(nxtchr) {
case '%':
number = prsbin();
break;
case '$':
number = prshex();
break;
case '\'':
number = prschr();
break;
default:
number = prsdec();
case '%': number = prsbin(); break;
case '$': number = prshex(); break;
case '\'': number = prschr(); break;
default: number = prsdec();
}
DEBUG("Parsed number '%s' ", word)
DETAIL("with value '%d'\n", number)
if (number > maxval)
ERROR("Out of bounds constant '%d';\n", number, EXIT_FAILURE)
if (maxval > 255)
sprintf(value, "$%04X", number);
else
sprintf(value, "$%02X", number);
if (number > 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;
}
@ -308,10 +282,8 @@ int prsbyt(void) {return prsnum(0xFF);}
/* Find Defined Constant */
void fnddef(char *name) {
DEBUG("Looking up defined constant '%s'\n", word)
for (defidx=0; defidx<defcnt; defidx++) {
if (strcmp(defnam[defidx], name) == 0)
return;
}
for (defidx=0; defidx<defcnt; defidx++)
if (strcmp(defnam[defidx], name) == 0) return;
defidx = -1;
}
@ -320,9 +292,7 @@ int prsdef(void) {
expect('#');
getwrd(); //Get Constant Name
fnddef(word);
if (defidx < 0)
ERROR("Undefined constant '%s'\n", word, EXIT_FAILURE)
if (defidx < 0) ERROR("Undefined constant '%s'\n", word, EXIT_FAILURE)
strcpy(value, word);
return defval[defidx];
}
@ -338,10 +308,8 @@ int prsdef(void) {
* character arguments instead of 'c' */
void prscon(void) {
skpspc();
if (ishash())
cnstnt = prsdef();
else
cnstnt = prsbyt();
if (ishash()) cnstnt = prsdef();
else cnstnt = prsbyt();
valtyp = CONSTANT;
strcpy(word, value); //Patch for DASM
strcpy(value, "#");
@ -358,8 +326,7 @@ int gettyp(void) {
/* Parse arithmetic or bitwise operator */
void prsopr(void) {
if (!isoper())
expctd("Arithmetic or bitwise operator");
if (!isoper()) expctd("Arithmetic or bitwise operator");
oper = getnxt();
DEBUG("Parsed operator '%c'\n", oper)
CCMNT(oper);
@ -382,44 +349,28 @@ void prcpst(char* name, char *index) {
}
switch(oper) {
case '+':
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);
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;
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);
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);
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);
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);
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);
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);
break;
default:
ERROR("Unrecognized post operator '%c'\n", oper, EXIT_FAILURE)
@ -436,10 +387,8 @@ int prspst(char trmntr, char* name, char* index) {
CCMNT(oper);
expect(trmntr);
prcpst(name, index); //Process Post-Op
oper = 0;
}
else {
DEBUG("Not a post operation\n", 0)
return 0;
}
DEBUG("Not a post operation\n", 0)
return oper;
}

View File

@ -37,11 +37,9 @@ void endblk(int blkflg) {
DEBUG("Ending program block with flag %d\n", blkflg)
expect('}'); //Block End Character
DEBUG("Found inblck set to %d\n", inblck)
if (inblck != blkflg)
ERROR("Encountered '}' without matching '{'\n", 0, EXIT_FAILURE)
if (inblck != blkflg) ERROR("Encountered '}' without matching '{'\n", 0, EXIT_FAILURE)
lbtype = poplbl();
if (lbtype == LTDO)
pdowhl(); //Parse While at End of Do Loop
if (lbtype == LTDO) pdowhl(); //Parse While at End of Do Loop
}
/* Parse Shortcut If */
@ -75,10 +73,8 @@ void prcidx(int idxtyp, char *name, char *index)
/* Process Assignment */
void prcasn(char trmntr) {
expect('=');
if (look('('))
prssif(trmntr); //Parse Shortcut If
else
prsxpr(trmntr); //Parse Expression
if (look('(')) prssif(trmntr); //Parse Shortcut If
else prsxpr(trmntr); //Parse Expression
DEBUG("Processing X assignment variable '%s'\n", xsnvar)
if (xsnvar[0]) {
asmlin("STX", xsnvar);
@ -86,32 +82,25 @@ void prcasn(char trmntr) {
}
DEBUG("Processing Y assignment variable '%s'\n", ysnvar)
if (ysnvar[0]) {
if (strlen(ysnidx))
prcidx(ysnivt, ysnvar, ysnidx);
if (strlen(ysnidx)) prcidx(ysnivt, ysnvar, ysnidx);
asmlin("STY", ysnvar);
ysnvar[0] = 0;
}
DEBUG("Checking if '%s' is a register\n", asnvar)
if (strcmp(asnvar, "X")==0) asmlin("TAX", "");
else if (strcmp(asnvar, "Y")==0) asmlin("TAY", "");
else if (strcmp(asnvar, "A")==0) return;
DEBUG("Processing assignment variable '%s'\n", asnvar)
if (strcmp(asnvar, "X")==0)
asmlin("TAX", "");
else if (strcmp(asnvar, "Y")==0)
asmlin("TAY", "");
else if ((strcmp(asnvar, "A")!=0))
{
if (strlen(asnidx))
prcidx(asnivt, asnvar, asnidx);
asmlin("STA", asnvar);
}
if (strlen(asnidx)) prcidx(asnivt, asnvar, asnidx);
asmlin("STA", asnvar);
}
/* Parse and Return Array Index and Type */
int getidx(char* idx) {
prsidx(); //Parse Array Index
if (valtyp == CONSTANT)
strncpy(idx, word, VARLEN);
else
strncpy(idx, value, VARLEN);
DEBUG("Set assigned index to %s\n", asnidx)
if (valtyp == CONSTANT) strncpy(idx, word, VARLEN);
else strncpy(idx, value, VARLEN);
DEBUG("Parsed index %s\n", idx)
return valtyp;
}
@ -125,51 +114,35 @@ void prcvar(char trmntr) {
asmlin("STA", asnvar);
return;
}
if (asntyp == ARRAY) {
asnivt = getidx(asnidx); //Get Array Index and Type
DEBUG("Set STA index to %s\n", asnidx)
DEBUG("Set STA index type to %d\n", asnivt)
}
else
asnidx[0] = 0;
if (asntyp == ARRAY) asnivt = getidx(asnidx); //Get Array Index and Type
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)) //Parse Post Operator
expctd("post operator");
/*refactor - put a return here and remove followig else*/
if (prspst(trmntr, asnvar, asnidx)) expctd("post operator");
return;
}
else {
if (look(',')) {
if (asntyp == REGISTER)
ERROR("Register %s not allowed in plural assignment\n", asnvar, EXIT_FAILURE)
if (look(',')) {
if (asntyp == REGISTER) ERROR("Register %s not allowed in plural assignment\n", asnvar, EXIT_FAILURE)
prsvar(FALSE); //get variable name
strcpy(ysnvar, word);
DEBUG("Set STY variable to %s\n", ysnvar)
if (valtyp == ARRAY) ysnivt = getidx(ysnidx); //Get Array Index and Type
else ysnidx[0] = 0;
DEBUG("Set STY index to '%s'", ysnidx) DETAIL(" and type to %d\n", ysnivt)
if (look(',')) {
prsvar(FALSE); //get variable name
strcpy(ysnvar, word);
DEBUG("Set STY variable to %s\n", ysnvar)
if (valtyp == ARRAY) {
ysnivt = getidx(ysnidx); //Get Array Index and Type
DEBUG("Set STY index to %s\n", ysnidx)
DEBUG("Set STY index type to %d\n", ysnivt)
}
else
ysnidx[0] = 0;
if (look(',')) {
prsvar(FALSE); //get variable name
strcpy(xsnvar, word);
DEBUG("Set STX variable to %s\n", xsnvar)
if (valtyp == ARRAY)
ERROR("Array element not allowed in third assignment\n", 0, EXIT_FAILURE)
}
strcpy(xsnvar, word);
DEBUG("Set STX variable to %s\n", xsnvar)
if (valtyp == ARRAY) ERROR("Array element not allowed in third assignment\n", 0, EXIT_FAILURE)
}
prcasn(trmntr);
}
prcasn(trmntr);
}
/* Parse 'asm' String Parameter */
void pasmst(char trmntr) {
skpspc(); //Skip Spaces
if (!match('"'))
expctd("string");
if (!match('"')) expctd("string");
getstr();
skpspc();
expect(trmntr);
@ -198,8 +171,7 @@ void prsasn(char trmntr) {
void pbrcnt(int lbflag)
{
DEBUG("Parsing BREAK/CONTINUE statement\n", 0)
if (lstlbl(lbflag) < 0)
ERROR("Break/continue statement outside of loop\n", 0, EXIT_FAILURE)
if (lstlbl(lbflag) < 0) ERROR("Break/continue statement outside of loop\n", 0, EXIT_FAILURE)
DEBUG("Found Label '%s'\n", tmplbl)
asmlin("JMP", tmplbl);
expect(';');
@ -208,30 +180,24 @@ void pbrcnt(int lbflag)
/* parse and compile 'do' statement */
void pdo(void) {
DEBUG("Parsing DO statement '%c'\n", nxtchr)
newlbl(endlbl); //Create End Label
pshlbl(LTDWHL, endlbl); //and Push onto Stack
reqlbl(loplbl); //Get or Create/Set Loop Label
//newlbl(loplbl); //Create Do Loop Label
//setlbl(loplbl); //Set Label to Emit on Next Line
pshlbl(LTDO, loplbl); //Push onto Stack
bgnblk(FALSE); //Check For and Begin Block
newlbl(endlbl); //Create End Label
pshlbl(LTDWHL, endlbl); //and Push onto Stack
reqlbl(loplbl); //Get or Create/Set Loop Label
pshlbl(LTDO, loplbl); //Push onto Stack
bgnblk(FALSE); //Check For and Begin Block
}
/* parse and compile 'while' after 'do' statement */
void pdowhl(void) {
DEBUG("Parsing WHILE after DO '%c'\n", nxtchr)
getwrd(); //Check for While
if (!wordis("WHILE"))
expctd("while statement");
getwrd(); //Check for While
if (!wordis("WHILE")) expctd("while statement");
expect('(');
//poplbl(); //Pop While Conditional Label
strcpy(cndlbl, loplbl); //Set Conditional Label to Loop Label
prscnd(')', TRUE); //Parse Conditional Expession
//asmlin("JMP", loplbl); //Emit Jump to Beginning of Loop
//setlbl(cndlbl); //and Set Label to Emit on Next Line
strcpy(cndlbl, loplbl); //Set Conditional Label to Loop Label
prscnd(')', TRUE); //Parse Conditional Expession
poplbl(); //Pop While Conditional Label
setlbl(endlbl); //and Set Label to Emit on Next Line
expect(';'); //Check for End of Statement
expect(';'); //Check for End of Statement
}
@ -350,8 +316,7 @@ void ppush(void) {
/* parse and compile return statement */
void pretrn(void) {
DEBUG("Parsing RETURN statement\n", 0)
if (!look(';'))
prsxpr(';');
if (!look(';')) prsxpr(';');
asmlin("RTS", "");
lsrtrn = TRUE; //Set RETURN flag
}
@ -371,24 +336,21 @@ void pslct(void) {
/* process end of case block */
void ecase(void) {
DEBUG("Processing end of CASE block\n", 0)
if (poplbl(cndlbl) != LTCASE)
ERROR("%s not at end of CASE block\n", word, EXIT_FAILURE)
if (toplbl(endlbl) != LTSLCT)
ERROR("Illegal nesting in SELECT statement\n", 0, EXIT_FAILURE)
if (poplbl(cndlbl) != LTCASE) ERROR("%s not at end of CASE block\n", word, EXIT_FAILURE)
if (toplbl(endlbl) != LTSLCT) ERROR("Illegal nesting in SELECT statement\n", 0, EXIT_FAILURE)
asmlin("JMP", endlbl); //Emit jump over default case
setlbl(cndlbl); //Set entry point label to emit
}
/* parse and compile select statement */
void pcase(void) {
if (!fcase)
ecase(); //Process end of case block
if (!fcase) ecase(); //Process end of case block
skplbl[0] = 0; //Clear Skip Label
newlbl(cndlbl); //Create Conditional Label
pshlbl(LTCASE, cndlbl); //and Push onto Stack
while(TRUE) {
prstrm(); //Parse CASE argument
if (!fcase || valtyp != CONSTANT || cnstnt)
if (!fcase || valtyp != CONSTANT || cnstnt)
asmlin("CMP", term); //Emit Comparison
if (look(',')) {
chklbl(skplbl); //Emit skip to beginning of CASE block
@ -400,8 +362,7 @@ void pcase(void) {
asmlin("BNE", cndlbl);
break;
}
if (skplbl[0])
setlbl(skplbl); //Set CASE block label if defined
if (skplbl[0]) setlbl(skplbl); //Set CASE block label if defined
fcase = FALSE;
}
@ -418,8 +379,6 @@ void pwhile(void) {
newlbl(endlbl); //Create End Label
pshlbl(LTEND, endlbl); //and Push onto Stack
reqlbl(loplbl); //Get or Create/Set Loop Label
//newlbl(loplbl); //create Loop Label
//setlbl(loplbl); //Set to Emit on Next Line
pshlbl(LTLOOP, loplbl); //Push onto Stack
if (!look(')')) {
newlbl(cndlbl); //Create Conditional Skip Label
@ -446,10 +405,8 @@ void prsfns(void) {
void prssym(void) {
DEBUG("Parsing Identifier %s\n", word)
valtyp = gettyp();
if (valtyp == FUNCTION)
prsfns(); //Parse Statement Function Call
else
prcvar(';'); //Parse Assignment
if (valtyp == FUNCTION) prsfns(); //Parse Statement Function Call
else prcvar(';'); //Parse Assignment
}
/* parse and compile program statement */
@ -494,9 +451,8 @@ void pstmnt(void) {
prslbl(); //Parse Label
return;
}
if (wordis("ASM"))
pasm();
else if (wordis("BREAK"))
if (wordis("ASM")) pasm();
else if (wordis("BREAK"))
pbrcnt(LFEND);
else if (wordis("CONTINUE"))
pbrcnt(LFBGN);

View File

@ -32,7 +32,7 @@ int fndvar(char *name) {
* name - variable name */
void chksym(int alwreg, char *name) {
if (strlen(name) == 1 && strchr("AXY", name[0])) {
if (alwreg && valtyp != ARRAY) {
if (alwreg && valtyp != ARRAY) {
valtyp = REGISTER;
return;
}
@ -59,9 +59,7 @@ void prsvar(int alwreg) {
* Sets: vrname - operand for LDA/STA/LDY/STY */
void reqvar(int alwary) {
prsvar(FALSE);
if (!alwary)
if (valtyp != VARIABLE)
expctd("Variable");
if (!alwary && valtyp != VARIABLE) expctd("Variable");
}
/* Parse Data Array */
@ -69,12 +67,10 @@ void prsdta(void) {
dtype = DTARRY;
expect('{');
dlen = 0;
while (TRUE) {
do {
prscon();
dattmp[dlen++] = cnstnt;
if (!look(','))
break;
}
} while (look(','));
expect('}');
}
@ -99,14 +95,12 @@ void setdat(void) {
}
else if (dtype == DTARRY) {
DEBUG("Setting variable data to array of length %d\n", dlen)
for (i=0; i<dlen; i++)
datvar[dsize++] = dattmp[i];
for (i=0; i<dlen; i++) datvar[dsize++] = dattmp[i];
}
else {
DEBUG("Setting variable data to '%s'\n", value)
dlen = strlen(value);
for (i=0; i<dlen; i++)
datvar[dsize++] = value[i];
for (i=0; i<dlen; i++) datvar[dsize++] = value[i];
}
datlen[varcnt] = dlen;
dattyp[varcnt] = dtype;
@ -116,21 +110,12 @@ void setdat(void) {
/* Parse and store variable data */
void prsdat(void) {
DEBUG("Checking for variable data\n", 0)
if (!look('=')) {
datlen[varcnt] = 0;
return;
}
if (!look('=')) { datlen[varcnt] = 0; return; }
skpspc();
if (iscpre()) {
dtype = DTBYTE;
prscon(); //Parse Data Constant
}
else if (match('"'))
prsdts(); //Parse Data String
else if (match('{'))
prsdta(); //Parse Data Array
else
expctd("numeric or string constant");
if (iscpre()) {dtype = DTBYTE; prscon(); }//Parse Data Constant
else if (match('"')) prsdts(); //Parse Data String
else if (match('{')) prsdta(); //Parse Data Array
else expctd("numeric or string constant");
setdat(); //Store Data Value
}
@ -150,10 +135,8 @@ void setvar(int m, int t) {
* Uses: word - variable name */
void addvar(int m, int t) {
strcpy(vrname, word); //Save Variable Name
if (fndvar(vrname))
ERROR("Duplicate declaration of variable '%s\n", word,EXIT_FAILURE)
if (t == VTVOID)
ERROR("Illegal Variable Type\n", 0, EXIT_FAILURE)
if (fndvar(vrname)) ERROR("Duplicate declaration of variable '%s\n", word,EXIT_FAILURE)
if (t == VTVOID) ERROR("Illegal Variable Type\n", 0, EXIT_FAILURE)
if (m == MTZP) {
setlbl(vrname);
sprintf(word, "$%hhX", zpaddr++);
@ -174,8 +157,7 @@ void addvar(int m, int t) {
if (!alcvar) strcpy(value, "*");
setvar(m, t); //Add to Variable Table
}
if (m != MTZP)
prsdat(); //Parse Variable Data
if (m != MTZP) prsdat(); //Parse Variable Data
varcnt++; //Increment Variable Counter
}
@ -190,10 +172,9 @@ void vartbl(void) {
fprintf(logfil, "%-31s %4d %4s %1d-%d\n", varnam[i], vartyp[i], varsiz[i], dattyp[i], datlen[i]);
strcpy(lblasm, varnam[i]);
DEBUG("Set Label to '%s'\n", lblasm)
if (strcmp(varsiz[i], "*") == 0)
continue;
if (strcmp(varsiz[i], "*") == 0) continue;
if (varmod[i] == MTALGN) {
DEBUG("Alligning variable '%s'\n", varnam[i])
DEBUG("Aligning variable '%s'\n", varnam[i])
asmlin(ALNOP, "256");
}
if (datlen[i]) {