1
0
mirror of https://github.com/RevCurtisP/C02.git synced 2024-11-29 01:49:19 +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; inpfil = srcfil;
strcpy(inpnam, srcnam); strcpy(inpnam, srcnam);
alcvar = TRUE; alcvar = TRUE;
inblck = FALSE;
nxtwrd[0] = 0; nxtwrd[0] = 0;
nxtptr = 0; nxtptr = 0;
} }
@ -45,7 +46,7 @@ void init()
pword() pword()
{ {
getwrd(); getwrd();
SCMNT(word); ACMNT(word);
DEBUG("Parsing Word '%s'\n", word); DEBUG("Parsing Word '%s'\n", word);
if (wordis("byte")) if (wordis("byte"))
pdecl(VTBYTE); //Parse 'byte' declaration pdecl(VTBYTE); //Parse 'byte' declaration
@ -88,17 +89,16 @@ void compile()
//DEBUG("Checking next character '%c'\n", nxtchr); //DEBUG("Checking next character '%c'\n", nxtchr);
if (match(EOF)) if (match(EOF))
break; break;
else if (match('}'))
endblk(TRUE); //End Multi-Line Program Block
else if (match('#')) else if (match('#'))
pdrctv(); //Process Directive pdrctv(); //Parse Directive
else if (match('/')) else if (match('/'))
skpcmt(); skpcmt(); //Skip Comment
else if (isalph()) else if (isalph())
pword(); pword(); //Parse Word
else else
{ ERROR("Unexpected character '%c'\n", nxtchr, EXIT_FAILURE);
printf("Unexpected character '%c'\n", nxtchr);
exterr(EXIT_FAILURE);
}
} }
epilog(); epilog();
} }

View File

@ -8,7 +8,8 @@
#define MAXDEF 255 //Maximum Number of Definitions #define MAXDEF 255 //Maximum Number of Definitions
#define VARLEN 6 //Maximum Variable Length #define VARLEN 6 //Maximum Variable Length
#define MAXVAR 255 //Maximum Number of Variables #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 LABLEN 6 //Maximum Label Length
#define LABFMT "L_%04d" //Label Format #define LABFMT "L_%04d" //Label Format
#define LABSFX ":" //Label Suffix #define LABSFX ":" //Label Suffix

31
cond.c
View File

