mirror of
https://github.com/RevCurtisP/C02.git
synced 2024-06-08 21:29:30 +00:00
Added const keyword
This commit is contained in:
parent
fac6ae6b0a
commit
ff9576b391
41
doc/c02.txt
41
doc/c02.txt
|
@ -68,9 +68,7 @@ directives, the C02 compiler processes directives directly.
|
|||
|
||||
DEFINE DIRECTIVE
|
||||
|
||||
The #define directive creates a named constant. A constant may be used
|
||||
anywhere a literal would be used. Use of the #define directive is
|
||||
explained in the CONSTANTS section below.
|
||||
The #define directive has been deprecated in favor of the const keyword.
|
||||
|
||||
INCLUDE DIRECTIVE
|
||||
|
||||
|
@ -169,25 +167,6 @@ Examples:
|
|||
'A' Character Literal
|
||||
'\'' Escaped Character Literal
|
||||
|
||||
CONSTANTS
|
||||
|
||||
A constant may be used anywhere a literal would be used. Constants are
|
||||
generally used to make code easier to modify or more readable.
|
||||
|
||||
A constant is defined by using the #define directive, followed by an equals
|
||||
sign, the name of the constant, and the literal value to assign to the
|
||||
constant.
|
||||
|
||||
When a constant is referenced in code, it is preceded with a # symbol.
|
||||
|
||||
Examples:
|
||||
#define TRUE = $FF
|
||||
#define FALSE = 0
|
||||
#define BITS = %01010101
|
||||
#define ZED = 'Z'
|
||||
|
||||
if (c == #ZED) return #TRUE;
|
||||
|
||||
ENUMERATIONS
|
||||
|
||||
An enumeration is a sequential list of constants. Enumerations are used to
|
||||
|
@ -222,6 +201,9 @@ simple variables, variable arrays, and functions.
|
|||
A label specifies a target point for a goto statement. A label is written
|
||||
as a symbol suffixed by a : character.
|
||||
|
||||
A constant represents a literal value. A constant is written as a symbol
|
||||
prefixed by the # character.
|
||||
|
||||
A simple variable represents a single byte of memory. A variable is written
|
||||
as a symbol without a suffix.
|
||||
|
||||
|
@ -255,6 +237,19 @@ A program block is a series of statements surrounded by the { and }
|
|||
characters. They may only be used with function definitions and control
|
||||
structures.
|
||||
|
||||
CONSTANTS
|
||||
|
||||
A constant is defined by using the const keyword followed by one or more
|
||||
constant assignments separated with commas and terminated with a semicolon.
|
||||
|
||||
A constant assignment consists of the the constant name, an equals sign,
|
||||
and the literal value to assign to the constant.
|
||||
|
||||
Examples:
|
||||
const #TRUE = $FF, #FALSE = 0;
|
||||
const #BITS = %01010101;
|
||||
const #ZED = 'Z';
|
||||
|
||||
DECLARATIONS
|
||||
|
||||
A declaration statement consists of type keyword (char or void) followed
|
||||
|
@ -458,7 +453,7 @@ statements push, pop, and inline.
|
|||
|
||||
The push statement is used to push arguments onto the machine stack prior
|
||||
to a function call. When using a push statement, it is followed by one or
|
||||
more arguments, separated by commas, and terminated with a semi-colon. An
|
||||
more arguments, separated by commas, and terminated with a semicolon. An
|
||||
argument may be an expression, in which case the single byte result is
|
||||
pushed onto the stack, or it may be an address or string, in which case the
|
||||
address is pushed onto the stack, high byte first and low byte second.
|
||||
|
|
|
@ -17,8 +17,8 @@ by the compiler.
|
|||
|
||||
CONSTANTS
|
||||
|
||||
Constant definitions use the same syntax as C, but when a constant is
|
||||
subsequently referenced in code, it must be prefixed with a # symbol.
|
||||
The syntax of the const keyword in C02 differs from that use in standard C.
|
||||
In C02, all constant names are prefixed with a # symbol.
|
||||
|
||||
ENUMERATION
|
||||
|
||||
|
|
27
src/dclrtn.c
27
src/dclrtn.c
|
@ -50,7 +50,27 @@ void addfnc(void) {
|
|||
bgnblk('{'); //Start Program Block
|
||||
}
|
||||
|
||||
/* (Check For and) Parse Variable Declaration*/
|
||||
/* Parse Constant Declaration*/
|
||||
void pconst(int m) {
|
||||
DEBUG("Processing constant declarations(s)\n", 0)
|
||||
if (m != MTNONE) ERROR("Illegal Modifier %d in Constant Definition", m, EXIT_FAILURE)
|
||||
do {
|
||||
expect('#'); //Require # prefix
|
||||
getwrd(); //Get constant name
|
||||
DEBUG("Defining constant '%s',", word)
|
||||
strncpy(defnam[defcnt], word, VARLEN);
|
||||
setlbl(word); //Set label Assembler Line
|
||||
expect('=');
|
||||
defval[defcnt++] = prsbyt(); //Get Value
|
||||
ACMNT(word); //comment value
|
||||
asmlin(EQUOP, value); //Write Definition
|
||||
DETAIL(" defined as '%s'\n", value)
|
||||
} while (look(','));
|
||||
expect(';');
|
||||
DEBUG("Constant Declaration Completed\n", 0)
|
||||
}
|
||||
|
||||
/* Parse Variable/Function Declaration*/
|
||||
void pdecl(int m, int t) {
|
||||
DEBUG("Processing variable declarations(s) of type %d\n", t)
|
||||
do {
|
||||
|
@ -70,8 +90,9 @@ void pdecl(int m, int t) {
|
|||
/* Check for and Parse Type Keyword */
|
||||
int ptype(int m) {
|
||||
int result = TRUE;
|
||||
if (wordis("VOID")) pdecl(m, VTVOID); //Parse 'void' declaration
|
||||
else if (wordis("CHAR")) pdecl(m, VTCHAR); //Parse 'char' declaration
|
||||
if (wordis("CONST")) pconst(m); //Parse 'const' 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;
|
||||
}
|
||||
|
|
10
src/expr.c
10
src/expr.c
|
@ -14,15 +14,15 @@
|
|||
#include "label.h"
|
||||
#include "expr.h"
|
||||
|
||||
/* Parse value (constant or identifier) *
|
||||
/* Parse value (literal or identifier) *
|
||||
* Sets: value - the value (as a string) *
|
||||
* valtyp - value type */
|
||||
void prsval(int alwreg) {
|
||||
DEBUG("Parsing value\n", 0)
|
||||
skpspc();
|
||||
if (iscpre()) prscon(); //Parse Constant
|
||||
else if (isalph()) prsvar(alwreg); //Parse Variable
|
||||
else expctd("constant or variable");
|
||||
if (islpre()) prslit(); //Parse Literal
|
||||
else if (isalph()) prsvar(alwreg); //Parse Variable
|
||||
else expctd("literal or variable");
|
||||
DEBUG("Parsed value of type %d\n", valtyp)
|
||||
skpspc();
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ void chkidx(void) {
|
|||
//DEBUG("Checking for Array Index with valtyp=%d\n", valtyp)
|
||||
if (valtyp == ARRAY) {
|
||||
prsidx();
|
||||
if (valtyp == CONSTANT) {
|
||||
if (valtyp == LITERAL) {
|
||||
strcat(term, "+");
|
||||
strcat(term, word);
|
||||
}
|
||||
|
|
|
@ -106,7 +106,7 @@ void porign(void) {
|
|||
|
||||
/* Parse Zeropage Subdirective */
|
||||
void prszpg(void) {
|
||||
zpaddr = prsnum(0xFF); //Set Zero Page Address to Constant
|
||||
zpaddr = prsnum(0xFF); //Set Zero Page Address to Literal
|
||||
DEBUG("Set zero page address to %d\n", zpaddr)
|
||||
}
|
||||
|
||||
|
|
44
src/parse.c
44
src/parse.c
|
@ -21,7 +21,7 @@ int isanum(void) {return isalnum(nxtchr);}
|
|||
int isapos(void) {return match('\'');}
|
||||
int isbin(void) {return inbtwn('0', '1');}
|
||||
int isbpre(void) {return TF(isnpre() || isapos());}
|
||||
int iscpre(void) {return TF(isbpre() || ishash());}
|
||||
int islpre(void) {return TF(isbpre() || ishash());}
|
||||
int isdec(void) {return inbtwn('0', '9');}
|
||||
int ishash(void) {return match('#');}
|
||||
int ishexd(void) {return TF(isdec() || inbtwn('A', 'Z'));}
|
||||
|
@ -31,7 +31,7 @@ int isoper(void) {return TF(strchr("+-&|^", nxtchr));}
|
|||
int ispopr(void) {return TF(strchr("+-<>", nxtchr));}
|
||||
int isprnt(void) {return isprint(nxtchr);}
|
||||
int isspc(void) {return isspace(nxtchr);}
|
||||
int isvpre(void) {return TF(isalph() || iscpre());}
|
||||
int isvpre(void) {return TF(isalph() || islpre());}
|
||||
int isxpre(void) {return TF(isvpre() || match('-'));}
|
||||
|
||||
/* Process ASCII Character */
|
||||
|
@ -217,7 +217,7 @@ int prshex(void) {
|
|||
int wrdlen = 0;
|
||||
int digit;
|
||||
int number = 0;
|
||||
DEBUG("Parsing hexadecimal constant '", 0)
|
||||
DEBUG("Parsing hexadecimal literal '", 0)
|
||||
if (!match('$')) expctd("hexadecimal number");
|
||||
word[wrdlen++] = getnxt();
|
||||
while (ishexd()) {
|
||||
|
@ -233,14 +233,14 @@ int prshex(void) {
|
|||
return (number);
|
||||
}
|
||||
|
||||
/* Reads Character constant from input file *
|
||||
* Sets: word - Character constant including *
|
||||
* single quotes *
|
||||
* Returns: ASCII value of constant */
|
||||
/* Read Character Literal from Input File *
|
||||
* Sets: word - Character literal including *
|
||||
* single quotes *
|
||||
* Returns: ASCII value of literal */
|
||||
int prschr(void) {
|
||||
int wrdlen = 0;
|
||||
char c;
|
||||
DEBUG("Parsing character constant\n", 0)
|
||||
DEBUG("Parsing character literal\n", 0)
|
||||
expect('\'');
|
||||
word[wrdlen++] = '\'';
|
||||
if (match('\\')) word[wrdlen++] = getnxt();
|
||||
|
@ -261,16 +261,16 @@ int prschr(void) {
|
|||
int prsnum(int maxval) {
|
||||
int number;
|
||||
skpspc();
|
||||
if (!isbpre()) expctd("constant value");
|
||||
if (!isbpre()) expctd("literal value");
|
||||
switch(nxtchr) {
|
||||
case '%': number = prsbin(); break;
|
||||
case '$': number = prshex(); break;
|
||||
case '\'': number = prschr(); break;
|
||||
default: number = prsdec();
|
||||
}
|
||||
DEBUG("Parsed number '%s' ", word)
|
||||
DETAIL("with value '%d'\n", number)
|
||||
if (number > maxval) ERROR("Out of bounds constant '%d';\n", number, EXIT_FAILURE)
|
||||
DEBUG("Parsed number %s ", word)
|
||||
DETAIL("with value %d\n", number)
|
||||
if (number > maxval) ERROR("Out of bounds literal '%d';\n", number, EXIT_FAILURE)
|
||||
if (maxval > 255) sprintf(value, "$%04X", number);
|
||||
else sprintf(value, "$%02X", number);
|
||||
return number;
|
||||
|
@ -297,24 +297,24 @@ int prsdef(void) {
|
|||
return defval[defidx];
|
||||
}
|
||||
|
||||
/* Parse numeric constant *
|
||||
/* Parse numeric literal *
|
||||
* Args: maxval - maximum allowed value *
|
||||
* Sets: cnstnt - the constant (as an integer) *
|
||||
* value - the constant (as asm arg) *
|
||||
* valtyp - value type (CONSTANT) *
|
||||
* word - constant (as a string) *
|
||||
* Sets: litval - literal (as an integer) *
|
||||
* value - literal (as asm arg) *
|
||||
* valtyp - value type (LITERAL) *
|
||||
* word - literal (as a string) *
|
||||
* Note: Value is converted to hexadecimal *
|
||||
* because DASM uses the format 'c for *
|
||||
* character arguments instead of 'c' */
|
||||
void prscon(void) {
|
||||
void prslit(void) {
|
||||
skpspc();
|
||||
if (ishash()) cnstnt = prsdef();
|
||||
else cnstnt = prsbyt();
|
||||
valtyp = CONSTANT;
|
||||
if (ishash()) litval = prsdef();
|
||||
else litval = prsbyt();
|
||||
valtyp = LITERAL;
|
||||
strcpy(word, value); //Patch for DASM
|
||||
strcpy(value, "#");
|
||||
strcat(value, word);
|
||||
DEBUG("Generated constant '%s'\n", value)
|
||||
DEBUG("Generated literal '%s'\n", value)
|
||||
}
|
||||
|
||||
/* Get Value Type */
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#define TF(x) (x) ? TRUE : FALSE;
|
||||
|
||||
enum stypes {CONSTANT, VARIABLE, REGISTER, ARRAY, FUNCTION}; //Symbol Types
|
||||
enum stypes {LITERAL, VARIABLE, REGISTER, ARRAY, FUNCTION}; //Symbol Types
|
||||
enum etypes {ETDEF, ETMAC}; //Definition Types
|
||||
|
||||
char nxtwrd[LINELEN]; //Next Word (from DEFINE lookup)
|
||||
|
@ -12,7 +12,7 @@ int nxtptr; //Pointer to next character in nxtwrd
|
|||
char value[LINELEN]; //Term parsed from equation
|
||||
int valtyp; //Value Type
|
||||
char oper; //Arithmetic or Bitwise Operator
|
||||
int cnstnt; //Value of Parsed Constant
|
||||
int litval; //Value of Parsed Literal
|
||||
|
||||
char defnam[MAXDEF+1][VARLEN+1]; //Definition Name Table
|
||||
int defval[MAXDEF+1]; //Definition Value Table
|
||||
|
@ -28,7 +28,7 @@ int isanum(); //Is Next Character AlphaNumeric
|
|||
int isapos(); //Is Next Character an Apostrophe
|
||||
int isbin(); //Is Next Character a Binary Digit
|
||||
int isbpre(); //
|
||||
int iscpre(); //Is Next Character a Constant
|
||||
int islpre(); //Is Next Character a Constant
|
||||
int isdec(); //Is Next Character a Decimal Digit
|
||||
int ishash(); //Is Next Character a Byte Value
|
||||
int ishexd(); //Is Next Character a Hexadecimal Digit
|
||||
|
@ -48,7 +48,7 @@ int gettyp(); //Get Value Type
|
|||
void getwrd(); //Get Next Word
|
||||
int look(char c); //Look for Character
|
||||
int prsbyt(); //Parse Numeric Byte
|
||||
void prscon(); //Parse a Constant
|
||||
void prslit(); //Parse Literal
|
||||
int prsnum(int maxval); //Parse Numeric
|
||||
void prsopr(); //Parse Arithmetic Operator
|
||||
int prspst(char trmntr, char* name, char* index); //Parse Post Operator
|
||||
|
|
10
src/stmnt.c
10
src/stmnt.c
|
@ -59,7 +59,7 @@ void prssif(char trmntr) {
|
|||
void prcidx(int idxtyp, char *name, char *index)
|
||||
{
|
||||
if (strlen(index)) {
|
||||
if (idxtyp == CONSTANT) {
|
||||
if (idxtyp == LITERAL) {
|
||||
strcat(name, "+");
|
||||
strcat(name, index);
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ void prcasn(char trmntr) {
|
|||
/* Parse and Return Array Index and Type */
|
||||
int getidx(char* idx) {
|
||||
prsidx(); //Parse Array Index
|
||||
if (valtyp == CONSTANT) strncpy(idx, word, VARLEN);
|
||||
if (valtyp == LITERAL) strncpy(idx, word, VARLEN);
|
||||
else strncpy(idx, value, VARLEN);
|
||||
DEBUG("Parsed index %s\n", idx)
|
||||
return valtyp;
|
||||
|
@ -278,8 +278,8 @@ void pinlne(void) {
|
|||
asmlin(BYTEOP, value);
|
||||
}
|
||||
else {
|
||||
prscon(0xFF);
|
||||
sprintf(word, "$%hhX", cnstnt); //not needed?
|
||||
prslit(0xFF); //Parse Literal
|
||||
sprintf(word, "$%hhX", litval); //not needed?
|
||||
asmlin(BYTEOP, value);
|
||||
}
|
||||
} while (look(','));
|
||||
|
@ -350,7 +350,7 @@ void pcase(void) {
|
|||
pshlbl(LTCASE, cndlbl); //and Push onto Stack
|
||||
while(TRUE) {
|
||||
prstrm(); //Parse CASE argument
|
||||
if (!fcase || valtyp != CONSTANT || cnstnt)
|
||||
if (!fcase || valtyp != LITERAL || litval)
|
||||
asmlin("CMP", term); //Emit Comparison
|
||||
if (look(',')) {
|
||||
chklbl(skplbl); //Emit skip to beginning of CASE block
|
||||
|
|
12
src/vars.c
12
src/vars.c
|
@ -68,8 +68,8 @@ void prsdta(void) {
|
|||
expect('{');
|
||||
dlen = 0;
|
||||
do {
|
||||
prscon();
|
||||
dattmp[dlen++] = cnstnt;
|
||||
prslit(); //Parse Literal
|
||||
dattmp[dlen++] = litval;
|
||||
} while (look(','));
|
||||
expect('}');
|
||||
}
|
||||
|
@ -89,9 +89,9 @@ void prsdts(void) {
|
|||
void setdat(void) {
|
||||
int i;
|
||||
if (dtype == DTBYTE) {
|
||||
DEBUG("Setting variable data to '%d'\n", cnstnt)
|
||||
DEBUG("Setting variable data to '%d'\n", litval)
|
||||
dlen = 1;
|
||||
datvar[dsize++] = cnstnt;
|
||||
datvar[dsize++] = litval;
|
||||
}
|
||||
else if (dtype == DTARRY) {
|
||||
DEBUG("Setting variable data to array of length %d\n", dlen)
|
||||
|
@ -112,10 +112,10 @@ void prsdat(void) {
|
|||
DEBUG("Checking for variable data\n", 0)
|
||||
if (!look('=')) { datlen[varcnt] = 0; return; }
|
||||
skpspc();
|
||||
if (iscpre()) {dtype = DTBYTE; prscon(); }//Parse Data Constant
|
||||
if (islpre()) {dtype = DTBYTE; prslit(); } //Parse Data Literal
|
||||
else if (match('"')) prsdts(); //Parse Data String
|
||||
else if (match('{')) prsdta(); //Parse Data Array
|
||||
else expctd("numeric or string constant");
|
||||
else expctd("numeric or string literal");
|
||||
setdat(); //Store Data Value
|
||||
}
|
||||
|
||||
|
|
18
test/const.c02
Normal file
18
test/const.c02
Normal file
|
@ -0,0 +1,18 @@
|
|||
/* Test C02 define directive */
|
||||
|
||||
#pragma origin 1000
|
||||
|
||||
const #TRUE = $FF, #FALSE = 0;
|
||||
|
||||
const #BITS = %01010101;
|
||||
const #ZED = 'Z';
|
||||
|
||||
#enum SOLO
|
||||
#enum ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN
|
||||
|
||||
char a = {#TRUE, #FALSE};
|
||||
char b;
|
||||
char f = #FALSE;
|
||||
char t = #TRUE;
|
||||
|
||||
b = #TRUE;
|
|
@ -5,6 +5,10 @@
|
|||
#define TRUE = $FF
|
||||
#define FALSE = 0
|
||||
|
||||
#define BITS = %01010101
|
||||
#define ZED = 'Z'
|
||||
|
||||
#enum SOLO
|
||||
#enum ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN
|
||||
|
||||
char a = {#TRUE, #FALSE};
|
||||
|
|
|
@ -4,7 +4,12 @@
|
|||
********************************************/
|
||||
|
||||
|
||||
//#define CR $0D -- DEFINE needs to be reimplimented
|
||||
#define CR = $0D //define is deprecated
|
||||
|
||||
/* Constants */
|
||||
const #TRUE = $FF, #FALSE = 0;
|
||||
const #BITS = %01010101;
|
||||
const #ZED = 'Z';
|
||||
|
||||
/* Variable Types */
|
||||
char b , i; //byte type has been removed
|
||||
|
|
Loading…
Reference in New Issue
Block a user