mirror of
https://github.com/RevCurtisP/C02.git
synced 2024-11-22 01:31:33 +00:00
Converted source code line endings to CR/LF
This commit is contained in:
parent
6703c8cb10
commit
3a7224ce9a
BIN
src/.vscode/ipch/771b4d3d25e434c7/C02.ipch
vendored
Normal file
BIN
src/.vscode/ipch/771b4d3d25e434c7/C02.ipch
vendored
Normal file
Binary file not shown.
BIN
src/.vscode/ipch/771b4d3d25e434c7/mmap_address.bin
vendored
Normal file
BIN
src/.vscode/ipch/771b4d3d25e434c7/mmap_address.bin
vendored
Normal file
Binary file not shown.
19
src/.vscode/launch.json
vendored
Normal file
19
src/.vscode/launch.json
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "(Windows) Launch",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/c02.exe",
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"externalConsole": true
|
||||
}
|
||||
]
|
||||
}
|
72
src/asm.c
72
src/asm.c
@ -1,36 +1,36 @@
|
||||
/*************************************
|
||||
* C02 Assembly Language Routines *
|
||||
*************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "files.h"
|
||||
#include "asm.h"
|
||||
|
||||
/* Process comment */
|
||||
void prccmt(void) {
|
||||
if (strlen(cmtasm)) { strcpy(asmcmt, ";"); strcat(asmcmt, cmtasm); }
|
||||
else asmcmt[0] = 0;
|
||||
setcmt("");
|
||||
}
|
||||
|
||||
/* output a single line of assembly code */
|
||||
void asmlin(char *opcode, char *oprnd) {
|
||||
if (strlen(lblasm)) strcat(lblasm, LABSFX);
|
||||
prccmt();
|
||||
fprintf(outfil, ASMFMT, lblasm, opcode, oprnd, asmcmt);
|
||||
if (debug) printf(ASMFMT, lblasm, opcode, oprnd, asmcmt);
|
||||
lblasm[0] = 0;
|
||||
}
|
||||
|
||||
/* output a single comment line */
|
||||
void cmtlin(void) {
|
||||
DEBUG("Writing Comment Line: %s\n", cmtasm)
|
||||
fprintf(outfil, "; %s\n", cmtasm);
|
||||
setcmt("");
|
||||
}
|
||||
/*************************************
|
||||
* C02 Assembly Language Routines *
|
||||
*************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "files.h"
|
||||
#include "asm.h"
|
||||
|
||||
/* Process comment */
|
||||
void prccmt(void) {
|
||||
if (strlen(cmtasm)) { strcpy(asmcmt, ";"); strcat(asmcmt, cmtasm); }
|
||||
else asmcmt[0] = 0;
|
||||
setcmt("");
|
||||
}
|
||||
|
||||
/* output a single line of assembly code */
|
||||
void asmlin(char *opcode, char *oprnd) {
|
||||
if (strlen(lblasm)) strcat(lblasm, LABSFX);
|
||||
prccmt();
|
||||
fprintf(outfil, ASMFMT, lblasm, opcode, oprnd, asmcmt);
|
||||
if (debug) printf(ASMFMT, lblasm, opcode, oprnd, asmcmt);
|
||||
lblasm[0] = 0;
|
||||
}
|
||||
|
||||
/* output a single comment line */
|
||||
void cmtlin(void) {
|
||||
DEBUG("Writing Comment Line: %s\n", cmtasm)
|
||||
fprintf(outfil, "; %s\n", cmtasm);
|
||||
setcmt("");
|
||||
}
|
||||
|
18
src/asm.h
18
src/asm.h
@ -1,9 +1,9 @@
|
||||
/*************************************
|
||||
* C02 Assembly Language Routines *
|
||||
*************************************/
|
||||
|
||||
char lblasm[LBLLEN+2]; //Label to emit on next asm line
|
||||
|
||||
void asmlin(char *opcode, char *oprnd); //Output a line of assembly code
|
||||
void cmtlin(); //Output a comment lines
|
||||
void prccmt(); //Process comment
|
||||
/*************************************
|
||||
* C02 Assembly Language Routines *
|
||||
*************************************/
|
||||
|
||||
char lblasm[LBLLEN+2]; //Label to emit on next asm line
|
||||
|
||||
void asmlin(char *opcode, char *oprnd); //Output a line of assembly code
|
||||
void cmtlin(); //Output a comment lines
|
||||
void prccmt(); //Process comment
|
||||
|
120
src/common.c
120
src/common.c
@ -1,60 +1,60 @@
|
||||
/*************************************
|
||||
* C02 Common Definitions & Routines *
|
||||
*************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include "common.h"
|
||||
|
||||
struct timespec curtim; //Current Time
|
||||
|
||||
/* Error - Print Input File name & position and exit */
|
||||
void exterr(int errnum) {
|
||||
fprintf(stderr, "Line %d Column %d of File %s\n", curlin, curcol, inpnam);
|
||||
exit(errnum);
|
||||
}
|
||||
|
||||
/* Error - print "Expected" error message *
|
||||
and exit with general failure code *
|
||||
Args: expected - Description of what was expected */
|
||||
void expctd(char *expstr) {
|
||||
fprintf(stderr, "Expected %s, but found '%c'\n", expstr, nxtchr);
|
||||
exterr(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Print current position in file */
|
||||
void prtpos(void) { if (inpnam[0]) printf("(%s: %d,%d) ", inpnam, curlin, curcol); }
|
||||
|
||||
/* Initialize elapsed time counter */
|
||||
void initim(void) {
|
||||
timespec_get (&curtim, TIME_UTC);
|
||||
bgntim = curtim.tv_sec;
|
||||
}
|
||||
|
||||
/* Print elapsed time */
|
||||
void prttim(void) {
|
||||
timespec_get (&curtim, TIME_UTC);
|
||||
printf("[%d", curtim.tv_sec - bgntim);
|
||||
printf(".%06d]",curtim.tv_nsec/1000);
|
||||
}
|
||||
|
||||
/* Set comment to string */
|
||||
void setcmt(char *s) { strcpy(cmtasm, s); }
|
||||
|
||||
/* Append string to comment */
|
||||
void addcmt(char *s) {
|
||||
if (strlen(cmtasm)+strlen(s)<73) strcat(cmtasm, s);
|
||||
}
|
||||
|
||||
/* Append character to comment */
|
||||
void chrcmt(char c) {
|
||||
if (strlen(cmtasm)>72) return;
|
||||
if (cmtasm[0] == 0 && c == ' ') return;
|
||||
int i = strlen(cmtasm);
|
||||
cmtasm[i++] = c;
|
||||
cmtasm[i] = 0;
|
||||
}
|
||||
/*************************************
|
||||
* C02 Common Definitions & Routines *
|
||||
*************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include "common.h"
|
||||
|
||||
struct timespec curtim; //Current Time
|
||||
|
||||
/* Error - Print Input File name & position and exit */
|
||||
void exterr(int errnum) {
|
||||
fprintf(stderr, "Line %d Column %d of File %s\n", curlin, curcol, inpnam);
|
||||
exit(errnum);
|
||||
}
|
||||
|
||||
/* Error - print "Expected" error message *
|
||||
and exit with general failure code *
|
||||
Args: expected - Description of what was expected */
|
||||
void expctd(char *expstr) {
|
||||
fprintf(stderr, "Expected %s, but found '%c'\n", expstr, nxtchr);
|
||||
exterr(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Print current position in file */
|
||||
void prtpos(void) { if (inpnam[0]) printf("(%s: %d,%d) ", inpnam, curlin, curcol); }
|
||||
|
||||
/* Initialize elapsed time counter */
|
||||
void initim(void) {
|
||||
timespec_get (&curtim, TIME_UTC);
|
||||
bgntim = curtim.tv_sec;
|
||||
}
|
||||
|
||||
/* Print elapsed time */
|
||||
void prttim(void) {
|
||||
timespec_get (&curtim, TIME_UTC);
|
||||
printf("[%d", curtim.tv_sec - bgntim);
|
||||
printf(".%06d]",curtim.tv_nsec/1000);
|
||||
}
|
||||
|
||||
/* Set comment to string */
|
||||
void setcmt(char *s) { strcpy(cmtasm, s); }
|
||||
|
||||
/* Append string to comment */
|
||||
void addcmt(char *s) {
|
||||
if (strlen(cmtasm)+strlen(s)<73) strcat(cmtasm, s);
|
||||
}
|
||||
|
||||
/* Append character to comment */
|
||||
void chrcmt(char c) {
|
||||
if (strlen(cmtasm)>72) return;
|
||||
if (cmtasm[0] == 0 && c == ' ') return;
|
||||
int i = strlen(cmtasm);
|
||||
cmtasm[i++] = c;
|
||||
cmtasm[i] = 0;
|
||||
}
|
||||
|
276
src/cond.c
276
src/cond.c
@ -1,138 +1,138 @@
|
||||
/************************************
|
||||
* C02 Conditional Parsing Routines *
|
||||
************************************/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "common.h"
|
||||
#include "asm.h"
|
||||
#include "parse.h"
|
||||
#include "vars.h"
|
||||
#include "expr.h"
|
||||
#include "label.h"
|
||||
#include "cond.h"
|
||||
|
||||
int cmprtr; //Encoded Comparison Operator
|
||||
int cmpenc; //Encoded Comparator Character
|
||||
|
||||
/* Encode Comparison Operator Character *
|
||||
* Args: Comparison Operator Character *
|
||||
* Returns: Comparison Operator Bit Mask */
|
||||
int enccmp(char c) {
|
||||
int e;
|
||||
DEBUG("Encoding Comparison Character '%c'", c)
|
||||
switch(c) {
|
||||
case '=': e = 1; break;
|
||||
case '<': e = 2; break;
|
||||
case '>': e = 4; break;
|
||||
default: e = 0;
|
||||
}
|
||||
if (e) { CCMNT(c); skpchr(); }
|
||||
DETAIL(", encoded as %d\n", e);
|
||||
return e;
|
||||
}
|
||||
|
||||
/* Process and Compile Comparison Operator and *
|
||||
* Args: comparator - Encoded Comparison Operator *
|
||||
* Uses: term - Term Being Compared Against *
|
||||
* label - Branch Target if Comparison is FALSE */
|
||||
void prccmp(void) {
|
||||
DEBUG("Processing comparator %d", cmprtr) DETAIL(" with REVCMP=%d\n", revcmp)
|
||||
if (cmprtr > 7) { //Process Flag
|
||||
cmprtr = (cmprtr ^ revcmp) & 1; //Apply Reversal
|
||||
if (cmprtr) asmlin("BPL", cmplbl);
|
||||
else asmlin("BMI", cmplbl);
|
||||
return;
|
||||
}
|
||||
cmprtr = (cmprtr ^ revcmp) & 7; //Apply reversal
|
||||
switch(cmprtr) {
|
||||
case 0: // Raw Expression (Skip)
|
||||
asmlin("BEQ", cmplbl); break;
|
||||
case 1: // = or ==
|
||||
asmlin("CMP", term); asmlin("BNE", cmplbl); break;
|
||||
case 2: // <
|
||||
asmlin("CMP", term); asmlin("BCS", cmplbl); break;
|
||||
case 3: // <= or =<
|
||||
asmlin("CLC", ""); asmlin("SBC", term); asmlin("BCS", cmplbl); break;
|
||||
case 4: // >
|
||||
asmlin("CLC", ""); asmlin("SBC", term); asmlin("BCC", cmplbl); break;
|
||||
case 5: // >= or =>
|
||||
asmlin("CMP", term); asmlin("BCC", cmplbl); break;
|
||||
case 6: // <> or ><
|
||||
asmlin("CMP", term); asmlin("BEQ", cmplbl); break;
|
||||
case 7: // Raw Expression (Normal)
|
||||
asmlin("BNE", cmplbl); break;
|
||||
default:
|
||||
ERROR("Unsupported comparison operator index %d\n", cmprtr, EXIT_FAILURE)
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse Comparison */
|
||||
void prscmp(int revrse) {
|
||||
skpspc();
|
||||
cmpenc = enccmp(nxtchr); //Encode Comparison Character
|
||||
cmprtr = cmpenc; //Set Encoded Comparator
|
||||
if (cmprtr) {
|
||||
cmpenc = enccmp(nxtchr); //Encode Next Comparison Character
|
||||
if (cmpenc != 0) cmprtr = cmprtr | cmpenc; //Combine Encoded Comparator
|
||||
}
|
||||
skpspc();
|
||||
if (cmprtr) prstrm(FALSE);
|
||||
//prccmp(); - Do after check for logical operator
|
||||
DEBUG("Parsed comparator %d\n", cmprtr)
|
||||
}
|
||||
|
||||
/* Parse Flag Operator */
|
||||
void prsflg(int revrse) {
|
||||
DEBUG("Parsing Flag Operator '%c'\n", nxtchr)
|
||||
if (match('+')) cmprtr = 8; //Bit 0 = 0
|
||||
else if (match('-')) cmprtr = 9; //Bit 1 = 1
|
||||
else expctd("Flag operator");
|
||||
skpchr();
|
||||
}
|
||||
|
||||
/* Parse Logical Operator *
|
||||
* Sets: logops */
|
||||
void prslop(void) {
|
||||
DEBUG("Checking for Logical Operator\n", 0)
|
||||
logopr = LOPNONE;
|
||||
skpspc();
|
||||
if (isalph()) {
|
||||
getwrd(); //Get Logical Operator
|
||||
DEBUG("Parsing Logical Operator %s\n", word)
|
||||
if (wordis("AND")) logopr = LOPAND;
|
||||
else if (wordis("OR")) logopr = LOPOR;
|
||||
else ERROR("Encountered invalid token \"%s\"\n", word, EXIT_FAILURE)
|
||||
}
|
||||
DEBUG("Set LOGOPR to %d\n", logopr)
|
||||
}
|
||||
|
||||
/* Parse and Compile Conditional Expression *
|
||||
* Condition = <expression> <comparator> <term> */
|
||||
void prscnd(char trmntr, int revrse) {
|
||||
DEBUG("Parsing condition with REVRSE=%d\n", revrse)
|
||||
tmplbl[0] = 0;
|
||||
do {
|
||||
strcpy(cmplbl, cndlbl); DEBUG("Set CMPLBL to \"%s\"\n", cmplbl);
|
||||
revcmp = revrse;
|
||||
if (look('!')) revcmp = (revcmp) ? FALSE: TRUE;
|
||||
DEBUG("Set REVCMP to %d\n", revcmp)
|
||||
if (!look('.')) prsxpr(0);
|
||||
if (look(':')) prsflg(revcmp); //Parse Flag Operator
|
||||
else prscmp(revcmp); //Parse Comparison Operator
|
||||
prslop(); //Parse Logical Operator
|
||||
if (logopr == LOPOR) {
|
||||
revcmp = (revcmp) ? FALSE: TRUE;
|
||||
DEBUG("Set REVCMP to %d\n", revcmp)
|
||||
}
|
||||
if (logopr && revcmp) {
|
||||
if (!tmplbl[0]) newlbl(tmplbl);
|
||||
strcpy(cmplbl, tmplbl); DEBUG("Set CMPLBL to \"%s\"\n", cmplbl);
|
||||
}
|
||||
prccmp(); //Process Comparison/Flag Operator
|
||||
} while (logopr);
|
||||
if (tmplbl[0]) setlbl(tmplbl);
|
||||
expect(trmntr);
|
||||
}
|
||||
/************************************
|
||||
* C02 Conditional Parsing Routines *
|
||||
************************************/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "common.h"
|
||||
#include "asm.h"
|
||||
#include "parse.h"
|
||||
#include "vars.h"
|
||||
#include "expr.h"
|
||||
#include "label.h"
|
||||
#include "cond.h"
|
||||
|
||||
int cmprtr; //Encoded Comparison Operator
|
||||
int cmpenc; //Encoded Comparator Character
|
||||
|
||||
/* Encode Comparison Operator Character *
|
||||
* Args: Comparison Operator Character *
|
||||
* Returns: Comparison Operator Bit Mask */
|
||||
int enccmp(char c) {
|
||||
int e;
|
||||
DEBUG("Encoding Comparison Character '%c'", c)
|
||||
switch(c) {
|
||||
case '=': e = 1; break;
|
||||
case '<': e = 2; break;
|
||||
case '>': e = 4; break;
|
||||
default: e = 0;
|
||||
}
|
||||
if (e) { CCMNT(c); skpchr(); }
|
||||
DETAIL(", encoded as %d\n", e);
|
||||
return e;
|
||||
}
|
||||
|
||||
/* Process and Compile Comparison Operator and *
|
||||
* Args: comparator - Encoded Comparison Operator *
|
||||
* Uses: term - Term Being Compared Against *
|
||||
* label - Branch Target if Comparison is FALSE */
|
||||
void prccmp(void) {
|
||||
DEBUG("Processing comparator %d", cmprtr) DETAIL(" with REVCMP=%d\n", revcmp)
|
||||
if (cmprtr > 7) { //Process Flag
|
||||
cmprtr = (cmprtr ^ revcmp) & 1; //Apply Reversal
|
||||
if (cmprtr) asmlin("BPL", cmplbl);
|
||||
else asmlin("BMI", cmplbl);
|
||||
return;
|
||||
}
|
||||
cmprtr = (cmprtr ^ revcmp) & 7; //Apply reversal
|
||||
switch(cmprtr) {
|
||||
case 0: // Raw Expression (Skip)
|
||||
asmlin("BEQ", cmplbl); break;
|
||||
case 1: // = or ==
|
||||
asmlin("CMP", term); asmlin("BNE", cmplbl); break;
|
||||
case 2: // <
|
||||
asmlin("CMP", term); asmlin("BCS", cmplbl); break;
|
||||
case 3: // <= or =<
|
||||
asmlin("CLC", ""); asmlin("SBC", term); asmlin("BCS", cmplbl); break;
|
||||
case 4: // >
|
||||
asmlin("CLC", ""); asmlin("SBC", term); asmlin("BCC", cmplbl); break;
|
||||
case 5: // >= or =>
|
||||
asmlin("CMP", term); asmlin("BCC", cmplbl); break;
|
||||
case 6: // <> or ><
|
||||
asmlin("CMP", term); asmlin("BEQ", cmplbl); break;
|
||||
case 7: // Raw Expression (Normal)
|
||||
asmlin("BNE", cmplbl); break;
|
||||
default:
|
||||
ERROR("Unsupported comparison operator index %d\n", cmprtr, EXIT_FAILURE)
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse Comparison */
|
||||
void prscmp(int revrse) {
|
||||
skpspc();
|
||||
cmpenc = enccmp(nxtchr); //Encode Comparison Character
|
||||
cmprtr = cmpenc; //Set Encoded Comparator
|
||||
if (cmprtr) {
|
||||
cmpenc = enccmp(nxtchr); //Encode Next Comparison Character
|
||||
if (cmpenc != 0) cmprtr = cmprtr | cmpenc; //Combine Encoded Comparator
|
||||
}
|
||||
skpspc();
|
||||
if (cmprtr) prstrm(FALSE);
|
||||
//prccmp(); - Do after check for logical operator
|
||||
DEBUG("Parsed comparator %d\n", cmprtr)
|
||||
}
|
||||
|
||||
/* Parse Flag Operator */
|
||||
void prsflg(int revrse) {
|
||||
DEBUG("Parsing Flag Operator '%c'\n", nxtchr)
|
||||
if (match('+')) cmprtr = 8; //Bit 0 = 0
|
||||
else if (match('-')) cmprtr = 9; //Bit 1 = 1
|
||||
else expctd("Flag operator");
|
||||
skpchr();
|
||||
}
|
||||
|
||||
/* Parse Logical Operator *
|
||||
* Sets: logops */
|
||||
void prslop(void) {
|
||||
DEBUG("Checking for Logical Operator\n", 0)
|
||||
logopr = LOPNONE;
|
||||
skpspc();
|
||||
if (isalph()) {
|
||||
getwrd(); //Get Logical Operator
|
||||
DEBUG("Parsing Logical Operator %s\n", word)
|
||||
if (wordis("AND")) logopr = LOPAND;
|
||||
else if (wordis("OR")) logopr = LOPOR;
|
||||
else ERROR("Encountered invalid token \"%s\"\n", word, EXIT_FAILURE)
|
||||
}
|
||||
DEBUG("Set LOGOPR to %d\n", logopr)
|
||||
}
|
||||
|
||||
/* Parse and Compile Conditional Expression *
|
||||
* Condition = <expression> <comparator> <term> */
|
||||
void prscnd(char trmntr, int revrse) {
|
||||
DEBUG("Parsing condition with REVRSE=%d\n", revrse)
|
||||
tmplbl[0] = 0;
|
||||
do {
|
||||
strcpy(cmplbl, cndlbl); DEBUG("Set CMPLBL to \"%s\"\n", cmplbl);
|
||||
revcmp = revrse;
|
||||
if (look('!')) revcmp = (revcmp) ? FALSE: TRUE;
|
||||
DEBUG("Set REVCMP to %d\n", revcmp)
|
||||
if (!look('.')) prsxpr(0);
|
||||
if (look(':')) prsflg(revcmp); //Parse Flag Operator
|
||||
else prscmp(revcmp); //Parse Comparison Operator
|
||||
prslop(); //Parse Logical Operator
|
||||
if (logopr == LOPOR) {
|
||||
revcmp = (revcmp) ? FALSE: TRUE;
|
||||
DEBUG("Set REVCMP to %d\n", revcmp)
|
||||
}
|
||||
if (logopr && revcmp) {
|
||||
if (!tmplbl[0]) newlbl(tmplbl);
|
||||
strcpy(cmplbl, tmplbl); DEBUG("Set CMPLBL to \"%s\"\n", cmplbl);
|
||||
}
|
||||
prccmp(); //Process Comparison/Flag Operator
|
||||
} while (logopr);
|
||||
if (tmplbl[0]) setlbl(tmplbl);
|
||||
expect(trmntr);
|
||||
}
|
||||
|
20
src/cond.h
20
src/cond.h
@ -1,10 +1,10 @@
|
||||
/************************************
|
||||
* C02 Conditional Parsing Routines *
|
||||
************************************/
|
||||
|
||||
enum LOGOPS {LOPNONE, LOPAND, LOPOR};
|
||||
|
||||
int revcmp; //Reverse Comparison
|
||||
int logopr; //Logical Operator (set to LOGOPS)
|
||||
|
||||
void prscnd(char trmntr, int revrse); //Parse Conditional Expression
|
||||
/************************************
|
||||
* C02 Conditional Parsing Routines *
|
||||
************************************/
|
||||
|
||||
enum LOGOPS {LOPNONE, LOPAND, LOPOR};
|
||||
|
||||
int revcmp; //Reverse Comparison
|
||||
int logopr; //Logical Operator (set to LOGOPS)
|
||||
|
||||
void prscnd(char trmntr, int revrse); //Parse Conditional Expression
|
||||
|
34
src/dclrtn.h
34
src/dclrtn.h
@ -1,17 +1,17 @@
|
||||
/************************************
|
||||
* 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+3]; //Function Parameter Y
|
||||
int prmcnt; //Number of Parameters
|
||||
//int lpemtd; //Location Prefix Emitted
|
||||
|
||||
void addcon(int numval); //Add Constant
|
||||
int pmodfr(); //Check for and Parse Modifier
|
||||
int ctype(int reqtyp); //Check for Type Keyword
|
||||
int ptype(int m); //Check for and Parse Type Keyword
|
||||
|
||||
enum types {TNONE, TVOID, TENUM, TBITMASK,TCHAR, TINT, TSTRUCT};
|
||||
/************************************
|
||||
* 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+3]; //Function Parameter Y
|
||||
int prmcnt; //Number of Parameters
|
||||
//int lpemtd; //Location Prefix Emitted
|
||||
|
||||
void addcon(int numval); //Add Constant
|
||||
int pmodfr(); //Check for and Parse Modifier
|
||||
int ctype(int reqtyp); //Check for Type Keyword
|
||||
int ptype(int m); //Check for and Parse Type Keyword
|
||||
|
||||
enum types {TNONE, TVOID, TENUM, TBITMASK,TCHAR, TINT, TSTRUCT};
|
||||
|
204
src/files.c
204
src/files.c
@ -1,102 +1,102 @@
|
||||
/******************************
|
||||
* C02 File Handling Routines *
|
||||
******************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "files.h"
|
||||
|
||||
/* Error - Print textual description of system error *
|
||||
* and exit with system error code */
|
||||
void extsys(char *s) {
|
||||
perror(s);
|
||||
exterr(errno);
|
||||
}
|
||||
|
||||
/* Open Source File *
|
||||
* Uses: srcnam - Source File Name *
|
||||
* Sets: srcfil - Source File Handle */
|
||||
void opnsrc(void) {
|
||||
DEBUG("Processing Source File Name '%s'\n", srcnam)
|
||||
if (strrchr(srcnam, '.') == NULL) strcat(srcnam, ".c02"); //if no extension. add ".c02"
|
||||
DEBUG("opening Source File '%s'\n", srcnam)
|
||||
srcfil = fopen(srcnam, "r"); //open file
|
||||
if (srcfil == NULL) extsys(srcnam);
|
||||
}
|
||||
|
||||
/* Close Source File */
|
||||
void clssrc(void) { fclose(srcfil); }
|
||||
|
||||
/* Open Output File *
|
||||
* Uses: outnam - Output File Name *
|
||||
* Sets: outfil - Output File Handle */
|
||||
void opnout(void) {
|
||||
DEBUG("Processing Output File Name '%s'\n", outnam)
|
||||
if (strlen(outnam) == 0) //if Output File not specified
|
||||
{
|
||||
strcpy(outnam, srcnam); //copy Source Name to Ouput Name
|
||||
char *dot = strrchr(outnam, '.'); //find extension
|
||||
if (dot != NULL) *dot = 0; //and remove it
|
||||
DEBUG("Set Output File Name to '%s'\n", outnam)
|
||||
}
|
||||
if (strrchr(outnam, '.') == NULL) strcat(outnam, ".asm"); //if no extension, add ".asm"
|
||||
DEBUG("Opening Output File '%s'\n", outnam)
|
||||
outfil = fopen(outnam, "w"); //open file
|
||||
if (outfil == NULL) extsys(outnam);
|
||||
}
|
||||
|
||||
/* Close Output File */
|
||||
void clsout(void) {
|
||||
fprintf(outfil, "\n");
|
||||
fclose(outfil);
|
||||
}
|
||||
|
||||
/* Open Log File *
|
||||
* Uses: srcnam - Source File Name *
|
||||
* Sets: logfil - Log File Handle */
|
||||
void opnlog(void) {
|
||||
strcpy(lognam, srcnam); //set Log File Name to Source File Name
|
||||
char *dot = strrchr(lognam, '.'); //find file extension
|
||||
if (dot != NULL) *dot = 0; //and remove it
|
||||
strcat(lognam, ".log"); //add extension ".log"
|
||||
DEBUG("Opening Log File '%s'\n", lognam)
|
||||
logfil = fopen(lognam, "w");
|
||||
if (logfil == NULL) extsys(lognam);
|
||||
}
|
||||
|
||||
/* Close Log File *
|
||||
* Uses: logfil - Log File Handle */
|
||||
void clslog(void) { fclose(logfil); }
|
||||
|
||||
/* Open Include file *
|
||||
* Uses: incnam - Include File Name *
|
||||
* subnam - Include File Name (Subdirectory) *
|
||||
* Sets: incfil - Include File Handle */
|
||||
void opninc(int chksub)
|
||||
{
|
||||
if (chksub) {
|
||||
for (subidx=0; subidx<subcnt; subidx++) {
|
||||
DEBUG("Attempting to open include file '%s'\n", subnam[subidx])
|
||||
incfil = fopen(subnam[subidx], "r");
|
||||
if (incfil == NULL) DEBUG("Open failed\n", 0)
|
||||
else {
|
||||
strcpy(incnam, subnam[subidx]);
|
||||
DEBUG("INCNAM set to '%s'\n", incnam);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG("Opening include file '%s'\n", incnam)
|
||||
incfil = fopen(incnam, "r");
|
||||
if (incfil == NULL) extsys(incnam);
|
||||
}
|
||||
|
||||
/* Close Include File *
|
||||
* Uses: incfil - Include File Handle */
|
||||
void clsinc(void) { fclose(incfil); }
|
||||
/******************************
|
||||
* C02 File Handling Routines *
|
||||
******************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "files.h"
|
||||
|
||||
/* Error - Print textual description of system error *
|
||||
* and exit with system error code */
|
||||
void extsys(char *s) {
|
||||
perror(s);
|
||||
exterr(errno);
|
||||
}
|
||||
|
||||
/* Open Source File *
|
||||
* Uses: srcnam - Source File Name *
|
||||
* Sets: srcfil - Source File Handle */
|
||||
void opnsrc(void) {
|
||||
DEBUG("Processing Source File Name '%s'\n", srcnam)
|
||||
if (strrchr(srcnam, '.') == NULL) strcat(srcnam, ".c02"); //if no extension. add ".c02"
|
||||
DEBUG("opening Source File '%s'\n", srcnam)
|
||||
srcfil = fopen(srcnam, "r"); //open file
|
||||
if (srcfil == NULL) extsys(srcnam);
|
||||
}
|
||||
|
||||
/* Close Source File */
|
||||
void clssrc(void) { fclose(srcfil); }
|
||||
|
||||
/* Open Output File *
|
||||
* Uses: outnam - Output File Name *
|
||||
* Sets: outfil - Output File Handle */
|
||||
void opnout(void) {
|
||||
DEBUG("Processing Output File Name '%s'\n", outnam)
|
||||
if (strlen(outnam) == 0) //if Output File not specified
|
||||
{
|
||||
strcpy(outnam, srcnam); //copy Source Name to Ouput Name
|
||||
char *dot = strrchr(outnam, '.'); //find extension
|
||||
if (dot != NULL) *dot = 0; //and remove it
|
||||
DEBUG("Set Output File Name to '%s'\n", outnam)
|
||||
}
|
||||
if (strrchr(outnam, '.') == NULL) strcat(outnam, ".asm"); //if no extension, add ".asm"
|
||||
DEBUG("Opening Output File '%s'\n", outnam)
|
||||
outfil = fopen(outnam, "w"); //open file
|
||||
if (outfil == NULL) extsys(outnam);
|
||||
}
|
||||
|
||||
/* Close Output File */
|
||||
void clsout(void) {
|
||||
fprintf(outfil, "\n");
|
||||
fclose(outfil);
|
||||
}
|
||||
|
||||
/* Open Log File *
|
||||
* Uses: srcnam - Source File Name *
|
||||
* Sets: logfil - Log File Handle */
|
||||
void opnlog(void) {
|
||||
strcpy(lognam, srcnam); //set Log File Name to Source File Name
|
||||
char *dot = strrchr(lognam, '.'); //find file extension
|
||||
if (dot != NULL) *dot = 0; //and remove it
|
||||
strcat(lognam, ".log"); //add extension ".log"
|
||||
DEBUG("Opening Log File '%s'\n", lognam)
|
||||
logfil = fopen(lognam, "w");
|
||||
if (logfil == NULL) extsys(lognam);
|
||||
}
|
||||
|
||||
/* Close Log File *
|
||||
* Uses: logfil - Log File Handle */
|
||||
void clslog(void) { fclose(logfil); }
|
||||
|
||||
/* Open Include file *
|
||||
* Uses: incnam - Include File Name *
|
||||
* subnam - Include File Name (Subdirectory) *
|
||||
* Sets: incfil - Include File Handle */
|
||||
void opninc(int chksub)
|
||||
{
|
||||
if (chksub) {
|
||||
for (subidx=0; subidx<subcnt; subidx++) {
|
||||
DEBUG("Attempting to open include file '%s'\n", subnam[subidx])
|
||||
incfil = fopen(subnam[subidx], "r");
|
||||
if (incfil == NULL) DEBUG("Open failed\n", 0)
|
||||
else {
|
||||
strcpy(incnam, subnam[subidx]);
|
||||
DEBUG("INCNAM set to '%s'\n", incnam);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG("Opening include file '%s'\n", incnam)
|
||||
incfil = fopen(incnam, "r");
|
||||
if (incfil == NULL) extsys(incnam);
|
||||
}
|
||||
|
||||
/* Close Include File *
|
||||
* Uses: incfil - Include File Handle */
|
||||
void clsinc(void) { fclose(incfil); }
|
||||
|
54
src/files.h
54
src/files.h
@ -1,27 +1,27 @@
|
||||
/******************************
|
||||
* C02 File Handling Routines *
|
||||
******************************/
|
||||
|
||||
FILE *srcfil; //Source File (Input)
|
||||
FILE *outfil; //Assembler File (Output)
|
||||
FILE *logfil; //Log File (Output)
|
||||
FILE *incfil; //Include File Handle
|
||||
FILE *inpfil; //Current Input File
|
||||
|
||||
char srcnam[FNAMLEN]; //Source File Name
|
||||
char outnam[FNAMLEN]; //Assembler File Name
|
||||
char lognam[FNAMLEN]; //Log File Name
|
||||
char incnam[FNAMLEN]; //Include File Name
|
||||
char subnam[SUBMAX][FNAMLEN]; //Include File Name (Subdirectory)
|
||||
|
||||
void opnsrc(); //Open Source File
|
||||
void clssrc(); //Close Source File
|
||||
|
||||
void opnout(); //Open Output File
|
||||
void clsout(); //Close Output File
|
||||
|
||||
void opnlog(); //Open Log File
|
||||
void clslog(); //Close Log File
|
||||
|
||||
void opninc(int chksub); //Open Include File
|
||||
void clsinc(); //Close Include File
|
||||
/******************************
|
||||
* C02 File Handling Routines *
|
||||
******************************/
|
||||
|
||||
FILE *srcfil; //Source File (Input)
|
||||
FILE *outfil; //Assembler File (Output)
|
||||
FILE *logfil; //Log File (Output)
|
||||
FILE *incfil; //Include File Handle
|
||||
FILE *inpfil; //Current Input File
|
||||
|
||||
char srcnam[FNAMLEN]; //Source File Name
|
||||
char outnam[FNAMLEN]; //Assembler File Name
|
||||
char lognam[FNAMLEN]; //Log File Name
|
||||
char incnam[FNAMLEN]; //Include File Name
|
||||
char subnam[SUBMAX][FNAMLEN]; //Include File Name (Subdirectory)
|
||||
|
||||
void opnsrc(); //Open Source File
|
||||
void clssrc(); //Close Source File
|
||||
|
||||
void opnout(); //Open Output File
|
||||
void clsout(); //Close Output File
|
||||
|
||||
void opnlog(); //Open Log File
|
||||
void clslog(); //Close Log File
|
||||
|
||||
void opninc(int chksub); //Open Include File
|
||||
void clsinc(); //Close Include File
|
||||
|
@ -86,7 +86,7 @@ void pdefin(void) {
|
||||
|
||||
/* Parse ASCII Subdirective */
|
||||
void pascii(void) {
|
||||
getwrd(); //Get Pragma Subdirective
|
||||
getwrd(); //Get Subdirective Argument
|
||||
DEBUG("Parsing subdirective '%s'\n", word)
|
||||
if (wordis("INVERT"))
|
||||
invasc = TRUE;
|
||||
|
@ -1,14 +1,14 @@
|
||||
/*************************************
|
||||
* C02 Include File Parsing Routines *
|
||||
*************************************/
|
||||
|
||||
char line[255]; /*Entire line parsed from include file*/
|
||||
|
||||
void logcon(); //Print Constant Table to Log File
|
||||
void pdefin(); //Process define directive
|
||||
void pdefin(); //Process define directive
|
||||
void penumd(); //Process enum directive
|
||||
void phdrfl(); //Process command line header file
|
||||
void pincfl(); //Process include file
|
||||
void pprgma(); //Parse Pragma Directive
|
||||
void setsrc(); ///Set Input to Source File
|
||||
/*************************************
|
||||
* C02 Include File Parsing Routines *
|
||||
*************************************/
|
||||
|
||||
char line[255]; /*Entire line parsed from include file*/
|
||||
|
||||
void logcon(); //Print Constant Table to Log File
|
||||
void pdefin(); //Process define directive
|
||||
void pdefin(); //Process define directive
|
||||
void penumd(); //Process enum directive
|
||||
void phdrfl(); //Process command line header file
|
||||
void pincfl(); //Process include file
|
||||
void pprgma(); //Parse Pragma Directive
|
||||
void setsrc(); ///Set Input to Source File
|
||||
|
306
src/label.c
306
src/label.c
@ -1,153 +1,153 @@
|
||||
/******************************************************
|
||||
* C02 Label Parsing, Generation, and Lookup Routines *
|
||||
******************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "files.h"
|
||||
#include "asm.h"
|
||||
#include "parse.h"
|
||||
#include "label.h"
|
||||
#include "vars.h"
|
||||
|
||||
/* Add New Program Label */
|
||||
void addlab(char *name) {
|
||||
if (fndvar(name)) ERROR("Label %s conflicts with variable with same name", name, EXIT_FAILURE)
|
||||
if (fndlab(name)) ERROR("Duplicate program label %s\n", name, EXIT_FAILURE)
|
||||
DEBUG("Adding Program Label %s ", name) DEBUG("at index %d\n", labcnt)
|
||||
strcpy(labnam[labcnt++], name);
|
||||
}
|
||||
|
||||
int fndlab(char *name) {
|
||||
DEBUG("Looking for Program Label %s\n", name)
|
||||
for (labidx=0; labidx<labcnt; labidx++)
|
||||
if (strcmp(labnam[labidx], name) == 0) return TRUE;
|
||||
DEBUG("Label %s Not Found\n", name)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Print Program Label Table to Log File */
|
||||
void loglab(void) {
|
||||
int i;
|
||||
fprintf(logfil, "\n%-10s\n", "Label");
|
||||
for (i=0; i<labcnt; i++) {
|
||||
fprintf(logfil, "%-10s\n", labnam[i]);
|
||||
}
|
||||
}
|
||||
|
||||
const char lblflg[] = {LFNONE, LFNONE, LFNONE, LFBGN, LFEND, LFBGN, LFEND, LFEND, LFNONE, LFNONE}; //Label Type Flags
|
||||
// enum ltypes {LTNONE, LTIF, LTELSE, LTLOOP, LTEND, LTDO, LTDWHL, LTSLCT, LTCASE, LTFUNC}; //Label Types
|
||||
|
||||
/* Find Last Label of Specified Types *
|
||||
* Args: lbtyp1: First label type *
|
||||
* lbtyp2: Second label type *
|
||||
* Sets: tmplbl - Label name *
|
||||
* Returns: Index into label table *
|
||||
* (-1 if not found) */
|
||||
int lstlbl(int lbflag) {
|
||||
int i;
|
||||
DEBUG("Searching for label flag %d\n", lbflag)
|
||||
for (i = lblcnt - 1; i>-1; i--)
|
||||
if (lblflg[lbltyp[i]] == lbflag) 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 *
|
||||
* Assembly Language Code *
|
||||
* to word */
|
||||
void setlbl(char *lblset) {
|
||||
DEBUG("Setting Label '%s'\n", lblset)
|
||||
if (strlen(lblasm) > 0) {
|
||||
DEBUG("Emitting Label '%s'\n'", lblasm);
|
||||
asmlin("",""); //Emit Block End Label on it's own line
|
||||
}
|
||||
if (strlen(lblset) > LBLLEN) ERROR("Label '%s' exceeds maximum size\n", word, EXIT_FAILURE)
|
||||
strcpy(lblasm, lblset);
|
||||
}
|
||||
|
||||
/* Parse Program Label */
|
||||
void prslab(void) {
|
||||
DEBUG("Parsing Label '%s''\n", word)
|
||||
addlab(word);
|
||||
CCMNT(nxtchr);
|
||||
skpchr(); //skip ':'
|
||||
}
|
||||
|
||||
/* generate new label */
|
||||
void newlbl(char* lbname) {
|
||||
sprintf(lbname, LBLFMT, lblnxt++);
|
||||
DEBUG("Generated new label '%s'\n", lbname)
|
||||
}
|
||||
|
||||
/* Check Label Contents *
|
||||
* If lbname is blank, generate new *
|
||||
* label and copy into lbname */
|
||||
void chklbl(char* lbname) {
|
||||
if (lbname[0]) return;
|
||||
newlbl(lbname);
|
||||
}
|
||||
|
||||
/* Request Label *
|
||||
* if label is already set, returns that label *
|
||||
* else generates new label and sets it */
|
||||
void reqlbl(char* lbname) {
|
||||
DEBUG("Requesting Label\n",0)
|
||||
if (lblasm[0] == 0) {newlbl(lbname); setlbl(lbname);}
|
||||
else {strcpy(lbname,lblasm); DEBUG("Found lblasm set to \"%s\"\n", lblasm)}
|
||||
}
|
||||
|
||||
/* 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: 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;
|
||||
case LTLOOP: asmlin("JMP", lblnam[lblcnt--]); //Jump to Beginning of Loop
|
||||
default: setlbl(lblnam[lblcnt]); //Emit End of Loop Label
|
||||
}
|
||||
if (lbtype != LTCASE) inblck = lblblk[lblcnt-1];
|
||||
return lbtype;
|
||||
}
|
||||
|
||||
/* Get Top Label and Return Type */
|
||||
int toplbl(char *rtlbl) {
|
||||
if (lblcnt) {
|
||||
strcpy(rtlbl, lblnam[lblcnt-1]);
|
||||
DEBUG("Found top label %s\n", rtlbl)
|
||||
return lbltyp[lblcnt-1];
|
||||
}
|
||||
rtlbl[0] = 0; //Clear Label
|
||||
return LTNONE;
|
||||
}
|
||||
|
||||
/* Push Label onto Stack *
|
||||
* Args: lbltyp - Label type *
|
||||
* Uses: curlbl - Label to push */
|
||||
void pshlbl(int lbtype, char* lbname) {
|
||||
DEBUG("Pushing label type %d\n", lbtype)
|
||||
strcpy(lblnam[lblcnt], lbname);
|
||||
lbltyp[lblcnt] = lbtype;
|
||||
lblblk[lblcnt++] = FALSE;
|
||||
DEBUG("Pushed label '%s' onto stack\n", lbname)
|
||||
}
|
||||
/******************************************************
|
||||
* C02 Label Parsing, Generation, and Lookup Routines *
|
||||
******************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "files.h"
|
||||
#include "asm.h"
|
||||
#include "parse.h"
|
||||
#include "label.h"
|
||||
#include "vars.h"
|
||||
|
||||
/* Add New Program Label */
|
||||
void addlab(char *name) {
|
||||
if (fndvar(name)) ERROR("Label %s conflicts with variable with same name", name, EXIT_FAILURE)
|
||||
if (fndlab(name)) ERROR("Duplicate program label %s\n", name, EXIT_FAILURE)
|
||||
DEBUG("Adding Program Label %s ", name) DEBUG("at index %d\n", labcnt)
|
||||
strcpy(labnam[labcnt++], name);
|
||||
}
|
||||
|
||||
int fndlab(char *name) {
|
||||
DEBUG("Looking for Program Label %s\n", name)
|
||||
for (labidx=0; labidx<labcnt; labidx++)
|
||||
if (strcmp(labnam[labidx], name) == 0) return TRUE;
|
||||
DEBUG("Label %s Not Found\n", name)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Print Program Label Table to Log File */
|
||||
void loglab(void) {
|
||||
int i;
|
||||
fprintf(logfil, "\n%-10s\n", "Label");
|
||||
for (i=0; i<labcnt; i++) {
|
||||
fprintf(logfil, "%-10s\n", labnam[i]);
|
||||
}
|
||||
}
|
||||
|
||||
const char lblflg[] = {LFNONE, LFNONE, LFNONE, LFBGN, LFEND, LFBGN, LFEND, LFEND, LFNONE, LFNONE}; //Label Type Flags
|
||||
// enum ltypes {LTNONE, LTIF, LTELSE, LTLOOP, LTEND, LTDO, LTDWHL, LTSLCT, LTCASE, LTFUNC}; //Label Types
|
||||
|
||||
/* Find Last Label of Specified Types *
|
||||
* Args: lbtyp1: First label type *
|
||||
* lbtyp2: Second label type *
|
||||
* Sets: tmplbl - Label name *
|
||||
* Returns: Index into label table *
|
||||
* (-1 if not found) */
|
||||
int lstlbl(int lbflag) {
|
||||
int i;
|
||||
DEBUG("Searching for label flag %d\n", lbflag)
|
||||
for (i = lblcnt - 1; i>-1; i--)
|
||||
if (lblflg[lbltyp[i]] == lbflag) 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 *
|
||||
* Assembly Language Code *
|
||||
* to word */
|
||||
void setlbl(char *lblset) {
|
||||
DEBUG("Setting Label '%s'\n", lblset)
|
||||
if (strlen(lblasm) > 0) {
|
||||
DEBUG("Emitting Label '%s'\n'", lblasm);
|
||||
asmlin("",""); //Emit Block End Label on it's own line
|
||||
}
|
||||
if (strlen(lblset) > LBLLEN) ERROR("Label '%s' exceeds maximum size\n", word, EXIT_FAILURE)
|
||||
strcpy(lblasm, lblset);
|
||||
}
|
||||
|
||||
/* Parse Program Label */
|
||||
void prslab(void) {
|
||||
DEBUG("Parsing Label '%s''\n", word)
|
||||
addlab(word);
|
||||
CCMNT(nxtchr);
|
||||
skpchr(); //skip ':'
|
||||
}
|
||||
|
||||
/* generate new label */
|
||||
void newlbl(char* lbname) {
|
||||
sprintf(lbname, LBLFMT, lblnxt++);
|
||||
DEBUG("Generated new label '%s'\n", lbname)
|
||||
}
|
||||
|
||||
/* Check Label Contents *
|
||||
* If lbname is blank, generate new *
|
||||
* label and copy into lbname */
|
||||
void chklbl(char* lbname) {
|
||||
if (lbname[0]) return;
|
||||
newlbl(lbname);
|
||||
}
|
||||
|
||||
/* Request Label *
|
||||
* if label is already set, returns that label *
|
||||
* else generates new label and sets it */
|
||||
void reqlbl(char* lbname) {
|
||||
DEBUG("Requesting Label\n",0)
|
||||
if (lblasm[0] == 0) {newlbl(lbname); setlbl(lbname);}
|
||||
else {strcpy(lbname,lblasm); DEBUG("Found lblasm set to \"%s\"\n", lblasm)}
|
||||
}
|
||||
|
||||
/* 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: 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;
|
||||
case LTLOOP: asmlin("JMP", lblnam[lblcnt--]); //Jump to Beginning of Loop
|
||||
default: setlbl(lblnam[lblcnt]); //Emit End of Loop Label
|
||||
}
|
||||
if (lbtype != LTCASE) inblck = lblblk[lblcnt-1];
|
||||
return lbtype;
|
||||
}
|
||||
|
||||
/* Get Top Label and Return Type */
|
||||
int toplbl(char *rtlbl) {
|
||||
if (lblcnt) {
|
||||
strcpy(rtlbl, lblnam[lblcnt-1]);
|
||||
DEBUG("Found top label %s\n", rtlbl)
|
||||
return lbltyp[lblcnt-1];
|
||||
}
|
||||
rtlbl[0] = 0; //Clear Label
|
||||
return LTNONE;
|
||||
}
|
||||
|
||||
/* Push Label onto Stack *
|
||||
* Args: lbltyp - Label type *
|
||||
* Uses: curlbl - Label to push */
|
||||
void pshlbl(int lbtype, char* lbname) {
|
||||
DEBUG("Pushing label type %d\n", lbtype)
|
||||
strcpy(lblnam[lblcnt], lbname);
|
||||
lbltyp[lblcnt] = lbtype;
|
||||
lblblk[lblcnt++] = FALSE;
|
||||
DEBUG("Pushed label '%s' onto stack\n", lbname)
|
||||
}
|
||||
|
82
src/label.h
82
src/label.h
@ -1,41 +1,41 @@
|
||||
/******************************************************
|
||||
* C02 Label Parsing, Generation, and Lookup Routines *
|
||||
******************************************************/
|
||||
|
||||
char labnam[MAXLAB+1][LABLEN+1]; //Program Label Names
|
||||
int labcnt; //Number of Program Labels
|
||||
int labidx; //Index into labnam[]
|
||||
|
||||
char curlbl[LBLLEN+1]; //Most recently generated label
|
||||
char cmplbl[LBLLEN+1]; //Label for Comparison
|
||||
char cndlbl[LBLLEN+1]; //Label for Conditional Code
|
||||
char endlbl[LBLLEN+1]; //End Label
|
||||
char forlbl[LBLLEN+1]; //For Loop Label
|
||||
char loplbl[LBLLEN+1]; //Skip Increment Label
|
||||
char skplbl[LBLLEN+1]; //Skip Increment Label
|
||||
char tmplbl[LBLLEN+1]; //Temporary Label
|
||||
char lblnam[MAXLBL+1][LBLLEN+1]; //Label Name Table
|
||||
int lbltyp[MAXLBL+1]; //Label Type
|
||||
int lblblk[MAXLBL+1]; //Label Ends Program Block
|
||||
int lblcnt; //Number of Labels in stack
|
||||
int lblnxt; //Sequence of next label to be generated
|
||||
char lbltmp[LBLLEN+1]; //Label Temporary Storage
|
||||
|
||||
enum ltypes {LTNONE, LTIF, LTELSE, LTLOOP, LTEND, LTDO, LTDWHL, LTSLCT, LTCASE, LTFUNC}; //Label Types
|
||||
enum lflags {LFNONE, LFBGN, LFEND}; //Label Flag Types
|
||||
|
||||
void addlab(char *name); //Add Program Label
|
||||
int fndlab(char *name); //Find Program Label
|
||||
void prslab(); //Parse Program Label
|
||||
void loglab(void); //Print Program Label Table
|
||||
|
||||
void chklbl(char* lbname); //Check Label Contents
|
||||
int lstlbl(int lbflag); //Find Last Label of Specified Types *
|
||||
void newlbl(char* lbname); //Generate New Block Label
|
||||
int poplbl(); //Pop Last Label and Emit on Next Line
|
||||
void pshlbl(int lbtype, char* lbname); //Push Label onto Stack
|
||||
void reqlbl(char* lbname); //Require Label
|
||||
void setblk(int blkflg); //Set Block Flag for Last Label
|
||||
void setlbl(char *lblset); //Emit word as Label on Next Line
|
||||
int toplbl(char *rtlbl); //Get Top Label and Return Type
|
||||
|
||||
/******************************************************
|
||||
* C02 Label Parsing, Generation, and Lookup Routines *
|
||||
******************************************************/
|
||||
|
||||
char labnam[MAXLAB+1][LABLEN+1]; //Program Label Names
|
||||
int labcnt; //Number of Program Labels
|
||||
int labidx; //Index into labnam[]
|
||||
|
||||
char curlbl[LBLLEN+1]; //Most recently generated label
|
||||
char cmplbl[LBLLEN+1]; //Label for Comparison
|
||||
char cndlbl[LBLLEN+1]; //Label for Conditional Code
|
||||
char endlbl[LBLLEN+1]; //End Label
|
||||
char forlbl[LBLLEN+1]; //For Loop Label
|
||||
char loplbl[LBLLEN+1]; //Skip Increment Label
|
||||
char skplbl[LBLLEN+1]; //Skip Increment Label
|
||||
char tmplbl[LBLLEN+1]; //Temporary Label
|
||||
char lblnam[MAXLBL+1][LBLLEN+1]; //Label Name Table
|
||||
int lbltyp[MAXLBL+1]; //Label Type
|
||||
int lblblk[MAXLBL+1]; //Label Ends Program Block
|
||||
int lblcnt; //Number of Labels in stack
|
||||
int lblnxt; //Sequence of next label to be generated
|
||||
char lbltmp[LBLLEN+1]; //Label Temporary Storage
|
||||
|
||||
enum ltypes {LTNONE, LTIF, LTELSE, LTLOOP, LTEND, LTDO, LTDWHL, LTSLCT, LTCASE, LTFUNC}; //Label Types
|
||||
enum lflags {LFNONE, LFBGN, LFEND}; //Label Flag Types
|
||||
|
||||
void addlab(char *name); //Add Program Label
|
||||
int fndlab(char *name); //Find Program Label
|
||||
void prslab(); //Parse Program Label
|
||||
void loglab(void); //Print Program Label Table
|
||||
|
||||
void chklbl(char* lbname); //Check Label Contents
|
||||
int lstlbl(int lbflag); //Find Last Label of Specified Types *
|
||||
void newlbl(char* lbname); //Generate New Block Label
|
||||
int poplbl(); //Pop Last Label and Emit on Next Line
|
||||
void pshlbl(int lbtype, char* lbname); //Push Label onto Stack
|
||||
void reqlbl(char* lbname); //Require Label
|
||||
void setblk(int blkflg); //Set Block Flag for Last Label
|
||||
void setlbl(char *lblset); //Emit word as Label on Next Line
|
||||
int toplbl(char *rtlbl); //Get Top Label and Return Type
|
||||
|
||||
|
42
src/stmnt.h
42
src/stmnt.h
@ -1,21 +1,21 @@
|
||||
/************************************
|
||||
* C02 Statement Compiling Routines *
|
||||
************************************/
|
||||
|
||||
char asnvar[VARLEN+1]; //Assigned Variable Name
|
||||
int asntyp; //Assigned Variable Type
|
||||
char asnidx[VARLEN+1] ; //Assigned Variable Index
|
||||
int asnivt; //Assigned Index Variable Type
|
||||
char ysnvar[VARLEN+1]; //Assigned Y Variable Name
|
||||
char ysnidx[VARLEN+1] ; //Assigned Y Variable Index
|
||||
int ysnivt; //Assigned Y Index Variable Type
|
||||
char xsnvar[VARLEN+1]; //Assigned X Variable Name
|
||||
char xsnidx[VARLEN+1] ; //Assigned X Variable Index
|
||||
int xsnivt; //Assigned X Index Variable Type
|
||||
|
||||
char xstmnt[LINELEN]; //Expected Statement
|
||||
|
||||
void bgnblk(char blkchr); //End Program Block
|
||||
void endblk(int blkflg); //End Program Block
|
||||
void pdowhl(); //Parse and Compile WHILE after DO
|
||||
void pstmnt(); //Parse and Compile Program Statement
|
||||
/************************************
|
||||
* C02 Statement Compiling Routines *
|
||||
************************************/
|
||||
|
||||
char asnvar[VARLEN+1]; //Assigned Variable Name
|
||||
int asntyp; //Assigned Variable Type
|
||||
char asnidx[VARLEN+1] ; //Assigned Variable Index
|
||||
int asnivt; //Assigned Index Variable Type
|
||||
char ysnvar[VARLEN+1]; //Assigned Y Variable Name
|
||||
char ysnidx[VARLEN+1] ; //Assigned Y Variable Index
|
||||
int ysnivt; //Assigned Y Index Variable Type
|
||||
char xsnvar[VARLEN+1]; //Assigned X Variable Name
|
||||
char xsnidx[VARLEN+1] ; //Assigned X Variable Index
|
||||
int xsnivt; //Assigned X Index Variable Type
|
||||
|
||||
char xstmnt[LINELEN]; //Expected Statement
|
||||
|
||||
void bgnblk(char blkchr); //End Program Block
|
||||
void endblk(int blkflg); //End Program Block
|
||||
void pdowhl(); //Parse and Compile WHILE after DO
|
||||
void pstmnt(); //Parse and Compile Program Statement
|
||||
|
Loading…
Reference in New Issue
Block a user