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

Added pointer dereferencing to C02 compiler

This commit is contained in:
Curtis F Kaylor 2019-11-14 11:13:45 -05:00
parent 9478d41299
commit f94ddd63fc
10 changed files with 141 additions and 53 deletions

View File

@ -56,6 +56,13 @@ void init(void) {
strcpy(incdir, "../include/");
}
/* Parse Pointer Dereference Assignment */
void ppntr(void) {
lsrtrn = FALSE; //Clear RETURN flag
if (xstmnt[0]) ERROR("Expected '%s' statement\n", xstmnt, EXIT_FAILURE)
prcasp(';');
}
/* Reads and parses the next Word in Source File */
void pword(void) {
lsrtrn = FALSE; //Clear RETURN flag
@ -111,6 +118,7 @@ void compile(void) {
else if (match('}')) endblk(TRUE); //End Multi-Line Program Block
else if (match('#')) pdrctv(); //Parse Directive
else if (match('/')) skpcmt(TRUE); //Skip Comment
else if (match('*')) ppntr(); //Parse Pointer
else if (isalph()) pword(); //Parse Word
else ERROR("Unexpected character '%c'\n", nxtchr, EXIT_FAILURE)
}

View File

@ -29,7 +29,7 @@
#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 BYTEOP "BYTE" //Define Byte Pseudo-Op
#define STROP "DS" //Define String Pseudo-Op
#define ALNOP "ALIGN" //Align Pseudo-Op
#define USEGOP "SEG.U" //Uninitalized Segment Pseudo-Op

View File

@ -53,6 +53,7 @@ void addfnc(void) {
infunc = TRUE; //Set Inside Function Definition Flag
DEBUG("Set infunc to %d\n", infunc)
setlbl(fncnam); //Set Function Entry Point
asmlin(LOCOP, ""); //Set Local Variables Boundary
if (prmtra[0]) asmlin("STA", prmtra); //Store First Parameter
if (prmtry[0]) asmlin("STY", prmtry); //Store Second Parameter
if (prmtrx[0]) asmlin("STX", prmtrx); //Store Third Parameter

View File

@ -111,10 +111,43 @@ void chkidx(void) {
}
}
/* Parse Term in Expression *
* Sets: term - the term (as a string) */
/* Parse Pointer *
* Sets: term - Compiled Pointer */
void prsptr(void) {
DEBUG("Parsing pointer\n", 0)
expect('*'); //Pointer Dereference Operator
prsvar(FALSE,FALSE); //Parse Variable to Dereference
if (varble.modifr != MTZP) ERROR("Illegal dereference of non-pointer variable %s.\n", value, EXIT_FAILURE)
}
/* Process Pointer Index *
* Sets: term - Compiled Pointer */
void prcptx(char *index) {
if (strcmp(index,"X")==0) ERROR("Illegal use of register X\n", 0, EXIT_FAILURE);
if (strcmp(index,"A")==0) asmlin("TAY", "");
else if (strcmp(index,"Y") != 0) asmlin("LDY", index);
}
/* Process Pointer *
* Sets: term - Compiled Pointer */
int prcptr(void) {
prsptr();
DEBUG("Dereferencing pointer %s\n", value);
sprintf(term, "(%s),Y", value);
if (valtyp == ARRAY) {
prsidx(TRUE);
prcptx(value);
}
else asmlin("LDY","0");
return FALSE; //Return Value Not an Integer
}
/* Parse Term in Expression *
* Sets: term - the term (as a string) *
* Returns: TRUE if term is an integer */
int prstrm(int alwint) {
DEBUG("Parsing term\n", 0)
if (match('*')) return prcptr(); //Parse and Deference Pointer
prsval(FALSE, TRUE); //Parse Value - Disallow Registers, Allow Constants
if (valtyp == FUNCTION) ERROR("Function call only allowed in first term\n", 0, EXIT_FAILURE)
strcpy(term, value);
@ -303,6 +336,12 @@ int prcftm(int alwint) {
/* Parse first term of expession *
* First term can include function calls */
int prsftm(int alwint) {
DEBUG("Parsing first term\n", 0)
if (match('*')) {
prcptr(); //Parse and Deference Pointer
asmlin("LDA", term);
return FALSE;
}
prsval(TRUE, TRUE); //Parse Value, Allow Registers & Constants
return prcftm(alwint);
}

View File

@ -15,6 +15,7 @@ int trmcnt; //Number of total terms in current expression
int chkadr(int adract, int alwstr); //Check for and Process Address or String
void chkidx(); //Check for, Parse, and Process Index
int prcftm(int alwint); //Process First Term
void prcptx(char *index); //Process Pointer Index
void prcvri(void); //Process Integer Variable
int prcivr(int alwint); //Process Integer Variable in Term
void prsadr(int adract); //Parse and Compile Address of Operator
@ -23,6 +24,7 @@ void prsval(int alwreg, int alwcon); //Parse Value
void prsfnc(char trmntr); //Parse function call
void prsfpr(char trmntr); //Parse Function Paraeters or Return
void prsidx(); //Parse Array Index
void prsptr(void); //Parse Pointer
int prstrm(int alwint); //Parse Term in Expression
void prsrxp(char trmntr); //Parse Rest of Expression
int prsxpf(char trmntr); //Parse Expression in Function Call

View File

@ -37,8 +37,8 @@ void pincnm(void) {
sublen[subidx] = strlen(subnam[subidx]);
subnam[subidx][sublen[subidx]++] = '/';
}
dlmtr = '>';
}
dlmtr = '>';
}
else if (dlmtr != '"')
ERROR("Unexpected character '%c' after include\n", dlmtr, EXIT_FAILURE)
@ -146,7 +146,7 @@ void pprgma(void) {
else if (wordis("ORIGIN"))
porign(); //Parse Origin
else if (wordis("PADDING"))
ppddng(); //Parse Origin
ppddng(); //Parse Padding
else if (wordis("RAMBASE"))
prambs(); //Parse RamBase
else if (wordis("VARTABLE"))

View File

@ -13,6 +13,8 @@
#include "asm.h"
#include "parse.h"
#include "label.h"
#include "expr.h"
#include "stmnt.h"
/* Various tests against nxtchr */
int match(char c) {return TF(nxtchr == c);}
@ -372,21 +374,23 @@ void poperr(char* name) {
}
/* Process Post Operator */
void prcpst(int isint, char* name, char *index) {
void prcpst(int isint, char* name, char *index, char indtyp, char ispntr) {
DEBUG("Processing post operation '%c'\n", oper)
if (ispntr) {sprintf(word,"(%s),Y", name); strcpy(name, word); }
char name1[VARLEN+3];
strcpy(name1, name); strcat(name1, "+1");
if (strlen(index)) {
asmlin("LDX", index);
strcat(name,",X");
if (ispntr) prcptx(index); //Process Pointer Index
else prcidx(indtyp, name, index); //Process Index
}
else if (ispntr) asmlin("LDY","0");
switch(oper) {
case '+':
if (strcmp(name, "X")==0) asmlin("INX", "");
else if (strcmp(name, "Y")==0) asmlin("INY", "");
else if (strcmp(name, "A")==0) poperr(name); //65C02 supports implicit INC, 6502 does not
else {
asmlin("INC", name);
asmlin("INC", word);
if (isint) {
newlbl(skplbl);
asmlin("BNE", skplbl);
@ -407,7 +411,7 @@ void prcpst(int isint, char* name, char *index) {
asmlin("DEC", name1);
setlbl(skplbl);
}
asmlin("DEC", name);
asmlin("DEC", name);
}
break;
case '<':
@ -434,7 +438,7 @@ void prcpst(int isint, char* name, char *index) {
}
/* Parse Post Operator */
int prspst(char trmntr, int isint, char* name, char* index) {
int prspst(char trmntr, int isint, char* name, char* index, char indtyp, char ispntr) {
oper = getnxt();
CCMNT(oper);
DEBUG("Checking for post operation '%c'\n", oper)
@ -442,7 +446,7 @@ int prspst(char trmntr, int isint, char* name, char* index) {
skpchr();
CCMNT(oper);
expect(trmntr);
prcpst(isint, name, index); //Process Post-Op
prcpst(isint, name, index, indtyp, ispntr); //Process Post-Op
return 0;
}
DEBUG("Not a post operation\n", 0)

View File

@ -55,7 +55,7 @@ int prsbyt(); //Parse Numeric Byte
void prslit(); //Parse Literal
int prsnum(int maxval); //Parse Numeric
void prsopr(); //Parse Arithmetic Operator
int prspst(char trmntr, int isint, char* name, char* index); //Parse Post Operator
int prspst(char trmntr, int isint, char* name, char* index, char indtyp, char ispntr); //Parse Post Operator
int psizof(void); //Parse SizeOf Operator
int pidxof(void); //Parse SizeOf Operator
void skpchr(); //Skip Next Character

View File

@ -73,42 +73,52 @@ void prcidx(int idxtyp, char *name, char *index)
/* Set word to assignment variable *
* adding write offset (if set) */
void setasn(char *name) {
strcpy(word, name);
void setasn(char *name, char ispntr) {
if (ispntr) strcpy(word,"(");
else word[0] = 0;
strcat(word, name);
if (wrtofs[0]) strcat(word, wrtofs);
if (ispntr) strcat(word,"),Y");
}
void prcixy(char rgstr, char* idx, int ivt) {
DEBUG("Processing %c register indexed assignment\n", rgstr)
if (strlen(idx)) { //Process X variable Index
if (ivt != LITERAL) {
asmlin("PHA", ""); //Save Accumulator
if (rgstr == 'X') asmlin("TXA", ""); //Transfer Return Value to Accumulator
else asmlin("TYA", "");
prcidx(ivt, word, idx); //Process Index
asmlin("STA", word); //Store Return Value
asmlin("PLA", ""); //Restore Accumulator
} else {
prcidx(ivt, word, idx); //Process Index
if (rgstr == 'X') asmlin("STX", word); //Store Return Value
else asmlin("STY", word);
}
}
}
/* Process Assignment of X and Y variables */
void prcaxy(void) {
DEBUG("Processing X assignment variable '%s'\n", xsnvar)
if (xsnvar[0]) {
setasn(xsnvar);
if (strlen(xsnidx)) { //Process X variable Index
if (xsnivt != LITERAL) {
asmlin("PHA", ""); //Save Accumulator
asmlin("TXA", ""); //Transfer Return Value to Accumulator
prcidx(xsnivt, word, xsnidx); //Process Index
asmlin("STA", word); //Store Return Value
asmlin("PLA", ""); //Restore Accumulator
} else {
prcidx(xsnivt, word, xsnidx); //Process Index
asmlin("STX", word); //Store Return Value
}
}
setasn(xsnvar, FALSE);
if (strlen(xsnidx)) prcixy('X', xsnidx, xsnivt); //Process Index
else asmlin("STX", word); //Store Return Value
xsnvar[0] = 0;
}
DEBUG("Processing Y assignment variable '%s'\n", ysnvar)
if (ysnvar[0]) {
setasn(ysnvar);
if (strlen(ysnidx)) prcidx(ysnivt, word, ysnidx); //Process Index
asmlin("STY", word); //Store Return Value
setasn(ysnvar, FALSE);
if (strlen(ysnidx)) prcixy('Y', ysnidx, ysnivt); //Process Index
else asmlin("STY", word); //Store Return Value
ysnvar[0] = 0;
}
}
/* Process Assignment */
void prcasn(char trmntr) {
void prcasn(char trmntr, char ispntr) {
expect('=');
if (look('(')) prssif(trmntr); //Parse Shortcut If
else prsxpr(trmntr); //Parse Expression
@ -118,8 +128,12 @@ void prcasn(char trmntr) {
else if (strcmp(asnvar, "Y")==0) asmlin("TAY", "");
else if (strcmp(asnvar, "A")==0) return;
DEBUG("Processing assignment variable '%s'\n", asnvar)
setasn(asnvar);
if (asnidx[0]) prcidx(asnivt, word, asnidx); //Process Index
setasn(asnvar, ispntr);
if (asnidx[0]) {
if (ispntr) prcptx(asnidx); //Process Pointer Index
else prcidx(asnivt, word, asnidx); //Process Index
}
else if (ispntr) asmlin("LDY","0");
asmlin("STA", word); //Store Return Value
}
@ -143,6 +157,26 @@ int getidx(char* idx) {
return valtyp;
}
/* Process Accumulator Assignment Variable */
int prcava(char *name, char trmntr, char ispntr) {
strcpy(asnvar, name);
asntyp = valtyp; //Set Assigned Variable Type
DEBUG("Set STA variable to %s\n", asnvar)
if (asntyp == VARIABLE && look(';')) {
asmlin("STA", asnvar);
return TRUE;
}
if (asntyp == ARRAY) asnivt = getidx(asnidx); //Get Array Index and Type
else asnidx[0] = 0;
if (ispntr && strcmp(asnidx, "X") == 0) ERROR("Illegal use of register X\n", 0, EXIT_FAILURE)
DEBUG("Set STA index to '%s'", asnidx) DETAIL(" and type to %d\n", asnivt)
if (ispopr()) {
if (prspst(trmntr, FALSE, asnvar, asnidx, asnivt, ispntr)) expctd("post operator");
return TRUE;
}
return FALSE;
}
/* Process Assignment Variable(s) */
void prcavr(char trmntr) {
chksym(TRUE, FALSE, word);
@ -150,24 +184,11 @@ void prcavr(char trmntr) {
strcpy(vrname, word); //save variable to assign to
if (valtyp == STRUCTURE) prsmbr(vrname); //Updates word and vartyp
if (vartyp == VTINT) {
if (ispopr()) {if (prspst(trmntr, TRUE, vrname, "")) expctd("post operator");}
if (ispopr()) {if (prspst(trmntr, TRUE, vrname, "", 0, FALSE)) expctd("post operator");}
else prcasi(trmntr); //Process Integer Assignment
return;
}
strcpy(asnvar, vrname);
asntyp = valtyp; //Set Assigned Variable Type
DEBUG("Set STA variable to %s\n", asnvar)
if (asntyp == VARIABLE && look(';')) {
asmlin("STA", asnvar);
return;
}
if (asntyp == ARRAY) asnivt = getidx(asnidx); //Get Array Index and Type
else asnidx[0] = 0;
DEBUG("Set STA index to '%s'", asnidx) DETAIL(" and type to %d\n", asnivt)
if (ispopr()) {
if (prspst(trmntr, FALSE, asnvar, asnidx)) expctd("post operator");
return;
}
if (prcava(vrname, trmntr, FALSE)) return;
if (look(',')) {
if (asntyp == REGISTER) ERROR("Register %s not allowed in plural assignment\n", asnvar, EXIT_FAILURE)
prsvar(FALSE, FALSE); //get variable name
@ -185,7 +206,7 @@ void prcavr(char trmntr) {
else xsnidx[0] = 0;
}
}
prcasn(trmntr);
prcasn(trmntr, FALSE);
}
/* Parse 'asm' String Parameter */
@ -210,11 +231,22 @@ void pasm(void) {
asmlin(opcode, word);
}
/* Parse and Compile Assignment of Pointer */
void prcasp(char trmntr) {
prsptr(); //Parse Pointer Dereference
DEBUG("Processing assignment to dereferenced pointer %s\n", value)
if (prcava(value, trmntr, TRUE)) return; //Process Accumulator Assignment Variable
prcasn(trmntr, TRUE);
}
/* Parse and Compile an Assignment */
void prsasn(char trmntr) {
getwrd(); //Get Variable to be Assigned
DEBUG("Parsing assignment of word %s\n", word)
prcavr(trmntr);
if (match('*')) prcasp(trmntr);
else {
getwrd(); //Get Variable to be Assigned
DEBUG("Parsing assignment of word %s\n", word)
prcavr(trmntr);
}
}
/* parse and compile 'break'/'continue' statement */

View File

@ -17,5 +17,7 @@ char xstmnt[LINELEN]; //Expected Statement
void bgnblk(char blkchr); //End Program Block
void endblk(int blkflg); //End Program Block
void prcasp(char trmntr); //Process Pointer Assignment
void prcidx(int idxtyp, char *name, char *index);
void pdowhl(); //Parse and Compile WHILE after DO
void pstmnt(); //Parse and Compile Program Statement