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:
parent
2126642205
commit
cf8264f99a
@ -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("");
|
||||
}
|
||||
|
||||
|
12
src/common.c
12
src/common.c
@ -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) {
|
||||
|
71
src/cond.c
71
src/cond.c
@ -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);
|
||||
}
|
||||
|
48
src/dclrtn.c
48
src/dclrtn.c
@ -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;
|
||||
}
|
||||
|
123
src/expr.c
123
src/expr.c
@ -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
|
||||
|
23
src/files.c
23
src/files.c
@ -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); }
|
||||
|
45
src/label.c
45
src/label.c
@ -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;
|
||||
}
|
||||
|
||||
|
137
src/parse.c
137
src/parse.c
@ -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;
|
||||
}
|
||||
|
152
src/stmnt.c
152
src/stmnt.c
@ -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);
|
||||
|
51
src/vars.c
51
src/vars.c
@ -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]) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user