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:
parent
f179acceb1
commit
eb90c48f0d
35
src/c02.c
35
src/c02.c
@ -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 */
|
||||
|
22
src/common.h
22
src/common.h
@ -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
|
||||
|
33
src/dclrtn.c
33
src/dclrtn.c
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
10
src/label.c
10
src/label.c
@ -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;
|
||||
|
@ -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
3
test/a02.bat
Normal 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
22
test/arrays.c02
Normal 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
3
test/c02.bat
Normal file
@ -0,0 +1,3 @@
|
||||
@ECHO Compiling File %1.c02
|
||||
..\c02.exe %1 >%1.dbg
|
||||
|
58
test/example.c02
Normal file
58
test/example.c02
Normal 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
46
test/flags.c02
Normal 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;
|
@ -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
13
test/test.bas
Normal 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
9
test/test.h
Normal 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
12
test/test.srec
Normal file
@ -0,0 +1,12 @@
|
||||
S1130200A90038E50118650238E5038D8702A51FAA
|
||||
S113021025058D8902AD87020D890245FF8D8A026D
|
||||
S1130220EE8A02CE8A020E87024E8902A5008D88CC
|
||||
S113023002AD8802AE88029D8C02EE8C02AE88026A
|
||||
S1130240BD8C02AE88029D9B022000F08D8B02AD16
|
||||
S113025089022000F08D8B02AD8702186D89021887
|
||||
S11302606D8A022002F0AE8802BD8C022000F020CC
|
||||
S113027002F0AD8A02CD8B02F00AAD8702186D89B7
|
||||
S1130280028D88024C00FF00000000000000000006
|
||||
S1130290000000000000000000000000000000005A
|
||||
S10D02A00000000000000000000050
|
||||
S9030000FC
|
Loading…
x
Reference in New Issue
Block a user