1
0
mirror of https://github.com/RevCurtisP/C02.git synced 2025-02-19 19:31:04 +00:00

Disallowed nested function declarations and commented more code

This commit is contained in:
Curtis F Kaylor 2018-07-21 20:51:41 -04:00
parent f179acceb1
commit eb90c48f0d
16 changed files with 251 additions and 55 deletions

View File

@ -28,24 +28,25 @@
/* Initilize Compiler Variables */
void init(void) {
DEBUG("Initializing Compiler Variables\n",0)
concnt = 0;
varcnt = 0;
lblcnt = 0;
curcol = 0;
curlin = 0;
concnt = 0; //Number of Constants Defined
varcnt = 0; //Number of Variables in Table
lblcnt = 0; //Number of Labels in stack
curcol = 0; //Current Column in Source Code
curlin = 0; //Current Line in Source Code
alcvar = TRUE; //Allocate Variables Flag
inblck = FALSE; //Multiline Block Flag
infunc = FALSE; //Inside Function Definition
xstmnt[0] = 0; //Expected Statement
nxtwrd[0] = 0; //Next Word (from DEFINE lookup)
nxtptr = 0; //Pointer to next character in nxtwrd
vrwrtn = FALSE; //Variables Written Flag
zpaddr = 0; //Current Zero-Page Address
invasc = FALSE; //Invert ASCII Flag
mskasc = FALSE; //Set High Bit Flag
fcase = FALSE; //First Case Statement Flag
xsnvar[0] = 0; //Assigned X Variable Name
ysnvar[0] = 0; //Assigned Y Variable Name
strcpy(incdir, "../include/");
alcvar = TRUE;
inblck = FALSE;
xstmnt[0] = 0;
nxtwrd[0] = 0;
nxtptr = 0;
vrwrtn = FALSE;
zpaddr = 0;
invasc = FALSE;
mskasc = FALSE;
fcase = FALSE;
xsnvar[0] = 0;
ysnvar[0] = 0;
}
/* Reads and parses the next Word in Source File */

View File

@ -14,18 +14,21 @@
#define MAXVAR 255 //Maximum Number of Variables
#define MAXTRM 16 //Maximum Terms in Stack
#define DATASPC 2048 //Space to Allocate for Variable Data
#define LABLEN 6 //Maximum Label Length
#define LABFMT "L_%04d" //Label Format
#define LABSFX ":" //Label Suffix
#define MAXLAB 15 //Maximum Number of Labels (Nesting Depth)
#define LOCPFX "." //Local Variable Prefix
#define CPUOP "PROCESSOR" //Target CPU Pseudo-Operator
#define CPUARG "6502" //Target CPU Operand
#define ORGOP "ORG" //Origin Pseudo-Op
#define EQUOP "EQU" //Equate Pseudo-Op
#define BYTEOP "DC" //Define Byte Pseudo-Op
#define STROP "DS" //Define String Pseudo-Op
#define ALNOP "ALIGN" //Align Pseudo-Op
#define CPUOP "PROCESSOR" //Target CPU Pseudo-Operator
#define CPUARG "6502" //Target CPU Operand
#define ORGOP "ORG" //Origin Pseudo-Op
#define EQUOP "EQU" //Equate Pseudo-Op
#define BYTEOP "DC" //Define Byte Pseudo-Op
#define STROP "DS" //Define String Pseudo-Op
#define ALNOP "ALIGN" //Align Pseudo-Op
#define LOCOP "SUBROUTINE" //Local Variable Boundary Pseudo-Op
#define ASMFMT "%-7s %-3s %-12s %s\n" //Assembly Language Line printf Format
@ -60,8 +63,9 @@ char inpnam[FNAMLEN]; //Input File Name
int alcvar; //Allocate Variables Flag
int inblck; //Multiline Block Flag
int lsrtrn; //Last Statement was a Return
int fcase; //First Case Statement
int infunc; //Inside Function Definition Flag
int lsrtrn; //Last Statement was a Return Flag
int fcase; //First Case Statement Flag
void exterr(int errnum); //Print current file name & position and exit
void expctd(char *expected); //Print Expected message and exit

View File

