mirror of
https://github.com/RevCurtisP/C02.git
synced 2024-11-25 06:31:25 +00:00
Implemented do, while, and for
This commit is contained in:
parent
1abb077f09
commit
772c841052
16
c02.c
16
c02.c
@ -37,6 +37,7 @@ void init()
|
||||
inpfil = srcfil;
|
||||
strcpy(inpnam, srcnam);
|
||||
alcvar = TRUE;
|
||||
inblck = FALSE;
|
||||
nxtwrd[0] = 0;
|
||||
nxtptr = 0;
|
||||
}
|
||||
@ -45,7 +46,7 @@ void init()
|
||||
pword()
|
||||
{
|
||||
getwrd();
|
||||
SCMNT(word);
|
||||
ACMNT(word);
|
||||
DEBUG("Parsing Word '%s'\n", word);
|
||||
if (wordis("byte"))
|
||||
pdecl(VTBYTE); //Parse 'byte' declaration
|
||||
@ -88,17 +89,16 @@ void compile()
|
||||
//DEBUG("Checking next character '%c'\n", nxtchr);
|
||||
if (match(EOF))
|
||||
break;
|
||||
else if (match('}'))
|
||||
endblk(TRUE); //End Multi-Line Program Block
|
||||
else if (match('#'))
|
||||
pdrctv(); //Process Directive
|
||||
pdrctv(); //Parse Directive
|
||||
else if (match('/'))
|
||||
skpcmt();
|
||||
skpcmt(); //Skip Comment
|
||||
else if (isalph())
|
||||
pword();
|
||||
pword(); //Parse Word
|
||||
else
|
||||
{
|
||||
printf("Unexpected character '%c'\n", nxtchr);
|
||||
exterr(EXIT_FAILURE);
|
||||
}
|
||||
ERROR("Unexpected character '%c'\n", nxtchr, EXIT_FAILURE);
|
||||
}
|
||||
epilog();
|
||||
}
|
||||
|
3
common.h
3
common.h
@ -8,7 +8,8 @@
|
||||
#define MAXDEF 255 //Maximum Number of Definitions
|
||||
#define VARLEN 6 //Maximum Variable Length
|
||||
#define MAXVAR 255 //Maximum Number of Variables
|
||||
#define DATASPC 2048 //Space to Allocate for
|
||||
#define MAXFNS 16 //Maximum Functions in Stack
|
||||
#define DATASPC 2048 //Space to Allocate for Variable Data
|
||||
#define LABLEN 6 //Maximum Label Length
|
||||
#define LABFMT "L_%04d" //Label Format
|
||||
#define LABSFX ":" //Label Suffix
|
||||
|
31
cond.c
31
cond.c
@ -41,16 +41,20 @@ int enccmp(char c)
|
||||
* Args: comparator - Encoded Comparison Operator *
|
||||
* Uses: term - Term Being Compared Against *
|
||||
* label - Branch Target if Comparison is FALSE */
|
||||
void prccmp(int cmprtr)
|
||||
void prccmp()
|
||||
{
|
||||
DEBUG("Processing comparison operator %d\n", cmprtr);
|
||||
DEBUG("Expression signedness is %d\n", expsgn);
|
||||
switch(cmprtr) {
|
||||
case 0: // Raw Expression (Skip)
|
||||
asmlin("BEQ", curlbl);
|
||||
break;
|
||||
case 1: // = or ==
|
||||
asmlin("CMP", term);
|
||||
asmlin("BNE", curlbl);
|
||||
break;
|
||||
case 2: // <
|
||||
if (cmpsgn) {
|
||||
if (expsgn) {
|
||||
asmlin("CMP", term);
|
||||
asmlin("BPL", curlbl);
|
||||
}
|
||||
@ -60,7 +64,7 @@ void prccmp(int cmprtr)
|
||||
}
|
||||
break;
|
||||
case 3: // <= or =<
|
||||
if (cmpsgn) {
|
||||
if (expsgn) {
|
||||
asmlin("CMP", term);
|
||||
asmlin("BPL", curlbl);
|
||||
asmlin("BNE", curlbl);
|
||||
@ -72,7 +76,7 @@ void prccmp(int cmprtr)
|
||||
}
|
||||
break;
|
||||
case 4: // >
|
||||
if (cmpsgn) {
|
||||
if (expsgn) {
|
||||
asmlin("CMP", term);
|
||||
asmlin("BMI", curlbl);
|
||||
asmlin("BEQ", curlbl);
|
||||
@ -84,7 +88,7 @@ void prccmp(int cmprtr)
|
||||
}
|
||||
break;
|
||||
case 5: // >= or =>
|
||||
if (cmpsgn) {
|
||||
if (expsgn) {
|
||||
asmlin("CMP", term);
|
||||
asmlin("BMI", curlbl);
|
||||
}
|
||||
@ -97,6 +101,9 @@ void prccmp(int cmprtr)
|
||||
asmlin("CMP", term);
|
||||
asmlin("BEQ", curlbl);
|
||||
break;
|
||||
case 7: // Raw Expression (Normal)
|
||||
asmlin("BNE", curlbl);
|
||||
break;
|
||||
default:
|
||||
printf("Unsupported comparison operator index %d\n", cmprtr);
|
||||
exterr(EXIT_FAILURE);
|
||||
@ -104,13 +111,13 @@ void prccmp(int cmprtr)
|
||||
}
|
||||
|
||||
/* Parse Comparison Operator *
|
||||
* Sets: comparitor - Encoded Comparison Operator */
|
||||
* Sets: cmprtr - Encoded Comparison Operator */
|
||||
int prscmp()
|
||||
{
|
||||
cmpenc = enccmp(nxtchr); //Encode Comparison Character
|
||||
if (cmpenc == 0)
|
||||
expctd("comparison operator");
|
||||
cmprtr = cmpenc; //Set Encoded Comparator
|
||||
if (cmprtr == 0) //No Comparison
|
||||
return;
|
||||
cmpenc = enccmp(nxtchr); //Encode Next Comparison Character
|
||||
if (cmpenc != 0)
|
||||
cmprtr = cmprtr | cmpenc; //Combine Encoded Comparator
|
||||
@ -120,15 +127,17 @@ int prscmp()
|
||||
|
||||
/* Parse and Compile Conditional Expression *
|
||||
* Condition = <expression> <comparator> <term> */
|
||||
void prscnd(char trmntr)
|
||||
void prscnd(char trmntr, int revrse)
|
||||
{
|
||||
DEBUG("Parsing condition\n", 0);
|
||||
prsxpr(0);
|
||||
skpspc();
|
||||
prscmp();
|
||||
prstrm();
|
||||
if (cmprtr)
|
||||
prstrm();
|
||||
cmprtr = cmprtr ^ revrse & 7;
|
||||
prccmp();
|
||||
CCMNT(trmntr);
|
||||
prccmp(cmprtr);
|
||||
expect(trmntr);
|
||||
}
|
||||
|
||||
|
2
cond.h
2
cond.h
@ -4,5 +4,5 @@
|
||||
|
||||
int cmpsgn; // Comparison contains signed operands
|
||||
|
||||
void prscnd(char trmntr); //Parse Conditional Expression
|
||||
void prscnd(char trmntr, int revrse); //Parse Conditional Expression
|
||||
|
||||
|
106
expr.c
106
expr.c
@ -11,8 +11,16 @@
|
||||
#include "asm.h"
|
||||
#include "parse.h"
|
||||
#include "vars.h"
|
||||
#include "label.h"
|
||||
#include "expr.h"
|
||||
|
||||
/* Set Expession Signedness */
|
||||
setsgn(int sgndns)
|
||||
{
|
||||
expsgn = sgndns;
|
||||
DEBUG("Set Expression Signedness to %d\n", expsgn);
|
||||
}
|
||||
|
||||
/* Parse value (constant or identifier) *
|
||||
* Sets: value - the value (as a string) *
|
||||
* valtyp - value type */
|
||||
@ -22,8 +30,11 @@ void prsval()
|
||||
//expdef(); //Check for and expand define -- BROKEN!
|
||||
if (iscpre())
|
||||
prscon(0xff); //Parse Constant
|
||||
else if (isalph())
|
||||
else if (isalph()) {
|
||||
prsvar(); //Parse Variable
|
||||
DEBUG("Checking type of variable '%s'\n", value);
|
||||
if (vartyp[lookup(value)] == VTBYTE) setsgn(TRUE);
|
||||
}
|
||||
else
|
||||
expctd("constant or variable");
|
||||
skpspc();
|
||||
@ -41,7 +52,7 @@ void prsidx()
|
||||
expect(']');
|
||||
}
|
||||
|
||||
/* Parse term in expression *
|
||||
/* Parse term in expression *
|
||||
* Sets: term - the term (as a string) *
|
||||
* trmtxt - type of term */
|
||||
void prstrm()
|
||||
@ -62,39 +73,80 @@ void prstrm()
|
||||
skpspc();
|
||||
}
|
||||
|
||||
/* Parse and Compile Pointer Dereference */
|
||||
void prsadr(char dlmtr)
|
||||
/* Compile Address Reference */
|
||||
void prcadr(char* symbol)
|
||||
{
|
||||
prsvar();
|
||||
DEBUG("Dereferencing variable '%s'\n", value);
|
||||
ACMNT(value);
|
||||
strcpy(word,"#<");
|
||||
strcat(word,value);
|
||||
strcat(word,symbol);
|
||||
asmlin("LDX", word);
|
||||
strcpy(word,"#>");
|
||||
strcat(word,value);
|
||||
strcat(word,symbol);
|
||||
asmlin("LDY", word);
|
||||
if (dlmtr) expect(dlmtr);
|
||||
}
|
||||
|
||||
/* Parse and Compile Address of Operator */
|
||||
void prsadr()
|
||||
{
|
||||
prsvar();
|
||||
DEBUG("Parsing address of variable '%s'\n", value);
|
||||
ACMNT(value);
|
||||
prcadr(value); //Compile Address Reference
|
||||
}
|
||||
|
||||
|
||||
/* Parse function call in first term of expression *
|
||||
* Function call may include term as an argument */
|
||||
void prsxfn()
|
||||
/* Parse and Create Anonymous String */
|
||||
void prsstr()
|
||||
{
|
||||
char fnname[255]; /*Function name*/
|
||||
DEBUG("Processing expression function call '%s'...\n", term);
|
||||
strcpy(fnname, term);
|
||||
DEBUG("Parsing anonymous string\n", 0);
|
||||
strcpy(tmplbl, curlbl);//Save Current Label
|
||||
newlbl(); //Generate Label Name
|
||||
strcpy(word, curlbl); //and Use as Variable Name
|
||||
value[0] = 0; //Use Variable Size 0
|
||||
setvar(VTCHAR); //Set Variable Name, Type, and Size
|
||||
prsdts(); //Parse Data String
|
||||
setdat(); //Set Variable Data
|
||||
varcnt++; //Increment Variable Counter
|
||||
prcadr(curlbl); //Compile Address Reference
|
||||
strcpy(curlbl, tmplbl);//Restore Current Label
|
||||
}
|
||||
|
||||
/* Parse Additional Function Parameters */
|
||||
void prsfnp()
|
||||
{
|
||||
if (look(',')) {
|
||||
if (look('&'))
|
||||
prsadr();
|
||||
else if (match('"'))
|
||||
prsstr();
|
||||
else {
|
||||
prstrm();
|
||||
asmlin("LDY", term);
|
||||
if (look(',')) {
|
||||
prsval();
|
||||
asmlin("LDX", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse function call */
|
||||
void prsfnc()
|
||||
{
|
||||
DEBUG("Processing Function Call '%s'...\n", term);
|
||||
if (fnscnt >= MAXFNS)
|
||||
ERROR("Maximum Function Call Depth Exceeded", 0, EXIT_FAILURE);
|
||||
strcpy(fnstck[fnscnt++], term);
|
||||
skpchr(); //skip open paren
|
||||
CCMNT('(');
|
||||
if (look('&'))
|
||||
prsadr(0);
|
||||
prsadr();
|
||||
else if (match('"'))
|
||||
prsstr();
|
||||
else if (isvpre()) {
|
||||
prstrm();
|
||||
asmlin("LDA", term);
|
||||
}
|
||||
prsxpr(0);
|
||||
prsfnp();
|
||||
}
|
||||
expect(')');
|
||||
asmlin("JSR", fnname);
|
||||
asmlin("JSR", fnstck[--fnscnt]);
|
||||
skpspc();
|
||||
}
|
||||
|
||||
@ -107,7 +159,7 @@ void prsftm()
|
||||
strcpy(term, value);
|
||||
trmtxt = valtyp;
|
||||
if (trmtxt == FUNCTION) {
|
||||
prsxfn(); //Parse Expression Function
|
||||
prsfnc(); //Parse Expression Function
|
||||
return;
|
||||
}
|
||||
if (trmtxt == ARRAY) {
|
||||
@ -153,8 +205,12 @@ void prsxpr(char trmntr)
|
||||
{
|
||||
DEBUG("Parsing expression\n", 0);
|
||||
skpspc();
|
||||
if (match('-'))
|
||||
asmlin("LDA", "#$00"); //Handle Unary Minus
|
||||
setsgn(FALSE); //Default Expression to Unsigned
|
||||
if (match('-')) {
|
||||
DEBUG("Processing unary minus", 0);
|
||||
asmlin("LDA", "#$00"); //Handle Unary Minus
|
||||
setsgn(TRUE); //Expression is Signed
|
||||
}
|
||||
else
|
||||
prsftm(); //Parse First Term
|
||||
while (isoper())
|
||||
|
6
expr.h
6
expr.h
@ -5,7 +5,13 @@
|
||||
char term[255]; /*Term parsed from equation*/
|
||||
int trmtxt; /*Term Type*/
|
||||
|
||||
int expsgn; //Expression Contains Signed Term
|
||||
|
||||
char fnstck[MAXFNS][VARLEN+1]; //Function Call Stack
|
||||
int fnscnt; //Number of Functions in Stack
|
||||
|
||||
void prsidx(); //Parse Array Index
|
||||
void prstrm(); //Parse Term in Expression
|
||||
void prsxpr(char trmntr); //Parse Expression
|
||||
|
||||
|
||||
|
59
label.c
59
label.c
@ -13,6 +13,29 @@
|
||||
#include "parse.h"
|
||||
#include "label.h"
|
||||
|
||||
/* Find Last Label of Specified Type *
|
||||
* Args: lbtype: Label type *
|
||||
* Sets: tmplbl - Label name *
|
||||
* Returns: Index into label table *
|
||||
* (-1 if not found) */
|
||||
int lstlbl(int lbtype)
|
||||
{
|
||||
int i;
|
||||
DEBUG("Searching for label type %d\n", lbtype);
|
||||
for (i = lblcnt - 1; i>-1; i--)
|
||||
if (lbltyp[i] == lbtype) break;
|
||||
DEBUG("Search produced label index %d\n", i);
|
||||
if (i>=0)
|
||||
strcpy(tmplbl, lblnam[i]);
|
||||
return i;
|
||||
}
|
||||
|
||||
/* Set Block Flag for Last Label */
|
||||
void setblk(int blkflg)
|
||||
{
|
||||
lblblk[lblcnt-1] = blkflg;
|
||||
}
|
||||
|
||||
/* Set label for next line of *
|
||||
* Assembly Language Code *
|
||||
* to word */
|
||||
@ -21,8 +44,8 @@ void setlbl(char *lblset)
|
||||
DEBUG("Setting Label '%s''\n", lblset);
|
||||
if (strlen(lblasm) > 0)
|
||||
asmlin("",""); //Emit Block End Label on it's own line
|
||||
if (strlen(word) > LABLEN)
|
||||
ERROR("Label '%s' exceeds maximum size", word, EXIT_FAILURE);
|
||||
if (strlen(lblset) > LABLEN)
|
||||
ERROR("Label '%s' exceeds maximum size\n", word, EXIT_FAILURE);
|
||||
strcpy(lblasm, lblset);
|
||||
}
|
||||
|
||||
@ -35,27 +58,35 @@ void prslbl()
|
||||
}
|
||||
|
||||
/* generate new label */
|
||||
void newlbl(int lbtype)
|
||||
void newlbl()
|
||||
{
|
||||
sprintf(curlbl, LABFMT, lblnxt++);
|
||||
DEBUG("Generated new label '%s'\n", curlbl);
|
||||
strcpy(lblnam[lblcnt++], curlbl);
|
||||
lbltyp[lblcnt] = lbtype;
|
||||
}
|
||||
|
||||
/* set label to emit on next line and remove from stack */
|
||||
void lbllin()
|
||||
/* Pop Label from Stack and Emit on Next Line */
|
||||
int poplbl()
|
||||
{
|
||||
int lbtype = lbltyp[--lblcnt];
|
||||
if (lbtype == 1) {
|
||||
DEBUG("Ending Loop at Level %d'\n", lblcnt);
|
||||
strcpy(endlbl, lblnam[lblcnt]); //Save End of Loop Label
|
||||
asmlin("JMP", lblnam[--lblcnt]); //Jump to Beginning of Loop
|
||||
setlbl(endlbl); //Set End of Loop Label
|
||||
}
|
||||
DEBUG("Popped label type %d\n", lbtype);
|
||||
if (lbtype == LTLOOP)
|
||||
asmlin("JMP", lblnam[lblcnt--]); //Jump to Beginning of Loop
|
||||
if (lbtype == LTDO)
|
||||
strcpy(loplbl, lblnam[lblcnt]);
|
||||
else
|
||||
setlbl(lblnam[lblcnt]);
|
||||
DEBUG("Set label '%s' to emit on next line\n", lblasm);
|
||||
inblck = lblblk[lblcnt-1];
|
||||
return lbtype;
|
||||
}
|
||||
|
||||
/* Push Label onto Stack *
|
||||
* Args: lbltyp - Label type *
|
||||
* Uses: curlbl - Label to push */
|
||||
void pshlbl(int lbtype)
|
||||
{
|
||||
strcpy(lblnam[lblcnt], curlbl);
|
||||
lbltyp[lblcnt] = lbtype;
|
||||
lblblk[lblcnt++] = FALSE;
|
||||
DEBUG("Pushed label '%s' onto stack\n", curlbl);
|
||||
}
|
||||
|
||||
|
19
label.h
19
label.h
@ -2,18 +2,25 @@
|
||||
* C02 Label Parsing, Generation, and Lookup Routines *
|
||||
******************************************************/
|
||||
|
||||
int inblck; //Multiline Block Flag
|
||||
|
||||
char curlbl[LABLEN+1]; //Most recently generated label
|
||||
char endlbl[LABLEN+1]; //Label at end of block
|
||||
char endlbl[LABLEN+1]; //End Label
|
||||
char loplbl[LABLEN+1]; //Skip Increment Label
|
||||
char skplbl[LABLEN+1]; //Skip Increment Label
|
||||
char tmplbl[LABLEN+1]; //Temporary Label
|
||||
char lblnam[MAXLAB+1][LABLEN+1]; //Label Name Table
|
||||
int lbltyp[MAXLAB+1]; //Label Type
|
||||
int lblblk[MAXLAB+1]; //Label Ends Program Block
|
||||
int lblcnt; //Number of Labels in stack
|
||||
int lblnxt; //Sequence of next label to be generated
|
||||
char lbltmp[LABLEN+1]; //Label Temporary Storage
|
||||
|
||||
enum ltypes {LTIF, LTLOOP, LTEND}; //Label Types
|
||||
enum ltypes {LTIF, LTLOOP, LTEND, LTDO}; //Label Types
|
||||
|
||||
void prslbl(); //Parse Label From Code
|
||||
void newlbl(); //Generate New Block Label
|
||||
void lbllin(); //Pull Last Label and Emit on Next Line
|
||||
void setlbl(); //Emit word as Label on Next Line
|
||||
int lstlbl(int lbtype); //Find Last Label of Specified Type
|
||||
void prslbl(); //Parse Label From Code
|
||||
void newlbl(); //Generate New Block Label
|
||||
int poplbl(); //Pull Last Label and Emit on Next Line
|
||||
void setlbl(); //Emit word as Label on Next Line
|
||||
|
||||
|
55
parse.c
55
parse.c
@ -15,22 +15,22 @@
|
||||
char opstr[2]; //Operator as a String
|
||||
|
||||
/* Various tests against nxtchr */
|
||||
int match(char c) {return (nxtchr == c);}
|
||||
int inbtwn(char mn, char mx) {return nxtchr >= mn && nxtchr <= mx;}
|
||||
int match(char c) {return TF(nxtchr == c);}
|
||||
int inbtwn(char mn, char mx) {return TF(nxtchr >= mn && nxtchr <= mx);}
|
||||
int isprnt() {return isprint(nxtchr);}
|
||||
int isalph() {return isalpha(nxtchr);}
|
||||
int isanum() {return isalnum(nxtchr);}
|
||||
int isdec() {return inbtwn('0', '9');}
|
||||
int ishexd() {return isdec() || inbtwn('A', 'Z');}
|
||||
int ishexd() {return TF(isdec() || inbtwn('A', 'Z'));}
|
||||
int isbin() {return inbtwn('0', '1');}
|
||||
int isnl() {return match('\n') || match('\r');}
|
||||
int isnl() {return TF(match('\n') || match('\r'));}
|
||||
int isspc() {return isspace(nxtchr);}
|
||||
int isnpre() {return isdec() || match('$') || match('%');}
|
||||
int isnpre() {return TF(isdec() || match('$') || match('%'));}
|
||||
int isapos() {return match('\'');}
|
||||
int iscpre() {return isnpre() || isapos();}
|
||||
int isvpre() {return isalph() || iscpre();}
|
||||
int isoper() {return (strchr("+-&|^", nxtchr)) ? TRUE : FALSE;}
|
||||
int ispopr() {return (strchr("+-<>", nxtchr)) ? TRUE : FALSE;}
|
||||
int iscpre() {return TF(isnpre() || isapos());}
|
||||
int isvpre() {return TF(isalph() || iscpre());}
|
||||
int isoper() {return TF(strchr("+-&|^", nxtchr));}
|
||||
int ispopr() {return TF(strchr("+-<>", nxtchr));}
|
||||
|
||||
/* if Word is s then return TRUE else return FALSE*/
|
||||
int wordis(char *s)
|
||||
@ -182,29 +182,37 @@ void expdef()
|
||||
|
||||
char escape(char c)
|
||||
{
|
||||
DEBUG("Escaping character '%c'\n", c);
|
||||
switch (c) {
|
||||
case 'r': return 0x0d;
|
||||
default: return c;
|
||||
}
|
||||
}
|
||||
|
||||
void get_string() {
|
||||
char str_del, tmp_char;
|
||||
int wrdlen = 0, esc_next = FALSE;
|
||||
/* Get String */
|
||||
|
||||
void getstr() {
|
||||
char strdel, tmpchr;
|
||||
int wrdlen = 0, escnxt = FALSE;
|
||||
DEBUG("Parsing string\n", 0);
|
||||
str_del = getnxt();
|
||||
while(!match(str_del)) {
|
||||
if (esc_next)
|
||||
strdel = getnxt(); //Get String Delimiter
|
||||
CCMNT(strdel);
|
||||
while(match(strdel) == escnxt) {
|
||||
CCMNT(nxtchr);
|
||||
if (escnxt) {
|
||||
word[wrdlen++] = escape(getnxt());
|
||||
escnxt = FALSE;
|
||||
}
|
||||
else {
|
||||
if (match('\\'))
|
||||
esc_next = TRUE;
|
||||
escnxt = TRUE;
|
||||
else
|
||||
word[wrdlen++] = nxtchr;
|
||||
skpchr();
|
||||
}
|
||||
}
|
||||
skpchr();
|
||||
skpchr(); //Skip End Delimiter
|
||||
CCMNT(strdel);
|
||||
word[wrdlen++] = 0;
|
||||
}
|
||||
|
||||
@ -343,15 +351,18 @@ int prsnum(int maxval)
|
||||
* valtyp - value type (CONSTANT) */
|
||||
void prscon(int maxval)
|
||||
{
|
||||
int constant = prsnum(maxval);
|
||||
cnstnt = prsnum(maxval);
|
||||
valtyp = CONSTANT;
|
||||
if (maxval > 255)
|
||||
sprintf(value, "#$%04X", constant);
|
||||
sprintf(value, "#$%04X", cnstnt);
|
||||
else
|
||||
sprintf(value, "#$%02X", constant);
|
||||
sprintf(value, "#$%02X", cnstnt);
|
||||
DEBUG("Generated constant '%s'\n", value);
|
||||
}
|
||||
int get_vartyp()
|
||||
|
||||
|
||||
/* Get Value Type */
|
||||
int gettyp()
|
||||
{
|
||||
if (match('(')) return FUNCTION;
|
||||
else if (match('[')) return ARRAY;
|
||||
@ -364,7 +375,7 @@ int get_vartyp()
|
||||
void prsvar()
|
||||
{
|
||||
getwrd();
|
||||
valtyp = get_vartyp();
|
||||
valtyp = gettyp();
|
||||
if (valtyp != FUNCTION) chksym(word);
|
||||
strcpy(value, word);
|
||||
DEBUG("Parsed variable '%s'\n", value);
|
||||
|
3
parse.h
3
parse.h
@ -2,6 +2,8 @@
|
||||
* C02 Input File Parsing Routines *
|
||||
*************************************/
|
||||
|
||||
#define TF(x) (x) ? TRUE : FALSE;
|
||||
|
||||
enum trmtxts {CONSTANT, VARIABLE, ARRAY, FUNCTION};
|
||||
enum etypes {ETDEF, ETMAC}; //Definition Types
|
||||
|
||||
@ -11,6 +13,7 @@ int nxtptr; //Pointer to next character in nxtwrd
|
||||
char value[LINELEN]; //Term parsed from equation
|
||||
int valtyp; //Value Type
|
||||
char oper; //Arithmetic or Bitwise Operator
|
||||
int cnstnt; //Value of Parsed Constant
|
||||
|
||||
char defnam[MAXDEF+1][VARLEN+1]; //Definition Name Table
|
||||
char deftxt[MAXDEF+1][DEFLEN+1]; //Definition Text Table
|
||||
|
300
stmnt.c
300
stmnt.c
@ -11,73 +11,17 @@
|
||||
#include "asm.h"
|
||||
#include "parse.h"
|
||||
#include "vars.h"
|
||||
#include "expr.h"
|
||||
#include "label.h"
|
||||
#include "expr.h"
|
||||
#include "stmnt.h"
|
||||
|
||||
/* parse and compile if statement */
|
||||
void pif() {
|
||||
DEBUG("Parsing IF statement '%c'\n", nxtchr);
|
||||
expect('(');
|
||||
newlbl(LTIF);
|
||||
prscnd(')'); //Parse Conditional Expession
|
||||
}
|
||||
|
||||
/* parse and compile else statement */
|
||||
void pelse() {
|
||||
DEBUG("Parsing ELSE statement '%c'\n", nxtchr);
|
||||
strcpy(lbltmp, lblasm);
|
||||
lblasm[0] = 0;
|
||||
newlbl(LTIF);
|
||||
asmlin("JMP", curlbl);
|
||||
strcpy(lblasm, lbltmp);
|
||||
}
|
||||
|
||||
/* parse and compile for statement */
|
||||
void pfor() {
|
||||
ERROR("Unsupported statement FOR encountered",0, EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* parse and compile if statement */
|
||||
void pgoto() {
|
||||
DEBUG("Parsing GOTO statement\n", 0);
|
||||
getwrd();
|
||||
ACMNT(word);
|
||||
asmlin("JMP", word);
|
||||
expect(';');
|
||||
}
|
||||
|
||||
/* parse and compile if statement */
|
||||
void pretrn() {
|
||||
DEBUG("Parsing RETURN statement\n", 0);
|
||||
if (!look(';'))
|
||||
prsxpr(';');
|
||||
asmlin("RTS", "");
|
||||
}
|
||||
|
||||
/* parse and compile while statement */
|
||||
void pwhile() {
|
||||
DEBUG("Parsing WHILE statement '%c'\n", nxtchr);
|
||||
expect('(');
|
||||
newlbl(LTLOOP); //create Loop Label
|
||||
setlbl(curlbl);
|
||||
newlbl(LTEND); //Create End Label
|
||||
prscnd(')'); //Parse Conditional Expession
|
||||
}
|
||||
|
||||
/* generate unimplemented statement error */
|
||||
void punimp() {
|
||||
ERROR("Unimplemented statement '%s' encountered", word, EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
/* Parse and compile assignment */
|
||||
void prsasn()
|
||||
/* Process Assignment */
|
||||
void prcasn(char trmntr)
|
||||
{
|
||||
DEBUG("Parsing assignment of variable '%s''\n", asnvar);
|
||||
skpchr(); //skip equals sign
|
||||
ACMNT("=");
|
||||
prsxpr(';');
|
||||
DEBUG("Processing assignment of variable '%s'\n", asnvar);
|
||||
expect('=');
|
||||
prsxpr(trmntr);
|
||||
if (strlen(asnidx)) {
|
||||
asmlin("LDX", asnidx);
|
||||
strcat(asnvar,",X");
|
||||
@ -108,50 +52,22 @@ void prcpop() {
|
||||
}
|
||||
|
||||
/* Parse Post Operator */
|
||||
void prspop() {
|
||||
void prspop(char trmntr) {
|
||||
oper = getnxt();
|
||||
CCMNT(oper); CCMNT(oper);
|
||||
DEBUG("Checking for post operation '%c'\n", oper);
|
||||
if (nxtchr == oper) {
|
||||
skpchr();
|
||||
prcpop(); //Process Post-Op
|
||||
expect(';');
|
||||
expect(trmntr);
|
||||
}
|
||||
else
|
||||
expctd("post operator");
|
||||
}
|
||||
|
||||
/* Parse function call in first expression */
|
||||
void prsfnc()
|
||||
/* Process Variable at Beginning of Statement */
|
||||
void prcvar(char trmntr)
|
||||
{
|
||||
char fnname[255]; /*Function name*/
|
||||
DEBUG("Processing function call '%s'...\n", term);
|
||||
strcpy(fnname, word);
|
||||
skpchr(); //skip open paren
|
||||
CCMNT('(');
|
||||
skpspc();
|
||||
if (match(')')) //if no arguments
|
||||
skpchr(); // skip close paren
|
||||
else { //otherwise
|
||||
if (look('&')) {
|
||||
prsadr(')');
|
||||
}
|
||||
else
|
||||
prsxpr(')'); //parse expression
|
||||
}
|
||||
asmlin("JSR", fnname);
|
||||
expect(';');
|
||||
}
|
||||
|
||||
/* parse and compile identifier (variable or function call) */
|
||||
void prssym()
|
||||
{
|
||||
DEBUG("Parsing Identifier %s\n", word);
|
||||
valtyp = get_vartyp();
|
||||
if (valtyp == FUNCTION) {
|
||||
prsfnc(); //Parse Function Call
|
||||
return;
|
||||
}
|
||||
chksym(word);
|
||||
strcpy(asnvar, word); //sav variable to assign to
|
||||
if (valtyp == ARRAY) {
|
||||
@ -161,15 +77,180 @@ void prssym()
|
||||
else
|
||||
asnidx[0] = 0;
|
||||
if (ispopr(nxtchr))
|
||||
prspop(); //Parse Post Operator
|
||||
prspop(trmntr); //Parse Post Operator
|
||||
else
|
||||
{
|
||||
skpspc();
|
||||
if (match('='))
|
||||
prsasn(); //Parse Assignment
|
||||
else
|
||||
expctd("=");
|
||||
}
|
||||
prcasn(trmntr);
|
||||
}
|
||||
|
||||
/* Begin Program Block */
|
||||
void bgnblk()
|
||||
{
|
||||
DEBUG("Begining program block\n", 0);
|
||||
inblck = look('{');
|
||||
setblk(inblck);
|
||||
}
|
||||
|
||||
/* Parse and Compile and Assignment */
|
||||
void prsasn(char trmntr)
|
||||
{
|
||||
getwrd(); //Get Variable to be Assigned
|
||||
ACMNT(word);
|
||||
prcvar(trmntr);
|
||||
}
|
||||
|
||||
/* parse and compile 'break'/'continue' statement */
|
||||
void pbrcnt(int lbtype) {
|
||||
DEBUG("Parsing BREAK/CONTINUE statement\n", 0);
|
||||
if (lstlbl(lbtype) < 0)
|
||||
ERROR("Break/continue statement outside of loop\n", 0, EXIT_FAILURE);
|
||||
DEBUG("Found Label '%s'\n", tmplbl);
|
||||
asmlin("JMP", tmplbl);
|
||||
expect(';');
|
||||
}
|
||||
|
||||
/* parse and compile 'do' statement */
|
||||
void pdo() {
|
||||
DEBUG("Parsing DO statement '%c'\n", nxtchr);
|
||||
newlbl(); //Create Do Loop Label
|
||||
pshlbl(LTDO); //Push onto Stack
|
||||
setlbl(curlbl); //Set Label to Emit on Next Line
|
||||
bgnblk(); //Check For and Begin Block
|
||||
}
|
||||
|
||||
/* parse and compile 'while' after 'do' statement */
|
||||
void pdowhl() {
|
||||
DEBUG("Parsing WHILE after DO '%c'\n", nxtchr);
|
||||
getwrd(); //Check for While
|
||||
ACMNT(word);
|
||||
if (!wordis("while"))
|
||||
expctd("while statement");
|
||||
expect('(');
|
||||
newlbl(); //Create Skip Label
|
||||
prscnd(')', FALSE); //Parse Conditional Expession
|
||||
asmlin("JMP", loplbl); //Emit Jump to Beginning of Loop
|
||||
setlbl(curlbl); //and Set Label to Emit on Next Line
|
||||
expect(';'); //Check for End of Statement
|
||||
}
|
||||
|
||||
|
||||
/* parse and compile for statement */
|
||||
void pfor() {
|
||||
DEBUG("Parsing FOR statement '%c'\n", nxtchr);
|
||||
expect('(');
|
||||
prsasn(';'); //Process Initial Assignment
|
||||
newlbl(); //Create Temporary Label
|
||||
setlbl(curlbl); //Set to Emit on Next Line
|
||||
strcpy(tmplbl, curlbl); //and Save it
|
||||
newlbl(); //Create End Label
|
||||
pshlbl(LTEND); //and Push onto Stack
|
||||
strcpy(endlbl, curlbl); //and Save it
|
||||
newlbl(); //Create Loop Label
|
||||
strcpy(loplbl, curlbl); //and Save it
|
||||
pshlbl(LTLOOP); //and Push onto Stack
|
||||
newlbl(); //Create Skip Increment Label
|
||||
strcpy(skplbl, curlbl); //and Save it
|
||||
prscnd(';', TRUE); //Parse Conditional Expession
|
||||
asmlin("JMP", endlbl); //Jump over Increment
|
||||
setlbl(loplbl); //Set to Emit on Next Line
|
||||
prsasn(')'); //Parse Increment Assignment
|
||||
asmlin("JMP", tmplbl); //Jump to Conditional
|
||||
setlbl(skplbl); //Emit Label at Start of Loop
|
||||
bgnblk(); //Check For and Begin Block
|
||||
}
|
||||
|
||||
/* parse and compile if statement */
|
||||
void pif() {
|
||||
DEBUG("Parsing IF statement '%c'\n", nxtchr);
|
||||
expect('(');
|
||||
newlbl(); //Create New Label
|
||||
pshlbl(LTIF); //Push Onto Stack
|
||||
prscnd(')', FALSE); //Parse Conditional Expession
|
||||
bgnblk(); //Check For and Begin Block
|
||||
}
|
||||
|
||||
/* parse and compile else statement */
|
||||
void pelse() {
|
||||
DEBUG("Parsing ELSE statement '%c'\n", nxtchr);
|
||||
strcpy(lbltmp, lblasm);
|
||||
lblasm[0] = 0;
|
||||
newlbl(); //Create New Label
|
||||
pshlbl(LTIF); //Push Onto Stack
|
||||
asmlin("JMP", curlbl);
|
||||
strcpy(lblasm, lbltmp);
|
||||
bgnblk(); //Check For and Begin Block
|
||||
}
|
||||
|
||||
/* parse and compile if statement */
|
||||
void pgoto() {
|
||||
DEBUG("Parsing GOTO statement\n", 0);
|
||||
getwrd();
|
||||
ACMNT(word);
|
||||
asmlin("JMP", word);
|
||||
expect(';');
|
||||
}
|
||||
|
||||
/* parse and compile if statement */
|
||||
void pretrn() {
|
||||
DEBUG("Parsing RETURN statement\n", 0);
|
||||
if (!look(';'))
|
||||
prsxpr(';');
|
||||
asmlin("RTS", "");
|
||||
}
|
||||
|
||||
/* parse and compile while statement */
|
||||
void pwhile() {
|
||||
DEBUG("Parsing WHILE statement '%c'\n", nxtchr);
|
||||
expect('(');
|
||||
newlbl(); //Create End Label
|
||||
pshlbl(LTEND); //Push onto Stack
|
||||
strcpy(endlbl, curlbl); //and Save it
|
||||
newlbl(); //create Loop Label
|
||||
setlbl(curlbl); //Set to Emit on Next Line
|
||||
pshlbl(LTLOOP); //Push onto Stack
|
||||
newlbl(); //Create Conditional Skip Label
|
||||
prscnd(')', TRUE); //Parse Conditional Expession
|
||||
asmlin("JMP", endlbl); //Emit Jump to End of Loop
|
||||
setlbl(curlbl); //and Set Label to Emit on Next Line
|
||||
bgnblk(); //Check For and Begin Block
|
||||
}
|
||||
|
||||
/* generate unimplemented statement error */
|
||||
void punimp() {
|
||||
ERROR("Unimplemented statement '%s' encountered\n", word, EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
/* Parse Function Call as Statement */
|
||||
void prsfns()
|
||||
{
|
||||
strcpy(term, word); //Copy Function Name
|
||||
prsfnc(); //Parse Function Call
|
||||
expect(';');
|
||||
return;
|
||||
}
|
||||
|
||||
/* parse and compile identifier (variable or function call) */
|
||||
void prssym()
|
||||
{
|
||||
DEBUG("Parsing Identifier %s\n", word);
|
||||
valtyp = gettyp();
|
||||
if (valtyp == FUNCTION)
|
||||
prsfns(); //Parse Statement Function Call
|
||||
else
|
||||
prcvar(';'); //Parse Assignment
|
||||
}
|
||||
|
||||
/* End Program Block *
|
||||
* Args: blkflg: End of Multiline Block */
|
||||
void endblk(int blkflg)
|
||||
{
|
||||
DEBUG("Ending program block with flag %d\n", blkflg);
|
||||
skpchr(); //Skip '}';
|
||||
DEBUG("Found inblck set to %d\n", inblck);
|
||||
if (inblck != blkflg)
|
||||
ERROR("Encountered '}' without matching '{'\n",0,EXIT_FAILURE);
|
||||
if (poplbl() == LTDO)
|
||||
pdowhl(); //Parse While at End of Do Loop
|
||||
}
|
||||
|
||||
/* parse and compile program statement */
|
||||
@ -180,6 +261,10 @@ void pstmnt()
|
||||
prslbl(); //Parse Label
|
||||
return;
|
||||
}
|
||||
if (wordis("do")) {
|
||||
pdo();
|
||||
return;
|
||||
}
|
||||
if (wordis("if")) {
|
||||
pif();
|
||||
return;
|
||||
@ -193,17 +278,22 @@ void pstmnt()
|
||||
return;
|
||||
}
|
||||
if (wordis("for")) {
|
||||
punimp();
|
||||
pfor();
|
||||
return;
|
||||
}
|
||||
else if (wordis("break"))
|
||||
pbrcnt(LTEND);
|
||||
else if (wordis("continue"))
|
||||
pbrcnt(LTLOOP);
|
||||
else if (wordis("goto"))
|
||||
pgoto();
|
||||
else if (wordis("return"))
|
||||
pretrn();
|
||||
else
|
||||
prssym();
|
||||
if (lblcnt) {
|
||||
lbllin();
|
||||
if (lblcnt && !inblck) {
|
||||
if (poplbl() == LTDO)
|
||||
pdowhl(); //Parse While at End of Do Loop
|
||||
}
|
||||
}
|
||||
|
||||
|
7
stmnt.h
7
stmnt.h
@ -2,7 +2,8 @@
|
||||
* C02 Statement Compiling Routines *
|
||||
************************************/
|
||||
|
||||
char asnvar[VARLEN+1]; /*Assigned Variable Name*/
|
||||
char asnidx[VARLEN+1] ; /*Assigned Variable Index*/
|
||||
|
||||
char asnvar[VARLEN+1]; //Assigned Variable Name
|
||||
char asnidx[VARLEN+1] ; //Assigned Variable Index
|
||||
|
||||
void endblk(); //End Program Block
|
||||
void pstmnt(); //Parse and Compile Program Statement
|
||||
|
69
vars.c
69
vars.c
@ -45,7 +45,6 @@ void chksym(char *name)
|
||||
ERROR("Undeclared variable '%s' encountered\n", word, EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
/* Check for Array specifier and get size *
|
||||
* Sets: value - array size (as string) *
|
||||
* "" if not an array */
|
||||
@ -76,36 +75,64 @@ void prsdtc()
|
||||
void prsdts()
|
||||
{
|
||||
dtype = DTSTR;
|
||||
get_string();
|
||||
getstr();
|
||||
strcpy(value, word);
|
||||
DEBUG("Parsed Data String '%s'\n", value);
|
||||
}
|
||||
|
||||
/* Parse and store variable data *
|
||||
/* Store variable data *
|
||||
* Uses: value - Data to store *
|
||||
* Sets: datvar[] - Variable Data *
|
||||
* datlen[] - Data Length */
|
||||
void setdat()
|
||||
{
|
||||
int i;
|
||||
if (dtype == DTBYTE) {
|
||||
DEBUG("Setting variable data to '%d'\n", cnstnt);
|
||||
dlen = 1;
|
||||
datvar[dsize++] = cnstnt;
|
||||
}
|
||||
else {
|
||||
DEBUG("Setting variable data to '%s'\n", value);
|
||||
dlen = strlen(value);
|
||||
for (i=0; i<dlen; i++)
|
||||
datvar[dsize++] = value[i];
|
||||
}
|
||||
datlen[varcnt] = dlen;
|
||||
dattyp[varcnt] = dtype;
|
||||
}
|
||||
|
||||
/* Parse and store variable data */
|
||||
void prsdat()
|
||||
{
|
||||
DEBUG("Checking for variable data\n", 0);
|
||||
int i;
|
||||
if (!look('=')) {
|
||||
datlen[varcnt] = 0;
|
||||
return;
|
||||
}
|
||||
skpspc();
|
||||
if (isnpre())
|
||||
prsdtc(0xff);
|
||||
prsdtc(0xff); //Parse Data Constant
|
||||
else if (match('"'))
|
||||
prsdts();
|
||||
dlen = strlen(value);
|
||||
datlen[varcnt] = dlen;
|
||||
dattyp[varcnt] = dtype;
|
||||
DEBUG("Setting variable data to '%s'\n", value);
|
||||
for (i=0; i<dlen; i++)
|
||||
datvar[dsize++] = value[i];
|
||||
prsdts(); //Parse Data String
|
||||
else
|
||||
expctd("numeric or string constant");
|
||||
setdat(); //Store Data Value
|
||||
}
|
||||
|
||||
/* Add Variable to Variable table *
|
||||
* Uses: word - variable name *
|
||||
* value - variable size */
|
||||
void setvar(int t)
|
||||
{
|
||||
DEBUG("Adding variable '%s'\n", word);
|
||||
strncpy(varnam[varcnt], word, VARLEN);
|
||||
vartyp[varcnt] = t;
|
||||
strncpy(varsiz[varcnt], value, 3);
|
||||
DEBUG("Added at index %d\n", varcnt);
|
||||
}
|
||||
|
||||
/* Parse and Compile Variable Declaration *
|
||||
* Uses: word - variable name */
|
||||
void addvar(int t)
|
||||
{
|
||||
@ -113,14 +140,10 @@ void addvar(int t)
|
||||
ERROR("Duplicate declaration of variable '%s\n", word,EXIT_FAILURE);
|
||||
if (t == VTVOID)
|
||||
ERROR("Illegal Variable Type\n", 0, EXIT_FAILURE);
|
||||
DEBUG("Adding variable '%s'\n", word);
|
||||
strncpy(varnam[varcnt], word, VARLEN);
|
||||
vartyp[varcnt] = t;
|
||||
pvarsz();
|
||||
strncpy(varsiz[varcnt], value, 3);
|
||||
DEBUG("Added at index %d\n", varcnt);
|
||||
prsdat(); //Parse Variable Data
|
||||
varcnt++;
|
||||
pvarsz(); //Check for Array Declaration and Get Size
|
||||
setvar(t); //Add to Variable Table
|
||||
prsdat(); //Parse Variable Data
|
||||
varcnt++; //Increment Variable Counter
|
||||
}
|
||||
|
||||
void addfnc()
|
||||
@ -155,7 +178,7 @@ void vardat(int i)
|
||||
value[0] = 0;
|
||||
for (j=0; j<datlen[i]; j++) {
|
||||
if (j) strcat(value,",");
|
||||
sprintf(word, "$%02X", datvar[dlen++]);
|
||||
sprintf(word, "$%hhX", datvar[dlen++]);
|
||||
strcat(value, word);
|
||||
}
|
||||
if (dattyp[i] == DTSTR) strcat(value, ",$00");
|
||||
@ -191,10 +214,10 @@ void vartbl()
|
||||
void logvar()
|
||||
{
|
||||
int i;
|
||||
fprintf(logfil, "\n%-31s %s %s\n", "Variable", "Type", "Size");
|
||||
fprintf(logfil, "\n%-31s %s %s %s\n", "Variable", "Type", "Size", "Data");
|
||||
for (i=0; i<varcnt; i++)
|
||||
{
|
||||
fprintf(logfil, "%-31s %4d %s\n", varnam[i], vartyp[i], varsiz[i]);
|
||||
fprintf(logfil, "%-31s %4d %4s %1d-%d\n", varnam[i], vartyp[i], varsiz[i], dattyp[i], datlen[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
9
vars.h
9
vars.h
@ -8,6 +8,10 @@ char vartyp[MAXVAR+1]; //Variable Type
|
||||
char varsiz[MAXVAR+1][4]; //Variable Array
|
||||
int varcnt; //Number of Variables in Table
|
||||
|
||||
/*
|
||||
int varidx; //Index into Variable Table
|
||||
int vrtype; //Variable Type
|
||||
*/
|
||||
enum vtypes {VTVOID, VTBYTE, VTCHAR}; //Variable Types
|
||||
|
||||
char datvar[DATASPC+1]; //Variable Data Storage
|
||||
@ -22,6 +26,9 @@ enum dtypes {DTBYTE, DTSTR}; //Variable Data Types
|
||||
int symdef(char *name); //Is Variable defined (TRUE or FALSE)
|
||||
void chksym(char *name); //Error if Variable not defined
|
||||
|
||||
void pdecl(int t); //Parse Variable Declaration
|
||||
void prsdts(); //Parse Data String
|
||||
void setdat(); //Set Variable Data
|
||||
void setvar(int t); //Set Variable Name and Size
|
||||
void pdecl(int t); //Parse Variable Declaration
|
||||
|
||||
void vartbl(); //Create Variable Table
|
||||
|
Loading…
Reference in New Issue
Block a user