1
0
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:
Curtis F Kaylor 2018-03-07 11:38:22 -05:00
parent fac6ae6b0a
commit ff9576b391
12 changed files with 115 additions and 72 deletions

View File

@ -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.

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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)
}

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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
View 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;

View File

@ -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};

View File

@ -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