@ -17,25 +17,27 @@
#include "stmnt.h"
#include "dclrtn.h"
void addprm(char* prmtr) {
reqvar(FALSE); //Get Variable Name
strcpy(prmtr, value); //Copy to Parameter Variable
prmcnt++; //Increment # of Parameters
}
/* Add Function Definition */
void addfnc(void) {
if (infunc) ERROR("Nested Function Definitions Not Allowed\n", 0, EXIT_FAILURE)
expect('(');
infunc = TRUE; //Set Inside Function Definition Flag
DEBUG("Set infunc to %d\n", infunc)
strcpy(fncnam, word); //Save Function Name
prmcnt = 0; //Set Number of Parameters
prmcnt = 0; //Initialze Number of Parameters
skpspc(); //Skip Spaces
/* QUESTION: Eliminate this in favor of Register Assignments inside Function Call? */
if (isalph()) { //Parse Parameters
reqvar(FALSE); //Get First Parameter
strcpy(prmtra, value);
prmcnt++;
if (look(',')) {
reqvar(FALSE); //Get Second Parameter
strcpy(prmtry, value);
prmcnt++;
if (look(',')) {
reqvar(FALSE); //Third Parameter
strcpy(prmtrx, value);
prmcnt++;
addprm(prmtra); //Get First Parameter
if (look(',')) { //Look for Comma
addprm(prmtry); //Get Second Parameter
if (look(',')) { //Look for Comma
addprm(prmtrx); //Get Third Parameter
}
}
}
@ -107,7 +109,7 @@ void pdecl(int m, int t) {
do {
getwrd();
if (match('(')) {
if (m != MTNONE) ERROR("Illegal Modifier %d in Function Definition", m, EXIT_FAILURE)
if (m != MTNONE) ERROR("Illegal Modifier %d in Function Definition\n", m, EXIT_FAILURE)
addfnc(); //Add Function Call
return;
}
@ -118,7 +120,8 @@ void pdecl(int m, int t) {
cmtlin(); //Write out declaration comment
}
/* Check for and Parse Type Keyword */
/* Check for and Parse Type Keyword *
* Args: m - Modifier Type */
int ptype(int m) {
int result = TRUE;
if (wordis("STRUCT")) pstrct(m); //Parse 'const' declaration

View File

@ -2,5 +2,12 @@
* C02 Declaration Compiling Routines *
************************************/
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
//int lpemtd; //Location Prefix Emitted
int pmodfr(); //Check for and Parse Modifier
int ptype(int m); //Check for and Parse Type Keyword

View File

@ -17,9 +17,9 @@
/* Push Term and Operator onto Stack */
void pshtrm(void) {
if (trmidx >= MAXTRM) ERROR("Maximum Function Call/Array Index Depth Exceeded", 0, EXIT_FAILURE)
oprstk[trmidx] = oper; //Put Current Operator on Stack
strcpy(trmstk[], term); //Put Current Term on Stack
trmidx++; //Increment Stack Pointer
oprstk[trmidx] = oper; //Put Current Operator on Stack
strcpy(trmstk[trmidx], term); //Put Current Term on Stack
trmidx++; //Increment Stack Pointer
}
/* Pop Term and Operator off Stack */

View File

@ -78,12 +78,20 @@ void reqlbl(char* lbname) {
setlbl(lbname);
}
/* End Function Block */
void endfnc(void) {
DEBUG("Ending function definition with lsrtrn set to %d\n", lsrtrn)
if (!lsrtrn) asmlin("RTS", "");
infunc = FALSE;
DEBUG("Set infunc to %d\n", infunc)
}
/* Pop Label from Stack and Emit on Next Line */
int poplbl(void) {
int lbtype = lbltyp[--lblcnt];
DEBUG("Popped label type %d\n", lbtype)
switch (lbtype) {
case LTFUNC: if (!lsrtrn) asmlin("RTS", ""); break; //Return From Subroutine
case LTFUNC: endfnc(); break; //Return From Subroutine
case LTDO: strcpy(loplbl, lblnam[lblcnt]); break;
case LTDWHL: strcpy(endlbl, lblnam[lblcnt]); break;
case LTCASE: strcpy(cndlbl, lblnam[lblcnt]); break;

View File

@ -48,17 +48,11 @@ int dsize; //Total Data Length
enum dtypes {DTBYTE, DTSTR, DTARRY}; //Variable Data Types
enum mtypes {MTNONE, MTALGN, MTZP, MTALS}; //Variable Modifier Types
enum mtypes {MTNONE, MTALGN, MTZP, MTALS, MTLOCAL}; //Variable Modifier Types
int symdef(char *name); //Is Variable defined (TRUE or FALSE)
int zpaddr; //Current Zero-Page Address
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 addvar(int m, int t); //Parse and Compile Variable Declaration
void addstc(); //Parse and Compile Structure Declaration
void defstc(); //Parse Structure Definition

3
test/a02.bat Normal file
View File

@ -0,0 +1,3 @@
@ECHO Assembling File %1.asm
dasm %1.asm -f3 -o%1.bin -l%1.lst -s%1.sym

22
test/arrays.c02 Normal file
View File

@ -0,0 +1,22 @@
/* Test C02 array manipulation */
#pragma origin 1000
char b, c, i;
char r[255];
char s = "string";
char d = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
char n = {1, 2, 3, 4, 5, 6, 7, 8, 9};
char func();
c = d[3];
b = n[i];
b = s[n[i]];
b = s[c + n[i-1]];
b = s[func()];
b = s[0] & d[c-1] | n[i+2];
pop b, d[i], n[func()], s[c-n[i+3]];

3
test/c02.bat Normal file
View File

@ -0,0 +1,3 @@
@ECHO Compiling File %1.c02
..\c02.exe %1 >%1.dbg

58
test/example.c02 Normal file
View File

@ -0,0 +1,58 @@
/* C02 Syntax Examples */
/* Constants */
const #TRUE = $FF, #FALSE = 0; //Constant
enum {BLACK, WHITE, RED, CYAN, PURPLE, GREEN, BLUE, YELLOW};
/* Structures */
struct record {char name[8]; char index;}; //Struct Definition
struct record rec; //Struct Declaration
/* Declarations */
char i, j; //Variables
char debug = #TRUE; //Variable initialized to constant
char flag = %01010101; //Variable initialized to literal
char r[7]; //8 byte Array
char s = "string"; //Array initialized to string
char m = {1,2,3}; //Array initialized to list
char isdgt(); //Forward declaration of function
/* Assignments */
hmove; s80vid; //Implicit Assignments
x = 0; y = a; a = 1; //Register Assignments
b = c + d - e & f | g ^ h; //Assignment and Expression
d[j] = r[i] + s[x] + t[y]; //Array Indexing
a<< ;b[i]>>; x++; y--; //Post-Operations
/* Function Calls */
i = abs(n); j = min(b,c), k = max(d,e); plot(h,v,c);
n = mult(e+f, div(m+n,d)) - t;
puts("string"); putc(#CR); fputs(fp, &line);
c = getc(); i = strchr(c, &s); row,col = scnpos();
push d,r; mult(); pop p; //Pass via Stack
iprint(); inline "Hello World"; //Pass Inline String
irect(); inline 10,10,100,100; //Pass Inline Parameters
/* Control Structures */
if (c = 27) goto end;
if (n) q = div(n,d) else puts("Division by 0!");
if (!fp) putln("File not opened");
i = 0; while (c < 10) { prbyte(i); i++; }
while() { c=rdkey; if (c=0) continue; putchr(c); if (c==13) break; }
do c = rdkey(); while (c=0);
do (c = getchr(); putchr(c); while (c<>13)
for (c='A'; c<='Z'; c++) putc(c);
for (i=strlen(s)-1;i:+;i--) putc(s[i]);
for (i=0;c>0;i++) { c=getc(); s[i]=c }
select (getc()) {
case $0D: putln("The Enter key");
case 'A','a': putln ("The letter A");
default: putln("some other key");
}
end: //Label
/* Function Declaration */
char isdgt(tmp) {
if (tmp >= '0') if (tmp <= '9') return true;
return false;
}

46
test/flags.c02 Normal file
View File

@ -0,0 +1,46 @@
/* Test C02 evaluations */
#pragma origin 1000
char aa, yy, xx;
char var;
doflgs(:+C :+D :+I);
doflgs(:-C :-D :-I :-V);
//doflgs(:+V);
doargs(aa, yy, xx :+C :-V);
if (?:+C) putln("Carry Set");
if (?:-C) putln("Carry Clear");
if (!?:+C) putln("Carry Not Set");
if (!?:-C) putln("Carry Not Clear");
if (?:+N) putln("Negative Set");
if (?:-N) putln("Negative Clear");
if (!?:+N) putln("Negative Not Set");
if (!?:-N) putln("Negative Not Clear");
if (?:+V) putln("Overflow Set");
if (?:-V) putln("Overflow Clear");
if (!?:+V) putln("Overflow Not Set");
if (!?:-V) putln("Overflow Not Clear");
if (?:+Z) putln("Zero Set");
if (?:-Z) putln("Zero Clear");
if (!?:+Z) putln("Zero Not Set");
if (!?:-Z) putln("Zero Not Clear");
if (?:+C:+N:+V:+Z) putln("Carry, Negative, Overflow, and Zero Set");
if (!?:+C:+N:+V:+Z) putln("Carry, Negative, Overflow, or Zero Not Set");
if (?:-C:-N:-V:-Z) putln("Carry, Negative, Overflow, and Zero Clear");
if (!?:-C:-N:-V:-Z) putln("Carry, Negative, Overflow, or Zero Not Clear");
if (VAR:+N) putln("VAR is negative");
if (VAR:+Z) putln("VAR is zero");
if (VAR:-N:-Z) putln("VAR is positive");
char sign() {
if (?:+N) return -1;
if (?:+Z) return 0;
return 1;
}
goto exit;

View File

@ -13,14 +13,25 @@ char t = {1, 2, 3, 4, 5};
char s = "This is a string.";
char aa,xx,yy ; //Function parameter variables
char aaa,xxx,yyy ; //Function return variables
char STROBE; //Strobe Register
char STROBE; //Strobe Register
/* Function Declaration */
/* Function Declarations */
char myfunc();
return b-c-d;
return;
char func1(aa) {
return aa;
}
char func2(aa, yy) {
return aa + yy;
}
char func3(aa, yy, xx) {
return aa + yy - xx;
}
main:
funcx:
@ -59,5 +70,7 @@ c, z[i], f = testfn(); //Return 3 Values with Array
r[i], z[j] = testfn(); //Return 2 Values with Arrays
r[i], z[j], f = testfn(); //Return 2 Values with Arrays
//void fnoutr() {char fninnr() {} }
//A, Y = testfn(); //Error - Registers not Allowed when returning multiple values
//r[i], z[j], f[b] = testfn(); //Error - Array Element not Allowed with STX assignment

13
test/test.bas Normal file
View File

@ -0,0 +1,13 @@
REM http://srecord.sourceforge.net/
DATA 169,0,56,229,1,24,101,2,56,229,3,141,135,2,165,31,37,5,141,137,2,173
DATA 135,2,13,137,2,69,255,141,138,2,238,138,2,206,138,2,14,135,2,78,137,2
DATA 165,0,141,136,2,173,136,2,174,136,2,157,140,2,238,140,2,174,136,2,189
DATA 140,2,174,136,2,157,155,2,32,0,240,141,139,2,173,137,2,32,0,240,141
DATA 139,2,173,135,2,24,109,137,2,24,109,138,2,32,2,240,174,136,2,189,140,2
DATA 32,0,240,32,2,240,173,138,2,205,139,2,240,10,173,135,2,24,109,137,2
DATA 141,136,2,76,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0
REM termination = 0
REM start = 512
REM finish = 682
REM length = 170

9
test/test.h Normal file
View File

@ -0,0 +1,9 @@
/* Generic 6502 header file */
//int getchar() = $f000
//void putchar() = $f002
#label exit $FF00
#origin $0300

12
test/test.srec Normal file
View File

@ -0,0 +1,12 @@
S1130200A90038E50118650238E5038D8702A51FAA
S113021025058D8902AD87020D890245FF8D8A026D
S1130220EE8A02CE8A020E87024E8902A5008D88CC
S113023002AD8802AE88029D8C02EE8C02AE88026A
S1130240BD8C02AE88029D9B022000F08D8B02AD16
S113025089022000F08D8B02AD8702186D89021887
S11302606D8A022002F0AE8802BD8C022000F020CC
S113027002F0AD8A02CD8B02F00AAD8702186D89B7
S1130280028D88024C00FF00000000000000000006
S1130290000000000000000000000000000000005A
S10D02A00000000000000000000050
S9030000FC