mirror of
https://github.com/RevCurtisP/C02.git
synced 2025-02-19 19:31:04 +00:00
Save before modifying newlbl() function
This commit is contained in:
parent
772c841052
commit
dba8e1a409
8
c02.c
8
c02.c
@ -1,7 +1,7 @@
|
||||
/**************************************************************
|
||||
* C02 Compiler - (C) 2013 Curtis F Kaylor *
|
||||
* *
|
||||
* C02 is a modified C-like language designed for the 6502 *
|
||||
* C02 is a simpified C-like language designed for the 6502 *
|
||||
* *
|
||||
* This Compiler generates crasm compatible assembly language *
|
||||
* *
|
||||
@ -38,6 +38,7 @@ void init()
|
||||
strcpy(inpnam, srcnam);
|
||||
alcvar = TRUE;
|
||||
inblck = FALSE;
|
||||
xstmnt[0] = 0;
|
||||
nxtwrd[0] = 0;
|
||||
nxtptr = 0;
|
||||
}
|
||||
@ -48,6 +49,11 @@ pword()
|
||||
getwrd();
|
||||
ACMNT(word);
|
||||
DEBUG("Parsing Word '%s'\n", word);
|
||||
if (xstmnt[0])
|
||||
if (wordis(xstmnt))
|
||||
xstmnt[0] = 0;
|
||||
else
|
||||
ERROR("Expected '%s' statement\n", xstmnt, EXIT_FAILURE);
|
||||
if (wordis("byte"))
|
||||
pdecl(VTBYTE); //Parse 'byte' declaration
|
||||
else if (wordis("char"))
|
||||
|
35
cond.c
35
cond.c
@ -23,6 +23,7 @@ int cmpenc; //Encoded Comparator Character
|
||||
int enccmp(char c)
|
||||
{
|
||||
int e;
|
||||
DEBUG("Encoding Comparison Character '%c'\n", c);
|
||||
switch(c)
|
||||
{
|
||||
case '=': e = 1; break;
|
||||
@ -32,8 +33,9 @@ int enccmp(char c)
|
||||
}
|
||||
if (e) {
|
||||
CCMNT(c);
|
||||
skpchr();
|
||||
skpchr();
|
||||
}
|
||||
DEBUG("Encoded as %d\n", e);
|
||||
return e;
|
||||
}
|
||||
|
||||
@ -44,7 +46,7 @@ int enccmp(char c)
|
||||
void prccmp()
|
||||
{
|
||||
DEBUG("Processing comparison operator %d\n", cmprtr);
|
||||
DEBUG("Expression signedness is %d\n", expsgn);
|
||||
DEBUG("Expression signedness is %d\n", xprsgn);
|
||||
switch(cmprtr) {
|
||||
case 0: // Raw Expression (Skip)
|
||||
asmlin("BEQ", curlbl);
|
||||
@ -54,7 +56,7 @@ void prccmp()
|
||||
asmlin("BNE", curlbl);
|
||||
break;
|
||||
case 2: // <
|
||||
if (expsgn) {
|
||||
if (xprsgn) {
|
||||
asmlin("CMP", term);
|
||||
asmlin("BPL", curlbl);
|
||||
}
|
||||
@ -64,8 +66,11 @@ void prccmp()
|
||||
}
|
||||
break;
|
||||
case 3: // <= or =<
|
||||
if (expsgn) {
|
||||
asmlin("CMP", term);
|
||||
if (xprsgn) {
|
||||
asmlin("SEC", "");
|
||||
asmlin("SBC", term);
|
||||
asmlin("BVC", "+4");
|
||||
asmlin("EOR", "#$80");
|
||||
asmlin("BPL", curlbl);
|
||||
asmlin("BNE", curlbl);
|
||||
}
|
||||
@ -76,7 +81,7 @@ void prccmp()
|
||||
}
|
||||
break;
|
||||
case 4: // >
|
||||
if (expsgn) {
|
||||
if (xprsgn) {
|
||||
asmlin("CMP", term);
|
||||
asmlin("BMI", curlbl);
|
||||
asmlin("BEQ", curlbl);
|
||||
@ -88,7 +93,7 @@ void prccmp()
|
||||
}
|
||||
break;
|
||||
case 5: // >= or =>
|
||||
if (expsgn) {
|
||||
if (xprsgn) {
|
||||
asmlin("CMP", term);
|
||||
asmlin("BMI", curlbl);
|
||||
}
|
||||
@ -116,11 +121,11 @@ int prscmp()
|
||||
{
|
||||
cmpenc = enccmp(nxtchr); //Encode Comparison Character
|
||||
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
|
||||
if (cmprtr) {
|
||||
cmpenc = enccmp(nxtchr); //Encode Next Comparison Character
|
||||
if (cmpenc != 0)
|
||||
cmprtr = cmprtr | cmpenc; //Combine Encoded Comparator
|
||||
}
|
||||
skpspc();
|
||||
DEBUG("Parsed comparator %d\n", cmprtr);
|
||||
}
|
||||
@ -129,7 +134,11 @@ int prscmp()
|
||||
* Condition = <expression> <comparator> <term> */
|
||||
void prscnd(char trmntr, int revrse)
|
||||
{
|
||||
DEBUG("Parsing condition\n", 0);
|
||||
DEBUG("Parsing condition with revrse=%d\n", revrse);
|
||||
if (look('!')) {
|
||||
revrse = (revrse) ? FALSE: TRUE;
|
||||
DEBUG("Set revrse to %d\n", revrse);
|
||||
}
|
||||
prsxpr(0);
|
||||
skpspc();
|
||||
prscmp();
|
||||
|
8
expr.c
8
expr.c
@ -17,8 +17,8 @@
|
||||
/* Set Expession Signedness */
|
||||
setsgn(int sgndns)
|
||||
{
|
||||
expsgn = sgndns;
|
||||
DEBUG("Set Expression Signedness to %d\n", expsgn);
|
||||
xprsgn = sgndns;
|
||||
DEBUG("Set Expression Signedness to %d\n", xprsgn);
|
||||
}
|
||||
|
||||
/* Parse value (constant or identifier) *
|
||||
@ -38,7 +38,6 @@ void prsval()
|
||||
else
|
||||
expctd("constant or variable");
|
||||
skpspc();
|
||||
ACMNT(word);
|
||||
}
|
||||
|
||||
/* Parse array index *
|
||||
@ -89,7 +88,6 @@ void prsadr()
|
||||
{
|
||||
prsvar();
|
||||
DEBUG("Parsing address of variable '%s'\n", value);
|
||||
ACMNT(value);
|
||||
prcadr(value); //Compile Address Reference
|
||||
}
|
||||
|
||||
@ -99,7 +97,7 @@ void prsstr()
|
||||
DEBUG("Parsing anonymous string\n", 0);
|
||||
strcpy(tmplbl, curlbl);//Save Current Label
|
||||
newlbl(); //Generate Label Name
|
||||
strcpy(word, curlbl); //and Use as Variable Name
|
||||
strcpy(vrname, 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
|
||||
|
2
expr.h
2
expr.h
@ -5,7 +5,7 @@
|
||||
char term[255]; /*Term parsed from equation*/
|
||||
int trmtxt; /*Term Type*/
|
||||
|
||||
int expsgn; //Expression Contains Signed Term
|
||||
int xprsgn; //Expression Contains Signed Term
|
||||
|
||||
char fnstck[MAXFNS][VARLEN+1]; //Function Call Stack
|
||||
int fnscnt; //Number of Functions in Stack
|
||||
|
3
label.c
3
label.c
@ -41,7 +41,7 @@ void setblk(int blkflg)
|
||||
* to word */
|
||||
void setlbl(char *lblset)
|
||||
{
|
||||
DEBUG("Setting Label '%s''\n", lblset);
|
||||
DEBUG("Setting Label '%s'\n", lblset);
|
||||
if (strlen(lblasm) > 0)
|
||||
asmlin("",""); //Emit Block End Label on it's own line
|
||||
if (strlen(lblset) > LABLEN)
|
||||
@ -84,6 +84,7 @@ int poplbl()
|
||||
* Uses: curlbl - Label to push */
|
||||
void pshlbl(int lbtype)
|
||||
{
|
||||
DEBUG("Pushing label type %d\n", lbtype);
|
||||
strcpy(lblnam[lblcnt], curlbl);
|
||||
lbltyp[lblcnt] = lbtype;
|
||||
lblblk[lblcnt++] = FALSE;
|
||||
|
12
label.h
12
label.h
@ -16,11 +16,11 @@ 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, LTDO}; //Label Types
|
||||
enum ltypes {LTIF, LTLOOP, LTEND, LTDO, LTCASE}; //Label Types
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
|
4
parse.c
4
parse.c
@ -60,7 +60,7 @@ char getnxt()
|
||||
/* Advance Input File to next printable character */
|
||||
void skpspc()
|
||||
{
|
||||
DEBUG("Skipping Spaces\n", 0);
|
||||
//DEBUG("Skipping Spaces\n", 0);
|
||||
while (isspc())
|
||||
getnxt();
|
||||
}
|
||||
@ -358,6 +358,7 @@ void prscon(int maxval)
|
||||
else
|
||||
sprintf(value, "#$%02X", cnstnt);
|
||||
DEBUG("Generated constant '%s'\n", value);
|
||||
ACMNT(word);
|
||||
}
|
||||
|
||||
|
||||
@ -379,6 +380,7 @@ void prsvar()
|
||||
if (valtyp != FUNCTION) chksym(word);
|
||||
strcpy(value, word);
|
||||
DEBUG("Parsed variable '%s'\n", value);
|
||||
ACMNT(word);
|
||||
}
|
||||
|
||||
/* Parse arithmetic or bitwise operator */
|
||||
|
2
parse.h
2
parse.h
@ -13,7 +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
|
||||
int cnstnt; //Value of Parsed Constant
|
||||
|
||||
char defnam[MAXDEF+1][VARLEN+1]; //Definition Name Table
|
||||
char deftxt[MAXDEF+1][DEFLEN+1]; //Definition Text Table
|
||||
|
106
stmnt.c
106
stmnt.c
@ -15,7 +15,6 @@
|
||||
#include "expr.h"
|
||||
#include "stmnt.h"
|
||||
|
||||
|
||||
/* Process Assignment */
|
||||
void prcasn(char trmntr)
|
||||
{
|
||||
@ -83,10 +82,16 @@ void prcvar(char trmntr)
|
||||
}
|
||||
|
||||
/* Begin Program Block */
|
||||
void bgnblk()
|
||||
void bgnblk(int blkflg)
|
||||
{
|
||||
DEBUG("Begining program block\n", 0);
|
||||
inblck = look('{');
|
||||
if (blkflg) {
|
||||
expect('{');
|
||||
inblck = TRUE;
|
||||
}
|
||||
else
|
||||
inblck = look('{');
|
||||
DEBUG("Set inblck to %d\n", inblck);
|
||||
setblk(inblck);
|
||||
}
|
||||
|
||||
@ -114,7 +119,7 @@ void pdo() {
|
||||
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
|
||||
bgnblk(FALSE); //Check For and Begin Block
|
||||
}
|
||||
|
||||
/* parse and compile 'while' after 'do' statement */
|
||||
@ -155,7 +160,7 @@ void pfor() {
|
||||
prsasn(')'); //Parse Increment Assignment
|
||||
asmlin("JMP", tmplbl); //Jump to Conditional
|
||||
setlbl(skplbl); //Emit Label at Start of Loop
|
||||
bgnblk(); //Check For and Begin Block
|
||||
bgnblk(FALSE); //Check For and Begin Block
|
||||
}
|
||||
|
||||
/* parse and compile if statement */
|
||||
@ -165,19 +170,19 @@ void pif() {
|
||||
newlbl(); //Create New Label
|
||||
pshlbl(LTIF); //Push Onto Stack
|
||||
prscnd(')', FALSE); //Parse Conditional Expession
|
||||
bgnblk(); //Check For and Begin Block
|
||||
bgnblk(FALSE); //Check For and Begin Block
|
||||
}
|
||||
|
||||
/* parse and compile else statement */
|
||||
void pelse() {
|
||||
DEBUG("Parsing ELSE statement '%c'\n", nxtchr);
|
||||
strcpy(lbltmp, lblasm);
|
||||
strcpy(lbltmp, lblasm);
|
||||
lblasm[0] = 0;
|
||||
newlbl(); //Create New Label
|
||||
pshlbl(LTIF); //Push Onto Stack
|
||||
newlbl(); //Create New Label
|
||||
pshlbl(LTIF); //Push Onto Stack
|
||||
asmlin("JMP", curlbl);
|
||||
strcpy(lblasm, lbltmp);
|
||||
bgnblk(); //Check For and Begin Block
|
||||
bgnblk(FALSE); //Check For and Begin Block
|
||||
}
|
||||
|
||||
/* parse and compile if statement */
|
||||
@ -189,7 +194,7 @@ void pgoto() {
|
||||
expect(';');
|
||||
}
|
||||
|
||||
/* parse and compile if statement */
|
||||
/* parse and compile return statement */
|
||||
void pretrn() {
|
||||
DEBUG("Parsing RETURN statement\n", 0);
|
||||
if (!look(';'))
|
||||
@ -197,6 +202,37 @@ void pretrn() {
|
||||
asmlin("RTS", "");
|
||||
}
|
||||
|
||||
/* parse and compile switch statement */
|
||||
void pswtch() {
|
||||
DEBUG("Parsing SWITCH statement\n", 0);
|
||||
expect('(');
|
||||
prsxpr(')');
|
||||
newlbl();
|
||||
pshlbl(LTEND);
|
||||
bgnblk(TRUE);
|
||||
strcpy(xstmnt,"case");
|
||||
}
|
||||
|
||||
/* parse and compile case statement */
|
||||
void pcase() {
|
||||
DEBUG("Parsing CASE statement\n", 0);
|
||||
prscon(0xff); //Parse Constant
|
||||
asmlin("CMP", value);
|
||||
newlbl();
|
||||
pshlbl(LTCASE);
|
||||
asmlin("BNE", curlbl);
|
||||
expect(':');
|
||||
}
|
||||
|
||||
void pdeflt() {
|
||||
DEBUG("Parsing DEFAULT statement\n", 0);
|
||||
expect(':');
|
||||
if (poplbl() != LTCASE)
|
||||
ERROR("Encountered default without case\n", 0, EXIT_FAILURE);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* parse and compile while statement */
|
||||
void pwhile() {
|
||||
DEBUG("Parsing WHILE statement '%c'\n", nxtchr);
|
||||
@ -211,7 +247,7 @@ void pwhile() {
|
||||
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
|
||||
bgnblk(FALSE); //Check For and Begin Block
|
||||
}
|
||||
|
||||
/* generate unimplemented statement error */
|
||||
@ -244,12 +280,16 @@ void prssym()
|
||||
* Args: blkflg: End of Multiline Block */
|
||||
void endblk(int blkflg)
|
||||
{
|
||||
int lbtype;
|
||||
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)
|
||||
ERROR("Encountered '}' without matching '{'\n", 0, EXIT_FAILURE);
|
||||
lbtype = poplbl();
|
||||
if (lbtype == LTCASE)
|
||||
ERROR("Ended switch without default\n", 0, EXIT_FAILURE);
|
||||
if (lbtype == LTDO)
|
||||
pdowhl(); //Parse While at End of Do Loop
|
||||
}
|
||||
|
||||
@ -257,31 +297,43 @@ void endblk(int blkflg)
|
||||
void pstmnt()
|
||||
{
|
||||
DEBUG("Parsing statement '%s'\n", word);
|
||||
if(match(':')) {
|
||||
prslbl(); //Parse Label
|
||||
return;
|
||||
}
|
||||
if (wordis("do")) {
|
||||
pdo();
|
||||
return;
|
||||
}
|
||||
if (wordis("if")) {
|
||||
pif();
|
||||
return;
|
||||
}
|
||||
if (wordis("else")) {
|
||||
pelse();
|
||||
return;
|
||||
}
|
||||
if (wordis("while")) {
|
||||
pwhile();
|
||||
return;
|
||||
}
|
||||
if (wordis("for")) {
|
||||
pfor();
|
||||
return;
|
||||
}
|
||||
else if (wordis("break"))
|
||||
if (wordis("if")) {
|
||||
pif();
|
||||
return;
|
||||
}
|
||||
if (wordis("switch")) {
|
||||
punimp();
|
||||
return;
|
||||
}
|
||||
if (wordis("case")) {
|
||||
punimp();
|
||||
return;
|
||||
}
|
||||
if (wordis("default")) {
|
||||
punimp();
|
||||
return;
|
||||
}
|
||||
if (wordis("while")) {
|
||||
pwhile();
|
||||
return;
|
||||
}
|
||||
if(match(':')) {
|
||||
prslbl(); //Parse Label
|
||||
return;
|
||||
}
|
||||
if (wordis("break"))
|
||||
pbrcnt(LTEND);
|
||||
else if (wordis("continue"))
|
||||
pbrcnt(LTLOOP);
|
||||
|
2
stmnt.h
2
stmnt.h
@ -5,5 +5,7 @@
|
||||
char asnvar[VARLEN+1]; //Assigned Variable Name
|
||||
char asnidx[VARLEN+1] ; //Assigned Variable Index
|
||||
|
||||
char xstmnt[LINELEN]; //Required Statement
|
||||
|
||||
void endblk(); //End Program Block
|
||||
void pstmnt(); //Parse and Compile Program Statement
|
||||
|
5
vars.c
5
vars.c
@ -126,7 +126,7 @@ void prsdat()
|
||||
void setvar(int t)
|
||||
{
|
||||
DEBUG("Adding variable '%s'\n", word);
|
||||
strncpy(varnam[varcnt], word, VARLEN);
|
||||
strncpy(varnam[varcnt], vrname, VARLEN);
|
||||
vartyp[varcnt] = t;
|
||||
strncpy(varsiz[varcnt], value, 3);
|
||||
DEBUG("Added at index %d\n", varcnt);
|
||||
@ -136,7 +136,8 @@ void setvar(int t)
|
||||
* Uses: word - variable name */
|
||||
void addvar(int t)
|
||||
{
|
||||
if (symdef(word))
|
||||
strcpy(vrname, word); //Save Variable Name
|
||||
if (symdef(vrname))
|
||||
ERROR("Duplicate declaration of variable '%s\n", word,EXIT_FAILURE);
|
||||
if (t == VTVOID)
|
||||
ERROR("Illegal Variable Type\n", 0, EXIT_FAILURE);
|
||||
|
3
vars.h
3
vars.h
@ -3,10 +3,11 @@
|
||||
*************************************/
|
||||
|
||||
/* Variable Table */
|
||||
char varnam[MAXVAR+1][VARLEN+1]; //Variable Name
|
||||
char varnam[MAXVAR+1][VARLEN+1]; //Variable Name Table
|
||||
char vartyp[MAXVAR+1]; //Variable Type
|
||||
char varsiz[MAXVAR+1][4]; //Variable Array
|
||||
int varcnt; //Number of Variables in Table
|
||||
char vrname[MAXVAR+1]; //Variable Name
|
||||
|
||||
/*
|
||||
int varidx; //Index into Variable Table
|
||||
|
Loading…
x
Reference in New Issue
Block a user