diff --git a/src/common.h b/src/common.h index eeb2a9f..b2a19cb 100644 --- a/src/common.h +++ b/src/common.h @@ -82,3 +82,4 @@ void setcmt(char *s); //Set comment to string #define SCMNT(str) if (gencmt) {setcmt(str);} #define ACMNT(str) if (gencmt) {addcmt(str);} #define CCMNT(chr) if (gencmt) {chrcmt(chr);} +#define LCMNT(str) if (gencmt) {setcmt(str); cmtlin();} diff --git a/src/dclrtn.c b/src/dclrtn.c index e3e8da1..2875781 100644 --- a/src/dclrtn.c +++ b/src/dclrtn.c @@ -115,22 +115,29 @@ void pdecl(int m, int t) { * Args: m - Modifier Type */ int ptype(int m) { int result = TRUE; - if (wordis("STRUCT")) pstrct(m); //Parse 'const' declaration - else if (wordis("CONST")) pconst(m); //Parse 'const' declaration - else if (wordis("ENUM")) penum(m); //Parse 'enum' declaration - else if (wordis("CHAR")) pdecl(m, VTCHAR); //Parse 'char' declaration - else if (wordis("VOID")) pdecl(m, VTVOID); //Parse 'void' declaration - else result = FALSE; + if (wordis("STRUCT")) pstrct(m); //Parse 'const' declaration + else if (wordis("ENUM")) penum(m); //Parse 'enum' declaration + else if (wordis("CHAR")) pdecl(m, VTCHAR); //Parse 'char' declaration + else if (wordis("VOID")) pdecl(m, VTVOID); //Parse 'void' declaration + else result = FALSE; return result; } +int pmtype(int m) { + getwrd(); + if (m == MTALGN && wordis("CONST")) {m = m | MTCONST; getwrd();} + DEBUG("Parsing type %s\n", word) + return ptype(m); +} + /* Check for and Parse Modifier */ int pmodfr(void) { DEBUG("Parsing modifier '%s'\n", word) int result = TRUE; - if (wordis("ALIGNED")) { getwrd(); ptype(MTALGN); } - else if (wordis("ZEROPAGE")) { getwrd(); ptype(MTZP); } - else if (wordis("ALIAS")) { getwrd(); ptype(MTALS); } + if (wordis("ALIAS")) { pmtype(MTALS); } + else if (wordis("ALIGNED")) { pmtype(MTALGN); } + else if (wordis("CONST")) { pmtype(MTCONST); } + else if (wordis("ZEROPAGE")) { pmtype(MTZP); } else result = FALSE; return result; } diff --git a/src/expr.c b/src/expr.c index 1377590..1fd3e8a 100644 --- a/src/expr.c +++ b/src/expr.c @@ -33,11 +33,11 @@ void poptrm(void) { * Args: alwreg - allow registers * * Sets: value - the value (as a string) * * valtyp - value type */ -void prsval(int alwreg) { +void prsval(int alwreg, int alwcon) { DEBUG("Parsing value\n", 0) skpspc(); if (islpre()) prslit(); //Parse Literal - else if (isalph()) prsvar(alwreg); //Parse Variable + else if (isalph()) prsvar(alwreg, alwcon); //Parse Variable else expctd("literal or variable"); DEBUG("Parsed value of type %d\n", valtyp) skpspc(); @@ -55,7 +55,7 @@ void prcmns(void) { * "" if no index defined */ void prsidx(int clbrkt) { expect('['); - prsval(TRUE); //Parse Value, Allowing Registers + prsval(TRUE, TRUE); //Parse Value, Allowing Registers DEBUG("Parsed array index '%s'\n", value) if (clbrkt) expect(']'); } @@ -113,7 +113,7 @@ void chkidx(void) { * Sets: term - the term (as a string) */ void prstrm(void) { DEBUG("Parsing term\n", 0) - prsval(FALSE); //Parse Term - Disallow Registers + prsval(FALSE, TRUE); //Parse Term - Disallow Registers if (valtyp == FUNCTION) ERROR("Function call only allowed in first term\n", 0, EXIT_FAILURE) strcpy(term, value); DEBUG("Parsed term %s\n", term) @@ -140,7 +140,7 @@ void prcadr(int adract, char* symbol) { void prsadr(int adract) { DEBUG("Parsing address\n", 0) if (isnpre()) prsnum(0xFFFF); - else prsvar(FALSE); + else prsvar(FALSE, TRUE); prcadr(adract, value); //Compile Address Reference } @@ -177,7 +177,7 @@ void prsfnc(char trmntr) { if (!look('*')) prsxpr(0); if (look(',') && !chkadr(0)) { if (!look('*')) { prstrm(); asmlin("LDY", term); } - if (look(',')) { prsval(FALSE); asmlin("LDX", value); } + if (look(',')) { prsval(FALSE, TRUE); asmlin("LDX", value); } } } expect(')'); @@ -201,7 +201,7 @@ void prcftm(void) { /* Parse first term of expession * * First term can include function calls */ void prsftm(void) { - prsval(TRUE); //Parse Value, Allowing Registers + prsval(TRUE, TRUE); //Parse Value, Allowing Registers prcftm(); } diff --git a/src/parse.c b/src/parse.c index 71d6765..09b4f25 100644 --- a/src/parse.c +++ b/src/parse.c @@ -25,7 +25,7 @@ int isdec(void) {return inbtwn('0', '9');} int iscpre(void) {return match('#');} int ishexd(void) {return TF(isdec() || inbtwn('A', 'Z'));} int islpre(void) {return TF(isbpre() || iscpre() || isszop() || isxfop());} -int isnl(void) {return TF(match('\n') || match('\r'));} +int isnl(void) {return TF(match('\n') || match('\r') || match(EOF));} int isnpre(void) {return TF(isdec() || match('$') || match('%'));} int isoper(void) {return TF(strchr("+-&|^", nxtchr));} int ispopr(void) {return TF(strchr("+-<>", nxtchr));} diff --git a/src/stmnt.c b/src/stmnt.c index 9a0a370..deaa2f7 100644 --- a/src/stmnt.c +++ b/src/stmnt.c @@ -113,7 +113,7 @@ int getidx(char* idx) { /* Process Assignment Variable(s) */ void prcvar(char trmntr) { - chksym(TRUE, word); + chksym(TRUE, FALSE, word); strcpy(asnvar, word); //save variable to assign to if (valtyp == VARIABLE && match('.')) prsmbr(asnvar); asntyp = valtyp; //Set Assigned Varable Type @@ -131,14 +131,14 @@ void prcvar(char trmntr) { } if (look(',')) { if (asntyp == REGISTER) ERROR("Register %s not allowed in plural assignment\n", asnvar, EXIT_FAILURE) - prsvar(FALSE); //get variable name + prsvar(FALSE, FALSE); //get variable name strcpy(ysnvar, word); DEBUG("Set STY variable to %s\n", ysnvar) if (valtyp == ARRAY) ysnivt = getidx(ysnidx); //Get Array Index and Type else ysnidx[0] = 0; DEBUG("Set STY index to '%s'", ysnidx) DETAIL(" and type to %d\n", ysnivt) if (look(',')) { - prsvar(FALSE); //get variable name + prsvar(FALSE, FALSE); //get variable name strcpy(xsnvar, word); DEBUG("Set STX variable to %s\n", xsnvar) //if (valtyp == ARRAY) ERROR("Array element not allowed in third assignment\n", 0, EXIT_FAILURE) diff --git a/src/vars.c b/src/vars.c index 092f976..7083a4e 100644 --- a/src/vars.c +++ b/src/vars.c @@ -53,8 +53,9 @@ int fndmbr(int idx, char *name) { /* Check for variable * * Generates error if variable is undefined * * Args: alwreg - allow register name * + * alwcon - allow const variable * * name - variable name */ -void chksym(int alwreg, char *name) { +void chksym(int alwreg, int alwcon, char *name) { if (strlen(name) == 1 && strchr("AXY", name[0])) { if (alwreg && valtyp != ARRAY) { valtyp = REGISTER; @@ -64,6 +65,8 @@ void chksym(int alwreg, char *name) { } if (!fndvar(name)) ERROR("Undeclared variable '%s' encountered\n", name, EXIT_FAILURE) + if (!alwcon && (varmod[varidx] & MTCONST)) + ERROR("Illegal use of const variable '%s'\n", name, EXIT_FAILURE) } /* Parse next word as struct member * @@ -87,10 +90,10 @@ void prsmbr(char* name) { * Args: alwreg - Allow Register Names * * Sets: value - Identifier Name * * valtyp - Identifier Type */ -void prsvar(int alwreg) { +void prsvar(int alwreg, int alwcon) { getwrd(); //Get Variable Name valtyp = gettyp(); //Determine Variable Type - if (valtyp != FUNCTION) chksym(alwreg, word); + if (valtyp != FUNCTION) chksym(alwreg, alwcon, word); strcpy(value, word); DEBUG("Parsed variable '%s'\n", value) if (valtyp == VARIABLE && match('.')) prsmbr(value); @@ -100,7 +103,7 @@ void prsvar(int alwreg) { * Parameters: alwary - Allow Array Reference * * Sets: vrname - operand for LDA/STA/LDY/STY */ void reqvar(int alwary) { - prsvar(FALSE); + prsvar(FALSE, TRUE); if (!alwary && valtyp != VARIABLE) expctd("Variable"); } @@ -191,9 +194,9 @@ void setdat(void) { } /* Parse and store variable data */ -void prsdat(void) { - DEBUG("Checking for variable data\n", 0) - if (!look('=')) { datlen[varcnt] = 0; return; } +void prsdat(int m) { + if ((m & MTCONST) == 0) ERROR("Initialization allowed only on variables declared CONST\n", 0, EXIT_FAILURE); + DEBUG("Parsing variable data\n", 0) skpspc(); if (islpre()) {dtype = DTBYTE; prslit(); } //Parse Data Literal else if (match('"')) prsdts(); //Parse Data String @@ -216,23 +219,23 @@ void setvar(int m, int t) { } /* Parse and Compile Variable Declaration * - * Uses: word - variable name */ + * Uses: word - variable name */ void addvar(int m, int t) { strcpy(vrname, word); //Save Variable Name if (fndvar(vrname)) ERROR("Duplicate declaration of variable '%s\n", vrname, EXIT_FAILURE) if (t == VTVOID) ERROR("Illegal Variable Type\n", 0, EXIT_FAILURE) - if (m == MTZP) { + if (m & MTZP) { setlbl(vrname); sprintf(word, "$%hhX", zpaddr++); asmlin(EQUOP, word); strcpy(value, "*"); //Set Variable to Non Allocated } - else if (m == MTALS) { + else if (m & MTALS) { setlbl(vrname); skpspc(); expect('='); skpspc(); - if (isnpre()) prsnum(0xFFFF); else prsvar(FALSE); + if (isnpre()) prsnum(0xFFFF); else prsvar(FALSE, FALSE); asmlin(EQUOP, word); strcpy(value, "*"); //Set Variable to Non Allocated } @@ -253,22 +256,24 @@ void addvar(int m, int t) { if (!alcvar) strcpy(value, "*"); } setvar(m, t); //Add to Variable Table - if (m < MTZP && t != VTSTRUCT ) prsdat(); //Parse Variable Data + if (look('=')) prsdat(m); //Parse Variable Data varcnt++; //Increment Variable Counter } -/* Write Variable Table */ -void vartbl(void) { +/* Write Variable Definitions * + * Args: m = write CONST vars flag */ +void vardef(int m) { int i, j; DEBUG("Writing Variable Table\n", 0) - fprintf(logfil, "\n%-31s %s %s %s %s\n", "Variable", "Type", "Size", "Struct", "Data"); + fprintf(logfil, "\n%-31s %s %s %s %s\n", "Variable", "Mod", "Type", "Size", "Struct", "Data"); dlen = 0; for (i=0; i