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

Added shortcut IFs in expressions

Implemented full Function Definitions
This commit is contained in:
Curtis F Kaylor 2017-05-15 20:25:11 -04:00
parent dba8e1a409
commit bfc84d11c5
15 changed files with 193 additions and 151 deletions

1
asm.c
View File

@ -36,6 +36,7 @@ void chrcmt(char c)
cmtasm[i] = 0;
}
/* Process comment */
void prccmt()
{
if (strlen(cmtasm)) {

BIN
asm.o Normal file

Binary file not shown.

5
c02.c
View File

@ -46,6 +46,7 @@ void init()
/* Reads and parses the next Word in Source File */
pword()
{
lsrtrn = FALSE; //Clear RETURN flag
getwrd();
ACMNT(word);
DEBUG("Parsing Word '%s'\n", word);
@ -54,8 +55,8 @@ pword()
xstmnt[0] = 0;
else
ERROR("Expected '%s' statement\n", xstmnt, EXIT_FAILURE);
if (wordis("byte"))
pdecl(VTBYTE); //Parse 'byte' declaration
if (wordis("void"))
pdecl(VTVOID); //Parse 'void' declaration
else if (wordis("char"))
pdecl(VTCHAR); //Parse 'char' declaration
else

View File

@ -2,6 +2,10 @@
* C02 Common Definitions & Routines *
*************************************/
#ifndef COMMON_H
#define COMMON_H //Define Guard
#define FNAMLEN 255 //Maximum File Name Length
#define LINELEN 255 //Maximum Input/Output Line Length
#define DEFLEN 9 //Maximum Definition Text Length
@ -47,8 +51,11 @@ char inpnam[FNAMLEN]; //Include File Name
int alcvar; //Allocate Variables Flag
int lsrtrn; //Last Statement was a Return
void exterr(int errnum); //Print current file name & position and exit
void expctd(char *expected); //Print Expected message and exit
void prtpos(); //Print current file name and position
#endif

96
cond.c
View File

@ -46,68 +46,38 @@ int enccmp(char c)
void prccmp()
{
DEBUG("Processing comparison operator %d\n", cmprtr);
DEBUG("Expression signedness is %d\n", xprsgn);
switch(cmprtr) {
case 0: // Raw Expression (Skip)
asmlin("BEQ", curlbl);
asmlin("BEQ", cndlbl);
break;
case 1: // = or ==
asmlin("CMP", term);
asmlin("BNE", curlbl);
asmlin("BNE", cndlbl);
break;
case 2: // <
if (xprsgn) {
asmlin("CMP", term);
asmlin("BPL", curlbl);
}
else {
asmlin("CMP", term);
asmlin("BCS", curlbl);
}
asmlin("CMP", term);
asmlin("BCS", cndlbl);
break;
case 3: // <= or =<
if (xprsgn) {
asmlin("SEC", "");
asmlin("SBC", term);
asmlin("BVC", "+4");
asmlin("EOR", "#$80");
asmlin("BPL", curlbl);
asmlin("BNE", curlbl);
}
else {
asmlin("CLC", "");
asmlin("SBC", term);
asmlin("BCS", curlbl);
}
asmlin("CLC", "");
asmlin("SBC", term);
asmlin("BCS", cndlbl);
break;
case 4: // >
if (xprsgn) {
asmlin("CMP", term);
asmlin("BMI", curlbl);
asmlin("BEQ", curlbl);
}
else {
asmlin("CLC", "");
asmlin("SBC", term);
asmlin("BCC", curlbl);
}
asmlin("CLC", "");
asmlin("SBC", term);
asmlin("BCC", cndlbl);
break;
case 5: // >= or =>
if (xprsgn) {
asmlin("CMP", term);
asmlin("BMI", curlbl);
}
else {
asmlin("CMP", term);
asmlin("BCC", curlbl);
}
asmlin("CMP", term);
asmlin("BCC", cndlbl);
break;
case 6: // <> or ><
asmlin("CMP", term);
asmlin("BEQ", curlbl);
asmlin("BEQ", cndlbl);
break;
case 7: // Raw Expression (Normal)
asmlin("BNE", curlbl);
asmlin("BNE", cndlbl);
break;
default:
printf("Unsupported comparison operator index %d\n", cmprtr);
@ -115,10 +85,10 @@ void prccmp()
}
}
/* Parse Comparison Operator *
* Sets: cmprtr - Encoded Comparison Operator */
int prscmp()
/* Parse Comparison */
int prscmp(revrse)
{
skpspc();
cmpenc = enccmp(nxtchr); //Encode Comparison Character
cmprtr = cmpenc; //Set Encoded Comparator
if (cmprtr) {
@ -127,9 +97,31 @@ int prscmp()
cmprtr = cmprtr | cmpenc; //Combine Encoded Comparator
}
skpspc();
if (cmprtr)
prstrm();
cmprtr = cmprtr ^ revrse & 7;
prccmp();
DEBUG("Parsed comparator %d\n", cmprtr);
}
/* Parse Flag Operator */
void prsflg(int revrse)
{
DEBUG("Parsing Flag Operator '%c'\n", nxtchr);
if (match('+'))
cmprtr = 0;
else if (match('-'))
cmprtr = 1;
else
expctd("Flag operator");
skpchr();
cmprtr = cmprtr ^ revrse & 1;
if (cmprtr)
asmlin("BPL", cndlbl);
else
asmlin("BMI", cndlbl);
}
/* Parse and Compile Conditional Expression *
* Condition = <expression> <comparator> <term> */
void prscnd(char trmntr, int revrse)
@ -140,12 +132,10 @@ void prscnd(char trmntr, int revrse)
DEBUG("Set revrse to %d\n", revrse);
}
prsxpr(0);
skpspc();
prscmp();
if (cmprtr)
prstrm();
cmprtr = cmprtr ^ revrse & 7;
prccmp();
if (look(':'))
prsflg(revrse); //Parse Flag Operator
else
prscmp(revrse); //Parse Comparison Operator
CCMNT(trmntr);
expect(trmntr);
}

21
expr.c
View File

@ -14,13 +14,6 @@
#include "label.h"
#include "expr.h"
/* Set Expession Signedness */
setsgn(int sgndns)
{
xprsgn = sgndns;
DEBUG("Set Expression Signedness to %d\n", xprsgn);
}
/* Parse value (constant or identifier) *
* Sets: value - the value (as a string) *
* valtyp - value type */
@ -32,8 +25,6 @@ void prsval()
prscon(0xff); //Parse Constant
else if (isalph()) {
prsvar(); //Parse Variable
DEBUG("Checking type of variable '%s'\n", value);
if (vartyp[lookup(value)] == VTBYTE) setsgn(TRUE);
}
else
expctd("constant or variable");
@ -95,16 +86,13 @@ void prsadr()
void prsstr()
{
DEBUG("Parsing anonymous string\n", 0);
strcpy(tmplbl, curlbl);//Save Current Label
newlbl(); //Generate Label Name
strcpy(vrname, curlbl); //and Use as Variable Name
newlbl(vrname); //Generate 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
prcadr(vrname); //Compile Address Reference
}
/* Parse Additional Function Parameters */
@ -187,9 +175,10 @@ void prcopr()
asmlin("AND", term);
break;
case '|':
case '!': //For systems that don't have pipe in character set
asmlin("ORA", term);
break;
case '^':
case '^': //Looks like an up-arrow in some character sets
asmlin("EOR", term);
break;
default:
@ -203,11 +192,9 @@ void prsxpr(char trmntr)
{
DEBUG("Parsing expression\n", 0);
skpspc();
setsgn(FALSE); //Default Expression to Unsigned
if (match('-')) {
DEBUG("Processing unary minus", 0);
asmlin("LDA", "#$00"); //Handle Unary Minus
setsgn(TRUE); //Expression is Signed
}
else
prsftm(); //Parse First Term

2
expr.h
View File

@ -5,8 +5,6 @@
char term[255]; /*Term parsed from equation*/
int trmtxt; /*Term Type*/
int xprsgn; //Expression Contains Signed Term
char fnstck[MAXFNS][VARLEN+1]; //Function Call Stack
int fnscnt; //Number of Functions in Stack

BIN
files.o Normal file

Binary file not shown.

View File

@ -74,8 +74,6 @@ void phdwrd() {
getwrd();
if (wordis("void"))
pdecl(VTVOID);
else if (wordis("byte"))
pdecl(VTBYTE);
else if (wordis("char"))
pdecl(VTCHAR);
else {

17
label.c
View File

@ -58,10 +58,10 @@ void prslbl()
}
/* generate new label */
void newlbl()
void newlbl(char* lbname)
{
sprintf(curlbl, LABFMT, lblnxt++);
DEBUG("Generated new label '%s'\n", curlbl);
sprintf(lbname, LABFMT, lblnxt++);
DEBUG("Generated new label '%s'\n", lbname);
}
/* Pop Label from Stack and Emit on Next Line */
@ -71,7 +71,10 @@ int poplbl()
DEBUG("Popped label type %d\n", lbtype);
if (lbtype == LTLOOP)
asmlin("JMP", lblnam[lblcnt--]); //Jump to Beginning of Loop
if (lbtype == LTDO)
if (lbtype == LTFUNC) {
if (!lsrtrn) asmlin("RTS", ""); //Return From Subroutine
}
else if (lbtype == LTDO)
strcpy(loplbl, lblnam[lblcnt]);
else
setlbl(lblnam[lblcnt]);
@ -82,12 +85,12 @@ int poplbl()
/* Push Label onto Stack *
* Args: lbltyp - Label type *
* Uses: curlbl - Label to push */
void pshlbl(int lbtype)
void pshlbl(int lbtype, char* lbname)
{
DEBUG("Pushing label type %d\n", lbtype);
strcpy(lblnam[lblcnt], curlbl);
strcpy(lblnam[lblcnt], lbname);
lbltyp[lblcnt] = lbtype;
lblblk[lblcnt++] = FALSE;
DEBUG("Pushed label '%s' onto stack\n", curlbl);
DEBUG("Pushed label '%s' onto stack\n", lbname);
}

12
label.h
View File

@ -5,7 +5,9 @@
int inblck; //Multiline Block Flag
char curlbl[LABLEN+1]; //Most recently generated label
char cndlbl[LABLEN+1]; //Label for Conditional Code
char endlbl[LABLEN+1]; //End Label
char forlbl[LABLEN+1]; //For Loop Label
char loplbl[LABLEN+1]; //Skip Increment Label
char skplbl[LABLEN+1]; //Skip Increment Label
char tmplbl[LABLEN+1]; //Temporary Label
@ -16,11 +18,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, LTCASE}; //Label Types
enum ltypes {LTIF, LTLOOP, LTEND, LTDO, LTCASE, LTFUNC}; //Label Types
int lstlbl(int lbtype); //Find Last Label of Specified Type
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
void newlbl(char* lbname); //Generate New Block Label
int poplbl(); //Pull Last Label and Emit on Next Line
void setlbl(); //Emit word as Label on Next Line

BIN
label.o Normal file

Binary file not shown.

102
stmnt.c
View File

@ -20,8 +20,20 @@ void prcasn(char trmntr)
{
DEBUG("Processing assignment of variable '%s'\n", asnvar);
expect('=');
prsxpr(trmntr);
if (strlen(asnidx)) {
if (look('(')) { //Parse Shortcut If
newlbl(cndlbl); //Create Label for "if FALSE" expression
prscnd(')', FALSE); //Parse Condition
expect('?');
prsxpr(':'); //Parse "if TRUE" expression
newlbl(tmplbl); //Create End of Expression Label
asmlin("JMP", tmplbl); //Jump over "if FALSE" expression
setlbl(cndlbl); //Emit "if FALSE" label
prsxpr(trmntr); //Parse "if FALSE" expression
setlbl(tmplbl); //Emit End of Expression Label
}
else
prsxpr(trmntr);
if (strlen(asnidx)) {
asmlin("LDX", asnidx);
strcat(asnvar,",X");
}
@ -116,9 +128,9 @@ void pbrcnt(int lbtype) {
/* 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
newlbl(loplbl); //Create Do Loop Label
pshlbl(LTDO, loplbl); //Push onto Stack
setlbl(loplbl); //Set Label to Emit on Next Line
bgnblk(FALSE); //Check For and Begin Block
}
@ -130,10 +142,10 @@ void pdowhl() {
if (!wordis("while"))
expctd("while statement");
expect('(');
newlbl(); //Create Skip Label
newlbl(cndlbl); //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
setlbl(cndlbl); //and Set Label to Emit on Next Line
expect(';'); //Check for End of Statement
}
@ -143,23 +155,19 @@ 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
newlbl(forlbl); //Create For Loop Conditional Label
setlbl(forlbl); //and Set to Emit on Next Line
newlbl(endlbl); //Create End Label
pshlbl(LTEND, endlbl); //and Push onto Stack
newlbl(loplbl); //Create Loop Label
pshlbl(LTLOOP, loplbl); //and Push onto Stack
newlbl(cndlbl); //Create Conditional Label
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
asmlin("JMP", forlbl); //Jump to Conditional
setlbl(cndlbl); //Emit Label at Start of Loop
bgnblk(FALSE); //Check For and Begin Block
}
@ -167,8 +175,8 @@ void pfor() {
void pif() {
DEBUG("Parsing IF statement '%c'\n", nxtchr);
expect('(');
newlbl(); //Create New Label
pshlbl(LTIF); //Push Onto Stack
newlbl(cndlbl); //Create New Label
pshlbl(LTIF,cndlbl); //Push Onto Stack
prscnd(')', FALSE); //Parse Conditional Expession
bgnblk(FALSE); //Check For and Begin Block
}
@ -176,13 +184,13 @@ void pif() {
/* 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(FALSE); //Check For and Begin Block
strcpy(lbltmp, lblasm); //Save Line Label
lblasm[0] = 0; //and Clear It
newlbl(skplbl); //Create Skip Label
pshlbl(LTIF, skplbl); //Push Onto Stack
asmlin("JMP", skplbl); //Emit Jump over Block Code
strcpy(lblasm, lbltmp); //Restore Line Label
bgnblk(FALSE); //Check For and Begin Block
}
/* parse and compile if statement */
@ -200,6 +208,7 @@ void pretrn() {
if (!look(';'))
prsxpr(';');
asmlin("RTS", "");
lsrtrn = TRUE; //Set RETURN flag
}
/* parse and compile switch statement */
@ -207,8 +216,8 @@ void pswtch() {
DEBUG("Parsing SWITCH statement\n", 0);
expect('(');
prsxpr(')');
newlbl();
pshlbl(LTEND);
newlbl(endlbl);
pshlbl(LTEND, endlbl);
bgnblk(TRUE);
strcpy(xstmnt,"case");
}
@ -218,9 +227,9 @@ void pcase() {
DEBUG("Parsing CASE statement\n", 0);
prscon(0xff); //Parse Constant
asmlin("CMP", value);
newlbl();
pshlbl(LTCASE);
asmlin("BNE", curlbl);
newlbl(skplbl);
pshlbl(LTCASE, skplbl);
asmlin("BNE", skplbl);
expect(':');
}
@ -237,17 +246,16 @@ void pdeflt() {
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
newlbl(endlbl); //Create End Label
pshlbl(LTEND, endlbl); //and Push onto Stack
newlbl(loplbl); //create Loop Label
setlbl(loplbl); //Set to Emit on Next Line
pshlbl(LTLOOP, loplbl); //Push onto Stack
newlbl(cndlbl); //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(FALSE); //Check For and Begin Block
setlbl(cndlbl); //and Set Label to Emit on Next Line
bgnblk(FALSE); //Check For and Begin Block
}
/* generate unimplemented statement error */
@ -282,7 +290,7 @@ void endblk(int blkflg)
{
int lbtype;
DEBUG("Ending program block with flag %d\n", blkflg);
skpchr(); //Skip '}';
expect('}'); //Block End Character
DEBUG("Found inblck set to %d\n", inblck);
if (inblck != blkflg)
ERROR("Encountered '}' without matching '{'\n", 0, EXIT_FAILURE);
@ -344,8 +352,8 @@ void pstmnt()
else
prssym();
if (lblcnt && !inblck) {
if (poplbl() == LTDO)
pdowhl(); //Parse While at End of Do Loop
if (poplbl() == LTDO)
pdowhl(); //Parse While at End of Do Loop
}
}

48
vars.c
View File

@ -12,6 +12,7 @@
#include "files.h"
#include "asm.h"
#include "parse.h"
#include "label.h"
#include "vars.h"
/* Lookup variable name in variable table *
@ -45,6 +46,16 @@ void chksym(char *name)
ERROR("Undeclared variable '%s' encountered\n", word, EXIT_FAILURE);
}
/* Parse Variable Name *
* Generates error if not a simple variable */
void reqvar()
{
prsvar();
if (valtyp != VARIABLE)
expctd("Variable");
}
/* Check for Array specifier and get size *
* Sets: value - array size (as string) *
* "" if not an array */
@ -147,11 +158,40 @@ void addvar(int t)
varcnt++; //Increment Variable Counter
}
/* Add Function Definition */
void addfnc()
{
strcpy(fncnam, word); //Save Function Name
prmcnt = 0; //Set Number of Parameters
skpspc(); //Skip Spaces
if (isalph()) { //Parse Parameters
reqvar(); //Get First Parameter
strcpy(prmtra, value);
prmcnt++;
if (look(',')) {
reqvar(); //Get Second Parameter
strcpy(prmtry, value);
prmcnt++;
if (look(',')) {
reqvar(); //Third Parameter
strcpy(prmtrx, value);
prmcnt++;
}
}
}
expect(')');
if (alcvar)
setlbl(word);
if (look(';')) //Forward Definition
return;
setlbl(fncnam); //Set Function Entry Point
if (prmcnt > 0)
asmlin("STA", prmtra); //Store First Parameter
if (prmcnt > 1)
asmlin("STY", prmtry); //Store Second Parameter
if (prmcnt > 2)
asmlin("STX", prmtrx); //Store Third Parameter
endlbl[0] = 0; //Create Dummy End Label
pshlbl(LTFUNC, endlbl); //and Push onto Stack
bgnblk(TRUE); //Start Program Block
}
/* (Check For and) Parse Variable Declaration*/
@ -161,8 +201,8 @@ void pdecl(int t)
while(TRUE) {
getwrd();
if (look('(')) {
addfnc();
break;
addfnc(); //Add Function Call
return;
}
addvar(t);
if (!look(','))

31
vars.h
View File

@ -13,23 +13,30 @@ char vrname[MAXVAR+1]; //Variable Name
int varidx; //Index into Variable Table
int vrtype; //Variable Type
*/
enum vtypes {VTVOID, VTBYTE, VTCHAR}; //Variable Types
enum vtypes {VTVOID, VTCHAR}; //Variable Types
char datvar[DATASPC+1]; //Variable Data Storage
char datlen[MAXVAR+1]; //Variable Data Length
char dattyp[MAXVAR+1]; //Variable Data Type
char datvar[DATASPC+1]; //Variable Data Storage
char datlen[MAXVAR+1]; //Variable Data Length
char dattyp[MAXVAR+1]; //Variable Data Type
int dtype; //Data Type
int dlen; //Length of Variable Data
int dsize; //Total Data Length
enum dtypes {DTBYTE, DTSTR}; //Variable Data Types
enum dtypes {DTBYTE, DTSTR}; //Variable Data Types
int symdef(char *name); //Is Variable defined (TRUE or FALSE)
void chksym(char *name); //Error if Variable not defined
int symdef(char *name); //Is Variable defined (TRUE or FALSE)
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
char fncnam[VARLEN+1]; //Function Name
char prmtra[VARLEN+1]; //Function Parameter A
char prmtrx[VARLEN+1]; //Function Parameter X
char prmtry[VARLEN+1]; //Function Parameter Y
int prmcnt; //Number of Parameters
void chksym(char *name); //Error if Variable not defined
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