@ -41,16 +41,20 @@ int enccmp(char c)
* Args: comparator - Encoded Comparison Operator * * Args: comparator - Encoded Comparison Operator *
* Uses: term - Term Being Compared Against * * Uses: term - Term Being Compared Against *
* label - Branch Target if Comparison is FALSE */ * label - Branch Target if Comparison is FALSE */
void prccmp(int cmprtr) void prccmp()
{ {
DEBUG("Processing comparison operator %d\n", cmprtr); DEBUG("Processing comparison operator %d\n", cmprtr);
DEBUG("Expression signedness is %d\n", expsgn);
switch(cmprtr) { switch(cmprtr) {
case 0: // Raw Expression (Skip)
asmlin("BEQ", curlbl);
break;
case 1: // = or == case 1: // = or ==
asmlin("CMP", term); asmlin("CMP", term);
asmlin("BNE", curlbl); asmlin("BNE", curlbl);
break; break;
case 2: // < case 2: // <
if (cmpsgn) { if (expsgn) {
asmlin("CMP", term); asmlin("CMP", term);
asmlin("BPL", curlbl); asmlin("BPL", curlbl);
} }
@ -60,7 +64,7 @@ void prccmp(int cmprtr)
} }
break; break;
case 3: // <= or =< case 3: // <= or =<
if (cmpsgn) { if (expsgn) {
asmlin("CMP", term); asmlin("CMP", term);
asmlin("BPL", curlbl); asmlin("BPL", curlbl);
asmlin("BNE", curlbl); asmlin("BNE", curlbl);
@ -72,7 +76,7 @@ void prccmp(int cmprtr)
} }
break; break;
case 4: // > case 4: // >
if (cmpsgn) { if (expsgn) {
asmlin("CMP", term); asmlin("CMP", term);
asmlin("BMI", curlbl); asmlin("BMI", curlbl);
asmlin("BEQ", curlbl); asmlin("BEQ", curlbl);
@ -84,7 +88,7 @@ void prccmp(int cmprtr)
} }
break; break;
case 5: // >= or => case 5: // >= or =>
if (cmpsgn) { if (expsgn) {
asmlin("CMP", term); asmlin("CMP", term);
asmlin("BMI", curlbl); asmlin("BMI", curlbl);
} }
@ -97,6 +101,9 @@ void prccmp(int cmprtr)
asmlin("CMP", term); asmlin("CMP", term);
asmlin("BEQ", curlbl); asmlin("BEQ", curlbl);
break; break;
case 7: // Raw Expression (Normal)
asmlin("BNE", curlbl);
break;
default: default:
printf("Unsupported comparison operator index %d\n", cmprtr); printf("Unsupported comparison operator index %d\n", cmprtr);
exterr(EXIT_FAILURE); exterr(EXIT_FAILURE);
@ -104,13 +111,13 @@ void prccmp(int cmprtr)
} }
/* Parse Comparison Operator * /* Parse Comparison Operator *
* Sets: comparitor - Encoded Comparison Operator */ * Sets: cmprtr - Encoded Comparison Operator */
int prscmp() int prscmp()
{ {
cmpenc = enccmp(nxtchr); //Encode Comparison Character cmpenc = enccmp(nxtchr); //Encode Comparison Character
if (cmpenc == 0)
expctd("comparison operator");
cmprtr = cmpenc; //Set Encoded Comparator cmprtr = cmpenc; //Set Encoded Comparator
if (cmprtr == 0) //No Comparison
return;
cmpenc = enccmp(nxtchr); //Encode Next Comparison Character cmpenc = enccmp(nxtchr); //Encode Next Comparison Character
if (cmpenc != 0) if (cmpenc != 0)
cmprtr = cmprtr | cmpenc; //Combine Encoded Comparator cmprtr = cmprtr | cmpenc; //Combine Encoded Comparator
@ -120,15 +127,17 @@ int prscmp()
/* Parse and Compile Conditional Expression * /* Parse and Compile Conditional Expression *
* Condition = <expression> <comparator> <term> */ * Condition = <expression> <comparator> <term> */
void prscnd(char trmntr) void prscnd(char trmntr, int revrse)
{ {
DEBUG("Parsing condition\n", 0); DEBUG("Parsing condition\n", 0);
prsxpr(0); prsxpr(0);
skpspc(); skpspc();
prscmp(); prscmp();
prstrm(); if (cmprtr)
prstrm();
cmprtr = cmprtr ^ revrse & 7;
prccmp();
CCMNT(trmntr); CCMNT(trmntr);
prccmp(cmprtr);
expect(trmntr); expect(trmntr);
} }

2
cond.h
View File

@ -4,5 +4,5 @@
int cmpsgn; // Comparison contains signed operands 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 "asm.h"
#include "parse.h" #include "parse.h"
#include "vars.h" #include "vars.h"
#include "label.h"
#include "expr.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) * /* Parse value (constant or identifier) *
* Sets: value - the value (as a string) * * Sets: value - the value (as a string) *
* valtyp - value type */ * valtyp - value type */
@ -22,8 +30,11 @@ void prsval()
//expdef(); //Check for and expand define -- BROKEN! //expdef(); //Check for and expand define -- BROKEN!
if (iscpre()) if (iscpre())
prscon(0xff); //Parse Constant prscon(0xff); //Parse Constant
else if (isalph()) else if (isalph()) {
prsvar(); //Parse Variable prsvar(); //Parse Variable
DEBUG("Checking type of variable '%s'\n", value);
if (vartyp[lookup(value)] == VTBYTE) setsgn(TRUE);
}
else else
expctd("constant or variable"); expctd("constant or variable");
skpspc(); skpspc();
@ -41,7 +52,7 @@ void prsidx()
expect(']'); expect(']');
} }
/* Parse term in expression * /* Parse term in expression *
* Sets: term - the term (as a string) * * Sets: term - the term (as a string) *
* trmtxt - type of term */ * trmtxt - type of term */
void prstrm() void prstrm()
@ -62,39 +73,80 @@ void prstrm()
skpspc(); skpspc();
} }
/* Parse and Compile Pointer Dereference */ /* Compile Address Reference */
void prsadr(char dlmtr) void prcadr(char* symbol)
{ {
prsvar();
DEBUG("Dereferencing variable '%s'\n", value);
ACMNT(value);
strcpy(word,"#<"); strcpy(word,"#<");
strcat(word,value); strcat(word,symbol);
asmlin("LDX", word); asmlin("LDX", word);
strcpy(word,"#>"); strcpy(word,"#>");
strcat(word,value); strcat(word,symbol);
asmlin("LDY", word); 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 and Create Anonymous String */
/* Parse function call in first term of expression * void prsstr()
* Function call may include term as an argument */
void prsxfn()
{ {
char fnname[255]; /*Function name*/ DEBUG("Parsing anonymous string\n", 0);
DEBUG("Processing expression function call '%s'...\n", term); strcpy(tmplbl, curlbl);//Save Current Label
strcpy(fnname, term); 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 skpchr(); //skip open paren
CCMNT('('); CCMNT('(');
if (look('&')) if (look('&'))
prsadr(0); prsadr();
else if (match('"'))
prsstr();
else if (isvpre()) { else if (isvpre()) {
prstrm(); prsxpr(0);
asmlin("LDA", term); prsfnp();
} }
expect(')'); expect(')');
asmlin("JSR", fnname); asmlin("JSR", fnstck[--fnscnt]);
skpspc(); skpspc();
} }
@ -107,7 +159,7 @@ void prsftm()
strcpy(term, value); strcpy(term, value);
trmtxt = valtyp; trmtxt = valtyp;
if (trmtxt == FUNCTION) { if (trmtxt == FUNCTION) {
prsxfn(); //Parse Expression Function prsfnc(); //Parse Expression Function
return; return;
} }
if (trmtxt == ARRAY) { if (trmtxt == ARRAY) {
@ -153,8 +205,12 @@ void prsxpr(char trmntr)
{ {
DEBUG("Parsing expression\n", 0); DEBUG("Parsing expression\n", 0);
skpspc(); skpspc();
if (match('-')) setsgn(FALSE); //Default Expression to Unsigned
asmlin("LDA", "#$00"); //Handle Unary Minus if (match('-')) {
DEBUG("Processing unary minus", 0);
asmlin("LDA", "#$00"); //Handle Unary Minus
setsgn(TRUE); //Expression is Signed
}
else else
prsftm(); //Parse First Term prsftm(); //Parse First Term
while (isoper()) while (isoper())

6
expr.h
View File

@ -5,7 +5,13 @@
char term[255]; /*Term parsed from equation*/ char term[255]; /*Term parsed from equation*/
int trmtxt; /*Term Type*/ 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 prsidx(); //Parse Array Index
void prstrm(); //Parse Term in Expression void prstrm(); //Parse Term in Expression
void prsxpr(char trmntr); //Parse Expression void prsxpr(char trmntr); //Parse Expression

59
label.c
View File

@ -13,6 +13,29 @@
#include "parse.h" #include "parse.h"
#include "label.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 * /* Set label for next line of *
* Assembly Language Code * * Assembly Language Code *
* to word */ * to word */
@ -21,8 +44,8 @@ void setlbl(char *lblset)
DEBUG("Setting Label '%s''\n", lblset); DEBUG("Setting Label '%s''\n", lblset);
if (strlen(lblasm) > 0) if (strlen(lblasm) > 0)
asmlin("",""); //Emit Block End Label on it's own line asmlin("",""); //Emit Block End Label on it's own line
if (strlen(word) > LABLEN) if (strlen(lblset) > LABLEN)
ERROR("Label '%s' exceeds maximum size", word, EXIT_FAILURE); ERROR("Label '%s' exceeds maximum size\n", word, EXIT_FAILURE);
strcpy(lblasm, lblset); strcpy(lblasm, lblset);
} }
@ -35,27 +58,35 @@ void prslbl()
} }
/* generate new label */ /* generate new label */
void newlbl(int lbtype) void newlbl()
{ {
sprintf(curlbl, LABFMT, lblnxt++); sprintf(curlbl, LABFMT, lblnxt++);
DEBUG("Generated new label '%s'\n", curlbl); 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 */ /* Pop Label from Stack and Emit on Next Line */
void lbllin() int poplbl()
{ {
int lbtype = lbltyp[--lblcnt]; int lbtype = lbltyp[--lblcnt];
if (lbtype == 1) { DEBUG("Popped label type %d\n", lbtype);
DEBUG("Ending Loop at Level %d'\n", lblcnt); if (lbtype == LTLOOP)
strcpy(endlbl, lblnam[lblcnt]); //Save End of Loop Label asmlin("JMP", lblnam[lblcnt--]); //Jump to Beginning of Loop
asmlin("JMP", lblnam[--lblcnt]); //Jump to Beginning of Loop if (lbtype == LTDO)
setlbl(endlbl); //Set End of Loop Label strcpy(loplbl, lblnam[lblcnt]);
}
else else
setlbl(lblnam[lblcnt]); 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 * * C02 Label Parsing, Generation, and Lookup Routines *
******************************************************/ ******************************************************/
int inblck; //Multiline Block Flag
char curlbl[LABLEN+1]; //Most recently generated label 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 char lblnam[MAXLAB+1][LABLEN+1]; //Label Name Table
int lbltyp[MAXLAB+1]; //Label Type int lbltyp[MAXLAB+1]; //Label Type
int lblblk[MAXLAB+1]; //Label Ends Program Block
int lblcnt; //Number of Labels in stack int lblcnt; //Number of Labels in stack
int lblnxt; //Sequence of next label to be generated int lblnxt; //Sequence of next label to be generated
char lbltmp[LABLEN+1]; //Label Temporary Storage 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 int lstlbl(int lbtype); //Find Last Label of Specified Type
void newlbl(); //Generate New Block Label void prslbl(); //Parse Label From Code
void lbllin(); //Pull Last Label and Emit on Next Line void newlbl(); //Generate New Block Label
void setlbl(); //Emit word as Label on Next Line 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 char opstr[2]; //Operator as a String
/* Various tests against nxtchr */ /* Various tests against nxtchr */
int match(char c) {return (nxtchr == c);} int match(char c) {return TF(nxtchr == c);}
int inbtwn(char mn, char mx) {return nxtchr >= mn && nxtchr <= mx;} int inbtwn(char mn, char mx) {return TF(nxtchr >= mn && nxtchr <= mx);}
int isprnt() {return isprint(nxtchr);} int isprnt() {return isprint(nxtchr);}
int isalph() {return isalpha(nxtchr);} int isalph() {return isalpha(nxtchr);}
int isanum() {return isalnum(nxtchr);} int isanum() {return isalnum(nxtchr);}
int isdec() {return inbtwn('0', '9');} 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 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 isspc() {return isspace(nxtchr);}
int isnpre() {return isdec() || match('$') || match('%');} int isnpre() {return TF(isdec() || match('$') || match('%'));}
int isapos() {return match('\'');} int isapos() {return match('\'');}
int iscpre() {return isnpre() || isapos();} int iscpre() {return TF(isnpre() || isapos());}
int isvpre() {return isalph() || iscpre();} int isvpre() {return TF(isalph() || iscpre());}
int isoper() {return (strchr("+-&|^", nxtchr)) ? TRUE : FALSE;} int isoper() {return TF(strchr("+-&|^", nxtchr));}
int ispopr() {return (strchr("+-<>", nxtchr)) ? TRUE : FALSE;} int ispopr() {return TF(strchr("+-<>", nxtchr));}
/* if Word is s then return TRUE else return FALSE*/ /* if Word is s then return TRUE else return FALSE*/
int wordis(char *s) int wordis(char *s)
@ -182,29 +182,37 @@ void expdef()
char escape(char c) char escape(char c)
{ {
DEBUG("Escaping character '%c'\n", c);
switch (c) { switch (c) {
case 'r': return 0x0d; case 'r': return 0x0d;
default: return c; default: return c;
} }
} }
void get_string() { /* Get String */
char str_del, tmp_char;
int wrdlen = 0, esc_next = FALSE; void getstr() {
char strdel, tmpchr;
int wrdlen = 0, escnxt = FALSE;
DEBUG("Parsing string\n", 0); DEBUG("Parsing string\n", 0);
str_del = getnxt(); strdel = getnxt(); //Get String Delimiter
while(!match(str_del)) { CCMNT(strdel);
if (esc_next) while(match(strdel) == escnxt) {
CCMNT(nxtchr);
if (escnxt) {
word[wrdlen++] = escape(getnxt()); word[wrdlen++] = escape(getnxt());
escnxt = FALSE;
}
else { else {
if (match('\\')) if (match('\\'))
esc_next = TRUE; escnxt = TRUE;
else else
word[wrdlen++] = nxtchr; word[wrdlen++] = nxtchr;
skpchr(); skpchr();
} }
} }
skpchr(); skpchr(); //Skip End Delimiter
CCMNT(strdel);
word[wrdlen++] = 0; word[wrdlen++] = 0;
} }
@ -343,15 +351,18 @@ int prsnum(int maxval)
* valtyp - value type (CONSTANT) */ * valtyp - value type (CONSTANT) */
void prscon(int maxval) void prscon(int maxval)
{ {
int constant = prsnum(maxval); cnstnt = prsnum(maxval);
valtyp = CONSTANT; valtyp = CONSTANT;
if (maxval > 255) if (maxval > 255)
sprintf(value, "#$%04X", constant); sprintf(value, "#$%04X", cnstnt);
else else
sprintf(value, "#$%02X", constant); sprintf(value, "#$%02X", cnstnt);
DEBUG("Generated constant '%s'\n", value); DEBUG("Generated constant '%s'\n", value);
} }
int get_vartyp()
/* Get Value Type */
int gettyp()
{ {
if (match('(')) return FUNCTION; if (match('(')) return FUNCTION;
else if (match('[')) return ARRAY; else if (match('[')) return ARRAY;
@ -364,7 +375,7 @@ int get_vartyp()
void prsvar() void prsvar()
{ {
getwrd(); getwrd();
valtyp = get_vartyp(); valtyp = gettyp();
if (valtyp != FUNCTION) chksym(word); if (valtyp != FUNCTION) chksym(word);
strcpy(value, word); strcpy(value, word);
DEBUG("Parsed variable '%s'\n", value); DEBUG("Parsed variable '%s'\n", value);

View File

@ -2,6 +2,8 @@
* C02 Input File Parsing Routines * * C02 Input File Parsing Routines *
*************************************/ *************************************/
#define TF(x) (x) ? TRUE : FALSE;
enum trmtxts {CONSTANT, VARIABLE, ARRAY, FUNCTION}; enum trmtxts {CONSTANT, VARIABLE, ARRAY, FUNCTION};
enum etypes {ETDEF, ETMAC}; //Definition Types 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 char value[LINELEN]; //Term parsed from equation
int valtyp; //Value Type int valtyp; //Value Type
char oper; //Arithmetic or Bitwise Operator char oper; //Arithmetic or Bitwise Operator
int cnstnt; //Value of Parsed Constant
char defnam[MAXDEF+1][VARLEN+1]; //Definition Name Table char defnam[MAXDEF+1][VARLEN+1]; //Definition Name Table
char deftxt[MAXDEF+1][DEFLEN+1]; //Definition Text Table char deftxt[MAXDEF+1][DEFLEN+1]; //Definition Text Table

300
stmnt.c
View File

@ -11,73 +11,17 @@
#include "asm.h" #include "asm.h"
#include "parse.h" #include "parse.h"
#include "vars.h" #include "vars.h"
#include "expr.h"
#include "label.h" #include "label.h"
#include "expr.h"
#include "stmnt.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 */ /* Process Assignment */
void pelse() { void prcasn(char trmntr)
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()
{ {
DEBUG("Parsing assignment of variable '%s''\n", asnvar); DEBUG("Processing assignment of variable '%s'\n", asnvar);
skpchr(); //skip equals sign expect('=');
ACMNT("="); prsxpr(trmntr);
prsxpr(';');
if (strlen(asnidx)) { if (strlen(asnidx)) {
asmlin("LDX", asnidx); asmlin("LDX", asnidx);
strcat(asnvar,",X"); strcat(asnvar,",X");
@ -108,50 +52,22 @@ void prcpop() {
} }
/* Parse Post Operator */ /* Parse Post Operator */
void prspop() { void prspop(char trmntr) {
oper = getnxt(); oper = getnxt();
CCMNT(oper); CCMNT(oper); CCMNT(oper); CCMNT(oper);
DEBUG("Checking for post operation '%c'\n", oper); DEBUG("Checking for post operation '%c'\n", oper);
if (nxtchr == oper) { if (nxtchr == oper) {
skpchr(); skpchr();
prcpop(); //Process Post-Op prcpop(); //Process Post-Op
expect(';'); expect(trmntr);
} }
else else
expctd("post operator"); expctd("post operator");
} }
/* Parse function call in first expression */ /* Process Variable at Beginning of Statement */
void prsfnc() 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); chksym(word);
strcpy(asnvar, word); //sav variable to assign to strcpy(asnvar, word); //sav variable to assign to
if (valtyp == ARRAY) { if (valtyp == ARRAY) {
@ -161,15 +77,180 @@ void prssym()
else else
asnidx[0] = 0; asnidx[0] = 0;
if (ispopr(nxtchr)) if (ispopr(nxtchr))
prspop(); //Parse Post Operator prspop(trmntr); //Parse Post Operator
else else
{ prcasn(trmntr);
skpspc(); }
if (match('='))
prsasn(); //Parse Assignment /* Begin Program Block */
else void bgnblk()
expctd("="); {
} 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 */ /* parse and compile program statement */
@ -180,6 +261,10 @@ void pstmnt()
prslbl(); //Parse Label prslbl(); //Parse Label
return; return;
} }
if (wordis("do")) {
pdo();
return;
}
if (wordis("if")) { if (wordis("if")) {
pif(); pif();
return; return;
@ -193,17 +278,22 @@ void pstmnt()
return; return;
} }
if (wordis("for")) { if (wordis("for")) {
punimp(); pfor();
return; return;
} }
else if (wordis("break"))
pbrcnt(LTEND);
else if (wordis("continue"))
pbrcnt(LTLOOP);
else if (wordis("goto")) else if (wordis("goto"))
pgoto(); pgoto();
else if (wordis("return")) else if (wordis("return"))
pretrn(); pretrn();
else else
prssym(); prssym();
if (lblcnt) { if (lblcnt && !inblck) {
lbllin(); if (poplbl() == LTDO)
pdowhl(); //Parse While at End of Do Loop
} }
} }

View File

@ -2,7 +2,8 @@
* C02 Statement Compiling Routines * * C02 Statement Compiling Routines *
************************************/ ************************************/
char asnvar[VARLEN+1]; /*Assigned Variable Name*/ char asnvar[VARLEN+1]; //Assigned Variable Name
char asnidx[VARLEN+1] ; /*Assigned Variable Index*/ 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); ERROR("Undeclared variable '%s' encountered\n", word, EXIT_FAILURE);
} }
/* Check for Array specifier and get size * /* Check for Array specifier and get size *
* Sets: value - array size (as string) * * Sets: value - array size (as string) *
* "" if not an array */ * "" if not an array */
@ -76,36 +75,64 @@ void prsdtc()
void prsdts() void prsdts()
{ {
dtype = DTSTR; dtype = DTSTR;
get_string(); getstr();
strcpy(value, word); strcpy(value, word);
DEBUG("Parsed Data String '%s'\n", value); DEBUG("Parsed Data String '%s'\n", value);
} }
/* Parse and store variable data * /* Store variable data *
* Uses: value - Data to store *
* Sets: datvar[] - Variable Data * * Sets: datvar[] - Variable Data *
* datlen[] - Data Length */ * 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() void prsdat()
{ {
DEBUG("Checking for variable data\n", 0); DEBUG("Checking for variable data\n", 0);
int i;
if (!look('=')) { if (!look('=')) {
datlen[varcnt] = 0; datlen[varcnt] = 0;
return; return;
} }
skpspc(); skpspc();
if (isnpre()) if (isnpre())
prsdtc(0xff); prsdtc(0xff); //Parse Data Constant
else if (match('"')) else if (match('"'))
prsdts(); prsdts(); //Parse Data String
dlen = strlen(value); else
datlen[varcnt] = dlen; expctd("numeric or string constant");
dattyp[varcnt] = dtype; setdat(); //Store Data Value
DEBUG("Setting variable data to '%s'\n", value);
for (i=0; i<dlen; i++)
datvar[dsize++] = value[i];
} }
/* Add Variable to Variable table * /* 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 */ * Uses: word - variable name */
void addvar(int t) void addvar(int t)
{ {
@ -113,14 +140,10 @@ void addvar(int t)
ERROR("Duplicate declaration of variable '%s\n", word,EXIT_FAILURE); ERROR("Duplicate declaration of variable '%s\n", word,EXIT_FAILURE);
if (t == VTVOID) if (t == VTVOID)
ERROR("Illegal Variable Type\n", 0, EXIT_FAILURE); ERROR("Illegal Variable Type\n", 0, EXIT_FAILURE);
DEBUG("Adding variable '%s'\n", word); pvarsz(); //Check for Array Declaration and Get Size
strncpy(varnam[varcnt], word, VARLEN); setvar(t); //Add to Variable Table
vartyp[varcnt] = t; prsdat(); //Parse Variable Data
pvarsz(); varcnt++; //Increment Variable Counter
strncpy(varsiz[varcnt], value, 3);
DEBUG("Added at index %d\n", varcnt);
prsdat(); //Parse Variable Data
varcnt++;
} }
void addfnc() void addfnc()
@ -155,7 +178,7 @@ void vardat(int i)
value[0] = 0; value[0] = 0;
for (j=0; j<datlen[i]; j++) { for (j=0; j<datlen[i]; j++) {
if (j) strcat(value,","); if (j) strcat(value,",");
sprintf(word, "$%02X", datvar[dlen++]); sprintf(word, "$%hhX", datvar[dlen++]);
strcat(value, word); strcat(value, word);
} }
if (dattyp[i] == DTSTR) strcat(value, ",$00"); if (dattyp[i] == DTSTR) strcat(value, ",$00");
@ -191,10 +214,10 @@ void vartbl()
void logvar() void logvar()
{ {
int i; 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++) 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 char varsiz[MAXVAR+1][4]; //Variable Array
int varcnt; //Number of Variables in Table int varcnt; //Number of Variables in Table
/*
int varidx; //Index into Variable Table
int vrtype; //Variable Type
*/
enum vtypes {VTVOID, VTBYTE, VTCHAR}; //Variable Types enum vtypes {VTVOID, VTBYTE, VTCHAR}; //Variable Types
char datvar[DATASPC+1]; //Variable Data Storage 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) int symdef(char *name); //Is Variable defined (TRUE or FALSE)
void chksym(char *name); //Error if Variable not defined 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 void vartbl(); //Create Variable Table