1
0
mirror of https://github.com/RevCurtisP/C02.git synced 2024-06-08 06:29:32 +00:00

Implemented do, while, and for

This commit is contained in:
Curtis F Kaylor 2017-04-30 21:17:50 -04:00
parent 1abb077f09
commit 772c841052
14 changed files with 465 additions and 220 deletions

16
c02.c
View File

@ -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();
}

View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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);

View File

@ -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
View File

@ -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
}
}

View File

@ -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
View File

@ -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
View File

@ -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