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:
parent
1abb077f09
commit
772c841052
16
c02.c
16
c02.c
@ -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();
|
||||||
}
|
}
|
||||||
|
3
common.h
3
common.h
@ -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
31
cond.c
@ -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
2
cond.h
@ -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
106
expr.c
@ -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
6
expr.h
@ -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
59
label.c
@ -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
19
label.h
@ -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
55
parse.c
@ -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);
|
||||||
|
3
parse.h
3
parse.h
@ -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
300
stmnt.c
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
7
stmnt.h
7
stmnt.h
@ -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
69
vars.c
@ -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
9
vars.h
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user