mirror of
https://github.com/RevCurtisP/C02.git
synced 2024-06-15 22:29:27 +00:00
Allow int members in structs
This commit is contained in:
parent
2530f3ed1e
commit
b6cec4d75a
6
c02.ppj
6
c02.ppj
|
@ -28,8 +28,8 @@ LIB = $(PellesCDir)\Lib\Win64;$(PellesCDir)\Lib#
|
|||
# Build c02.exe.
|
||||
#
|
||||
c02.exe: \
|
||||
output\c02.obj \
|
||||
output\asm.obj \
|
||||
output\c02.obj \
|
||||
output\common.obj \
|
||||
output\cond.obj \
|
||||
output\dclrtn.obj \
|
||||
|
@ -165,6 +165,7 @@ output\parse.obj: \
|
|||
src\asm.h \
|
||||
src\common.h \
|
||||
src\files.h \
|
||||
src\label.h \
|
||||
src\parse.h
|
||||
$(CC) $(CCFLAGS) "$!" -Fo"$@"
|
||||
|
||||
|
@ -190,6 +191,7 @@ output\vars.obj: \
|
|||
src\vars.c \
|
||||
src\asm.h \
|
||||
src\common.h \
|
||||
src\dclrtn.h \
|
||||
src\files.h \
|
||||
src\label.h \
|
||||
src\parse.h \
|
||||
|
@ -197,3 +199,5 @@ output\vars.obj: \
|
|||
$(CC) $(CCFLAGS) "$!" -Fo"$@"
|
||||
|
||||
.SILENT:
|
||||
|
||||
.EXCLUDEDFILES:
|
||||
|
|
192
doc/c02.txt
192
doc/c02.txt
|
@ -287,13 +287,13 @@ generate sets of related but distinct values.
|
|||
|
||||
An enumeration is defined using an enum statement. When using the enum
|
||||
keyword, it is followed by a { character, one or more constant names
|
||||
separated by commas, and a } character. An asterisk may be used in place
|
||||
of a constant name, in which case the sequence will be skipped. The enum
|
||||
statement is terminated with a semicolon.
|
||||
separated by commas, and a } character. A period may be used in place
|
||||
of a constant name, in which case the sequence will be skipped. The
|
||||
enum statement is terminated with a semicolon.
|
||||
|
||||
Examples:
|
||||
enum {BLACK, WHITE, RED, CYAN, PURPLE, GREEN, BLUE, YELLOW};
|
||||
enum {*, FIRST, SECOND, THIRD};
|
||||
enum {., FIRST, SECOND, THIRD};
|
||||
enum {ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN};
|
||||
|
||||
Note: Values are automatically assigned to the constants in an enumeration.
|
||||
|
@ -308,13 +308,13 @@ combined into a single char variable.
|
|||
|
||||
An enumeration is defined using a bitmask statement. When using the bitmask
|
||||
keyword, it is followed by a { character, one to eight constant names
|
||||
separated by commas, and a } character. An asterisk may be used in place
|
||||
of a constant name, in which case the bit value will be skipped. The
|
||||
bitmask statement is terminated with a semicolon.
|
||||
separated by commas, and a } character. A period may be used in place of a
|
||||
constant name, in which case the bit value will be skipped. The bitmask
|
||||
statement is terminated with a semicolon.
|
||||
|
||||
Examples:
|
||||
bitmask {BLUE, GREEN, RED, BRIGHT, INVERT, BLINK, FLIP, BKGRND};
|
||||
bitmask {RD, RTS, DTR, RI, CD, *, CTS, DSR};
|
||||
bitmask {RD, RTS, DTR, RI, CD, ., CTS, DSR};
|
||||
|
||||
Note: Values are automatically assigned to the constants in a bitmask,
|
||||
each of which is a sequential power of two. The first constant in the
|
||||
|
@ -323,43 +323,72 @@ the third is assigned the value 4, and so on.
|
|||
|
||||
DECLARATIONS
|
||||
|
||||
A declaration statement consists of type keyword (char or void) followed
|
||||
by one or more variable names and optional definitions, or a single
|
||||
function name and optional function block.
|
||||
A declaration statement consists of type a keyword (char, int, or void)
|
||||
followed one or more variable names (and optional definitions) or a single
|
||||
function name and optional function block, or the struct keyword followed
|
||||
by a structure name and either a definition or a variable name.
|
||||
|
||||
Variables may only be of type char and all variable declaration statements
|
||||
are suffixed with a ; character.
|
||||
Variables may only be of type char or int, and all variable declaration
|
||||
statements are suffixed with a ; character. Variables of type char may be
|
||||
delared as arrays, by appending the variable name with the [ character,
|
||||
the upper bound of the array (0 to 255), and the ] character.
|
||||
|
||||
Examples:
|
||||
char c; //Defines variable c
|
||||
char i, j; //Defines variables i and j
|
||||
char r[7]; //Defines 8 byte array r
|
||||
char c; //Defines 8-bit variable c
|
||||
char hi,lo; //Defines 8-bit variables hi and lo
|
||||
char r[7]; //Defines 8 byte array r
|
||||
int addr; //Defines 16-bit variable addr
|
||||
int i, j; //Defines 16-bit variables i and j
|
||||
|
||||
A function declaration consists of the function name suffixed with a (
|
||||
character, followed zero to three comma separated simple variables and
|
||||
a ) character. A function declaration terminated with a ; character is
|
||||
called a forward declaration and does not generate any code, while one
|
||||
followed by a program block creates the specified function. Functions of
|
||||
type char explicitly return a value (using a return statement), while
|
||||
functions of type void do not.
|
||||
character, followed by an optional parameter set and a ) character.
|
||||
|
||||
The parameter set, if specified, may be either one to three simple
|
||||
char variables, a single int variable, or a char variable followed
|
||||
by an int variable.
|
||||
|
||||
A function declaration terminated with a ; character is called a forward
|
||||
declaration and does not generate any code, while one followed by a
|
||||
program block creates the specified function.
|
||||
|
||||
Functions of type char and int explicitly return one or more values
|
||||
(using a return statement), while functions of type void return no
|
||||
explicit value.
|
||||
|
||||
The return statement causes the function to exit, after which control
|
||||
returns to the statement immediately following the function call. If
|
||||
the last statement before the closing } of the function body is not
|
||||
a return, then an implicit return is assumed.
|
||||
|
||||
A return statement may be followed by an list of one to three variables
|
||||
following the same rules as function arguments (see FUNCTION CALLS,
|
||||
below), in which case those values are returned by the function call,
|
||||
otherwise the function call will not return any explicit values.
|
||||
|
||||
Examples:
|
||||
void myfunc(); //Forward declaration of function myfunc
|
||||
char not(tmp) {tmp = tmp ^ $FF;}
|
||||
char max(tmp1, tmp2) {if (tmp1 > tmp2) return tmp1; else return tmp2;}
|
||||
char min(tmp1, tmp2) {if (tmp1 < tmp2) return tmp1; else return tmp2;}
|
||||
char test(b,c,d) {if (b:-) return min(c,d); else return max(c,d);}
|
||||
int swap(*,msb,lsb) {return *,lsb,msb;} //Swap bytes in integer
|
||||
int incdec(m,i) {if (m:-) i--; else i++; return i}; //inc/dec integer
|
||||
|
||||
Note: Like all variables, function parameters are global. They must be
|
||||
declared prior to the function decaration, and retain there values after
|
||||
declared prior to the function declaration, and retain there values after
|
||||
the function call. Although functions may be called recursively, they are
|
||||
not re-entrant. Allocation of variables and functions is implementation
|
||||
dependent, they could be placed in any part of memory and in any order.
|
||||
The default behavior is to place variables directly after the program code,
|
||||
including them as part of the generated object file.
|
||||
|
||||
The return value of a function is passed through the A register. A return
|
||||
statement with an explicit expression will simply process that expression
|
||||
(which leaves the result in the A register) before returning. A return
|
||||
statement without an expression (including an implicit return) will, by
|
||||
default, return the value of the last processed expression.
|
||||
Function arguments and return values are passed through the 6502 registers.
|
||||
Char type values are passed by loading A, Y, and X respectively, while int
|
||||
type values are passed by loading Y with the most significant byte and
|
||||
X with the least significant bit.
|
||||
|
||||
A return statement without explicit return values will return whatever
|
||||
happens to be in the registers at that time.
|
||||
|
||||
STRUCTS
|
||||
|
||||
|
@ -378,19 +407,29 @@ as well as declaring struct type variables.
|
|||
When defining a struct type, the struct keyword is followed by the name of
|
||||
the struct type, the { character, the member definitions separated by
|
||||
commas, and the } character. The struct definition is terminated with a
|
||||
semicolon. Each member definition is composed of the optional char keyword,
|
||||
and the member name. If the member is an array, the member name is suffixed
|
||||
the [ character, the upper bound of the array, and the ] character. Each
|
||||
member definition is terminated with a semicolon.
|
||||
semicolon. Each member definition is composed of a type keyword (char, int,
|
||||
or struct) and one or more member names, separated with commas. If a member
|
||||
is an array, the member name is suffixed the [ character, the upper bound of
|
||||
the array, and the ] character. Each member definition is terminated with a
|
||||
semicolon. Any number of comments may appear before the first member, between
|
||||
members, and after the last member.
|
||||
|
||||
When declaring a struct variable, the struct keyword is followed by the struct
|
||||
type name, and the name of the struct variable. The struct declaration is
|
||||
terminated with a semicolon.
|
||||
Member names are limited to six alphanumeric characters, the first of which
|
||||
must be alphabetic. Any names are allowed including reserved words, as well
|
||||
as A, X, and Y (which in this case, do not refer to registers).
|
||||
|
||||
When declaring a struct variable, the struct keyword is followed by the
|
||||
struct type name, and one or more variable names, separated with commas.
|
||||
The struct declaration is terminated with a semicolon.
|
||||
|
||||
Examples:
|
||||
|
||||
struct record {char name[8]; char index; data[128];};
|
||||
struct record {char name[8]; char index; int addr, char data[128];};
|
||||
struct record rec;
|
||||
struct record srcrec, dstrec;
|
||||
struct point {char x, y;}
|
||||
struct point pnt;
|
||||
struct line {struct pnt bgnpnt, endpnt;}
|
||||
|
||||
Note: Unlike simple and array variable, the members of a struct variable
|
||||
may not be initialized during declaration.
|
||||
|
@ -412,12 +451,13 @@ a page variable. This is used to ensure that accessing an array element will
|
|||
not cross a page boundary, which requires extra CPU cycles to execute.
|
||||
|
||||
The const modifier specifies that a variable or array should not be changed
|
||||
by program code. The const modifier may be preceded by the aligned modifier.
|
||||
by program code. The const modifier may be preceded by an` aligned or
|
||||
zeropage modifier.
|
||||
|
||||
A const variable declaration may include an initial value definition in
|
||||
the form of an = character and literal after the variable name.
|
||||
|
||||
A const array may be declared in one of two ways: the variable name
|
||||
A const array is declared in one of two ways: the variable name
|
||||
suffixed with a [ character, a literal specifying the upper bound of
|
||||
the array, and a ] character; or a variable name followed by an = character
|
||||
and string literal or series of atring and/or numeric literals separated by
|
||||
|
@ -437,20 +477,22 @@ Examples:
|
|||
const char n = {1,2,3}; //Defines 3 byte array m containing 1, 2, and 3
|
||||
const char m = {"abc", 123); //Defines 5 byte array containing string and byte
|
||||
const char t = {"ab", "cd"); //Defines 6 byte array of two strings
|
||||
aligned const char fbncci[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34};
|
||||
aligned const char fbncci = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34};
|
||||
zeropage char ptr, tmp; //Defines zero page variables
|
||||
|
||||
EXPRESSIONS
|
||||
|
||||
An expression is a series of one or more terms separated by operators.
|
||||
|
||||
The first term in an expression may be a function call, subscripted array
|
||||
element, simple variable, literal, or register (A, X, or Y). An expression
|
||||
may be preceded with a - character, in which case the first term is assumed
|
||||
to be a literal 0.
|
||||
Each term in an expression may be any of the following:
|
||||
function call (first term only)
|
||||
subscripted array element
|
||||
char type variable, struct member, constant, or literal
|
||||
byte operation
|
||||
register (A, X, or Y).
|
||||
|
||||
Additional terms are limited to subscripted array elements, simple variables,
|
||||
literals, and constants.
|
||||
An expression may be preceded with a - character, in which case the first
|
||||
term is assumed to be a literal 0.
|
||||
|
||||
Operators:
|
||||
+ — Add the following value.
|
||||
|
@ -471,10 +513,28 @@ result.
|
|||
|
||||
Note: Function calls are allowed in the first term of an expression
|
||||
because upon return from the function the return value will be in the
|
||||
Accumulator. However, due to the 6502 having only one Accumulatorm which
|
||||
Accumulator. However, due to the 6502 having only one Accumulator, which
|
||||
is used for all operations between two bytes, there is no simple system
|
||||
agnostic method for allowing function calls in subsequent terms.
|
||||
|
||||
BYTE OPERATIONS
|
||||
|
||||
Byte operation allows the the bytes in an integer value to be accessed
|
||||
as individual character values. A byte operation consists of a byte
|
||||
operator prefixed to an integer value.
|
||||
|
||||
Byte Operators:
|
||||
< - Get Least Significant Byte
|
||||
> - Get Most Significant Byte
|
||||
|
||||
The integer value may be an integer literal, an address, or an int type
|
||||
variable or struct member.
|
||||
|
||||
Examples:
|
||||
hi = >&r; lo = <&r; //Set hi, lo to MSB, LSB of address of array R
|
||||
page = >53281; //Set page to MSB of the integer literal 53281
|
||||
lsb = <count; //Set lsb to low byte of integer variable count
|
||||
|
||||
CONTENTIONS
|
||||
|
||||
An contention is a construct which generates either TRUE or FALSE condition,
|
||||
|
@ -624,7 +684,7 @@ a variable length.
|
|||
INDEX-OF OPERATOR
|
||||
|
||||
The index-of operator ? generates a literal value equal to the offset in bytes
|
||||
of a specified stucture member. It is allowed anywhere a literal would be and
|
||||
of a specified structure member. It is allowed anywhere a literal would be and
|
||||
should be used anytime the offset of the member of a struct is required.
|
||||
|
||||
When using the size-of operator, it is prefixed to the member specification.
|
||||
|
@ -634,7 +694,7 @@ Examples:
|
|||
blkmem(?rec.data, &s); //Search block for segment where data contains s
|
||||
memcpy(?rec.data, &t); //Copy bytes of rec up to member data into t
|
||||
|
||||
Note: The idex-of operator is evaluated at compile time and generates two
|
||||
Note: The index-of operator is evaluated at compile time and generates two
|
||||
bytes of machine language code. It is the most efficient method of specifying
|
||||
a the offset of a struct member.
|
||||
|
||||
|
@ -645,21 +705,21 @@ term in an expression. A function call consists of the function name
|
|||
appended with a ( character, followed by zero to three arguments separated
|
||||
with commas, and a closing ) character.
|
||||
|
||||
The first argument of a function call may be an expression, address, or
|
||||
string (see below).
|
||||
The first argument of a function call may be an expression, integer,
|
||||
address, or string (see below).
|
||||
|
||||
The second argument may be a term (subscripted array element, simple
|
||||
variable, or constant), address, or string,
|
||||
variable, or constant), integer, address, or string,
|
||||
|
||||
The third argument may only be a simple variable or constant.
|
||||
|
||||
If the first or second argument is an address or string, then no more
|
||||
arguments may be passed.
|
||||
If the first or second argument is an integer address or string, then
|
||||
no more arguments may be passed.
|
||||
|
||||
When passing the address of a variable, array, struct, or struct member
|
||||
into a function, the variable specification is prefixed with the
|
||||
address-of operator &. When passing a string, the string is simply
|
||||
specified as the argument with.
|
||||
address-of operator &. When passing a literal string, it is simply
|
||||
specified as is.
|
||||
|
||||
Examples:
|
||||
c = getc(); //Get character from keyboard
|
||||
|
@ -671,7 +731,7 @@ Examples:
|
|||
puts("Hello World"); //Write "Hello World" to screen
|
||||
memdst(&dstrec); //Set struct variable as destination
|
||||
memcpy(140, &srcrec); //Copy struct variable to destination struct
|
||||
puts(&rec.name); //Write struct membet to screen
|
||||
puts(&rec.name); //Write struct member to screen
|
||||
|
||||
Note: This particular argument passing convention has been chosen because
|
||||
of the 6502's limited number of registers and stack processing instructions.
|
||||
|
@ -698,14 +758,14 @@ The pop statement is likewise used to pop arguments off of the machine
|
|||
stack after a function call. When using a pop statement, it is followed
|
||||
with one or more simple variables or subscripted array elements , separated
|
||||
by commas, and terminated with a semicolon. If any of the arguments are to
|
||||
be discarded, an asterisk can be specified instead of a variable name.
|
||||
be discarded, a period may be specified instead of a variable name.
|
||||
|
||||
The number of arguments pushed and popped may or may not be the same,
|
||||
depending on how the machine language routine manipulates the stack pointer.
|
||||
|
||||
Examples:
|
||||
push d,r; mult(); pop p; //multiply d times r and store in p
|
||||
push x1,y1,x2,y2; rect(); pop *,*,*,*; //draw rectangle from x1,y1 to x2,y2
|
||||
push x1,y1,x2,y2; rect(); pop .,.,.,.; //draw rectangle from x1,y1 to x2,y2
|
||||
push &s, "tail"; strcat(); //concatenate "tail" onto string s
|
||||
push x[i],y[i]; rotate(d); pop x[i],y[i]; //rotate point x[1],y[i] by d
|
||||
|
||||
|
@ -845,8 +905,10 @@ of code to be executed if the conditional was false.
|
|||
|
||||
Examples:
|
||||
if (c = 27) goto end;
|
||||
if (n) q = div(n,d) else puts("Division by 0!");
|
||||
if (r[j]<r[i]) {t=r[i],r[i]=r[j],r[j]=t)}
|
||||
if (n) q = div(n,d) else putln("Division by 0!");
|
||||
if (r[q]<r[p]) {t=r[p],r[p]=r[q],r[q]=t)}
|
||||
if (!>i | <i) puts("i is zero.");
|
||||
if (>i > >j || >i = >j && <i > <j) k = i; else k = j;
|
||||
|
||||
Note: In order to optimize the compiled code, the if and else statements
|
||||
are to 6502 relative branch instructions. This limits the amount of
|
||||
|
@ -958,6 +1020,7 @@ if it is true, the code block is repeated.
|
|||
Examples:
|
||||
do c = rdkey(); while (c=0); //Wait for keypress
|
||||
do (c = getchr(); putchr(c); while (c<>13) //Echo line to screen
|
||||
i=0; do {i++;} while (>i <= >j && <i < <j); //Count from 0 to J
|
||||
|
||||
Note: Unlike the other loop structures do/while statements do not use
|
||||
6502 JMP instructions. This optimizes the compiled code, but limits
|
||||
|
@ -1021,10 +1084,11 @@ The #define directive allows the definition of constants but not macros.
|
|||
The #if, #else, and #endif directives are not recognized at all by the
|
||||
compiler. They may be added in the future.
|
||||
|
||||
The only type recognized by the compiler is char. Since the 6502 is an
|
||||
8-bit processor, multi-byte types would generate over-complicated code.
|
||||
In addition, the signed and unsigned keywords are unrecognized, due to the
|
||||
6502's limited signed comparison functionality.
|
||||
The only types recognized by the compiler are char and int. Int values
|
||||
may only be used in limited contexts. Since the 6502 is an 8-bit processor,
|
||||
multi-byte types would generate over-complicated code. In addition, the
|
||||
signed and unsigned keywords are unrecognized, due to the 6502's limited
|
||||
signed comparison functionality.
|
||||
|
||||
Because of the 6502's peculiar indirect addressing modes, pointers are not
|
||||
currently implemented. Limited pointer operations may be implemented using
|
||||
|
|
|
@ -1,34 +1,34 @@
|
|||
Character Symbols Recognized by the C02 Compiler
|
||||
|
||||
Symbol Prefix Operator Comparator Delimiter
|
||||
! Bitwise Or Logical Not
|
||||
" String Literal
|
||||
Symbol Prefix/Suffix Operator Contention Other
|
||||
! Bitwise Or Logical Not
|
||||
" String Literal
|
||||
# Constant
|
||||
$ Hexadecimal
|
||||
% Binary
|
||||
& Address Of Bitwise And
|
||||
' Character Literal
|
||||
( Comparison
|
||||
) Comparison
|
||||
* (pointer)
|
||||
+ Addition
|
||||
, Declarations
|
||||
- Subtraction
|
||||
. Struct Members
|
||||
& Address Of Bitwise And
|
||||
' Character Literal
|
||||
( Contention
|
||||
) Contention
|
||||
* (pointer)
|
||||
+ Addition
|
||||
, Argument Separator
|
||||
- Subtraction
|
||||
. Null Placeholder Struct Member Separator
|
||||
/ Comment
|
||||
: Status Flag Shortcut Else
|
||||
; Statement
|
||||
< Less Than
|
||||
= Equal To Assignment
|
||||
> Greater Than
|
||||
? Index Of Shortcut If
|
||||
: Status Flag Shortcut Else
|
||||
; Statement
|
||||
< Integer LSB Less Than
|
||||
= Equal To Assignment
|
||||
> Integer MSB Greater Than
|
||||
? Index Of Shortcut If
|
||||
@ Length Of
|
||||
[ Array Element
|
||||
\
|
||||
] Array Element
|
||||
^ (pointer)
|
||||
[ Array Element
|
||||
\
|
||||
] Array Element
|
||||
^ (pointer)
|
||||
_
|
||||
{ Block Start
|
||||
| Bitwise Or
|
||||
} Block End
|
||||
{ Block Start
|
||||
| Bitwise Or
|
||||
} Block End
|
||||
~
|
||||
|
|
|
@ -119,7 +119,7 @@ void prscnd(char trmntr, int revrse) {
|
|||
revcmp = revrse;
|
||||
if (look('!')) revcmp = (revcmp) ? FALSE: TRUE;
|
||||
DEBUG("Set REVCMP to %d\n", revcmp)
|
||||
if (!look('?')) prsxpr(0);
|
||||
if (!look('.')) prsxpr(0);
|
||||
if (look(':')) prsflg(revcmp); //Parse Flag Operator
|
||||
else prscmp(revcmp); //Parse Comparison Operator
|
||||
prslop(); //Parse Logical Operator
|
||||
|
|
41
src/dclrtn.c
41
src/dclrtn.c
|
@ -19,7 +19,7 @@
|
|||
|
||||
int addprm(char* prmtr) {
|
||||
reqvar(FALSE); //Get Variable Name
|
||||
if (varble.type == VTINT) {
|
||||
if (vartyp == VTINT) {
|
||||
strcpy(prmtrx, value);
|
||||
strcpy(prmtry, value);
|
||||
strcat(prmtry, "+1");
|
||||
|
@ -38,8 +38,8 @@ void addfnc(void) {
|
|||
prmtry[0] = 0;
|
||||
prmtrx[0] = 0;
|
||||
skpspc(); //Skip Spaces
|
||||
if (isalph() || match('?')) { //Parse Parameters
|
||||
if (!look('?')) {if (addprm(prmtra)) goto addfne;} //Get First Parameter
|
||||
if (isalph() || match('.')) { //Parse Parameters
|
||||
if (!look('.')) {if (addprm(prmtra)) goto addfne;} //Get First Parameter
|
||||
if (look(',')) { //Look for Comma
|
||||
if (addprm(prmtry)) goto addfne; //Get Second Parameter
|
||||
if (look(',')) { //Look for Comma
|
||||
|
@ -85,7 +85,7 @@ void penum(int m, int bitmsk) {
|
|||
expect('{');
|
||||
do {
|
||||
if (enmval > 0xFF) ERROR("Maximum ENUM or BITMASK value exceeded\n", 0, EXIT_FAILURE)
|
||||
if (look('?'))
|
||||
if (look('.'))
|
||||
DEBUG("Skipping sequence %d\n", enmval)
|
||||
else {
|
||||
getwrd(); //get defined identifier
|
||||
|
@ -129,18 +129,33 @@ void pdecl(int m, int t) {
|
|||
cmtlin(); //Write out declaration comment
|
||||
}
|
||||
|
||||
/* Check for and Parse Type Keyword *
|
||||
* Returns: Type (enum types) */
|
||||
int ctype(int reqtyp) {
|
||||
if (wordis("BITMASK")) return TBITMASK;
|
||||
else if (wordis("STRUCT")) return TSTRUCT;
|
||||
else if (wordis("ENUM")) return TENUM;
|
||||
else if (wordis("CHAR")) return TCHAR;
|
||||
else if (wordis("INT")) return TINT;
|
||||
else if (wordis("VOID")) return TVOID;
|
||||
else if (reqtyp) ERROR("Type Declaration Expected\n", 0, EXIT_FAILURE)
|
||||
return TNONE;
|
||||
}
|
||||
|
||||
/* Check for and Parse Type Keyword *
|
||||
* Args: m - Modifier Type */
|
||||
int ptype(int m) {
|
||||
int reslt = TRUE;
|
||||
if (wordis("STRUCT")) pstrct(m); //Parse 'struct' declaration
|
||||
else if (wordis("ENUM")) penum(m, FALSE); //Parse 'enum' declaration
|
||||
else if (wordis("BITMASK")) penum(m, TRUE); //Parse 'enum' declaration
|
||||
else if (wordis("CHAR")) pdecl(m, VTCHAR); //Parse 'char' declaration
|
||||
else if (wordis("INT")) pdecl(m, VTINT); //Parse 'int' declaration
|
||||
else if (wordis("VOID")) pdecl(m, VTVOID); //Parse 'void' declaration
|
||||
else reslt = FALSE;
|
||||
return reslt;
|
||||
int type = ctype(FALSE);
|
||||
switch (type) {
|
||||
case TSTRUCT: pstrct(m); break; //Parse 'struct' declaration
|
||||
case TENUM: penum(m, FALSE); break; //Parse 'enum' declaration
|
||||
case TBITMASK: penum(m, TRUE); break; //Parse 'enum' declaration
|
||||
case TCHAR: pdecl(m, VTCHAR); break; //Parse 'char' declaration
|
||||
case TINT: pdecl(m, VTINT); break; //Parse 'int' declaration
|
||||
case TVOID: pdecl(m, VTVOID); break; //Parse 'void' declaration
|
||||
default: return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int pmtype(int m) {
|
||||
|
|
|
@ -11,4 +11,7 @@ int prmcnt; //Number of Parameters
|
|||
|
||||
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};
|
||||
|
|
43
src/expr.c
43
src/expr.c
|
@ -37,8 +37,9 @@ void poptrm(void) {
|
|||
void prsval(int alwreg, int alwcon) {
|
||||
DEBUG("Parsing value\n", 0)
|
||||
skpspc();
|
||||
if (islpre()) prslit(); //Parse Literal
|
||||
if (islpre()) prslit(); //Parse Literal
|
||||
else if (isalph()) prsvar(alwreg, alwcon); //Parse Variable
|
||||
else if (isbtop()) prsbop(); //Parse Byte Operator
|
||||
else expctd("literal or variable");
|
||||
DEBUG("Parsed value of type %d\n", valtyp)
|
||||
skpspc();
|
||||
|
@ -56,7 +57,7 @@ void prcmns(void) {
|
|||
* "" if no index defined */
|
||||
void prsidx(int clbrkt) {
|
||||
expect('[');
|
||||
prsval(TRUE, TRUE); //Parse Value, Allowing Registers
|
||||
prsval(TRUE, TRUE); //Parse Value, Allow Registers & Constants
|
||||
DEBUG("Parsed array index '%s'\n", value)
|
||||
if (clbrkt) expect(']');
|
||||
}
|
||||
|
@ -114,7 +115,7 @@ void chkidx(void) {
|
|||
* Sets: term - the term (as a string) */
|
||||
int prstrm(int alwint) {
|
||||
DEBUG("Parsing term\n", 0)
|
||||
prsval(FALSE, TRUE); //Parse Term - Disallow Registers
|
||||
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);
|
||||
if (valtyp == VARIABLE && prcvar(alwint)) return TRUE;
|
||||
|
@ -180,19 +181,36 @@ int chkadr(int adract, int alwstr) {
|
|||
return result;
|
||||
}
|
||||
|
||||
/* Parse Byte Operator */
|
||||
void prsbop(void) {
|
||||
char byteop = getnxt();
|
||||
CCMNT(byteop);
|
||||
DEBUG("Parsing byte operator '%c'\n", byteop)
|
||||
if (chkadr(FALSE, FALSE)) {
|
||||
sprintf(value, "%c(%s)", byteop, word);
|
||||
valtyp = LITERAL;
|
||||
} else {
|
||||
reqvar(FALSE);
|
||||
if (vartyp != VTINT) ERROR("Integer Value Expected\n", 0, EXIT_FAILURE)
|
||||
if (byteop == '>') strcat(value, "+1");
|
||||
vartyp = VTCHAR;
|
||||
}
|
||||
DEBUG("Set value to \"%s\"\n", value)
|
||||
}
|
||||
|
||||
/* Parse Function Argument or Return Values */
|
||||
void prsfpr(char trmntr) {
|
||||
if (!chkadr(ADLDYX, TRUE) && isxpre() || match('?')) {
|
||||
if (!look('?')) {if (prsxpf(0)) goto prsfne;}
|
||||
if (!chkadr(ADLDYX, TRUE) && isxpre() || match('.')) {
|
||||
if (!look('.')) {if (prsxpf(0)) goto prsfne;}
|
||||
if (look(',') && !chkadr(ADLDYX, TRUE)) {
|
||||
if (!look('?')) {
|
||||
if (!look('.')) {
|
||||
if (prstrm(TRUE)) goto prsfne;
|
||||
asmlin("LDY", term);
|
||||
}
|
||||
if (look(',')) {
|
||||
prsval(FALSE, TRUE);
|
||||
prsval(FALSE, TRUE); //Parse Value - Disallow Registers, Allow Constants
|
||||
if (valtyp > VARIABLE) ERROR("Illegal Value Function Argument\n", 0, EXIT_FAILURE);
|
||||
if (valtyp == VARIABLE && varble.type != VTCHAR) ERROR("Illegal Variable Type\n", 0, EXIT_FAILURE);
|
||||
if (valtyp == VARIABLE && vartyp != VTCHAR) ERROR("Illegal Variable Type\n", 0, EXIT_FAILURE);
|
||||
asmlin("LDX", value); }
|
||||
}
|
||||
}
|
||||
|
@ -224,7 +242,7 @@ void prcvri(void) {
|
|||
|
||||
/* Process Variable in Term */
|
||||
int prcvar(int alwint) {
|
||||
switch (varble.type) {
|
||||
switch (vartyp) {
|
||||
case VTINT:
|
||||
if (!alwint) ERROR("Illegal Use of Integer Variable %s\n", word, EXIT_FAILURE)
|
||||
prcvri();
|
||||
|
@ -258,7 +276,7 @@ int prcftm(int alwint) {
|
|||
/* Parse first term of expession *
|
||||
* First term can include function calls */
|
||||
int prsftm(int alwint) {
|
||||
prsval(TRUE, TRUE); //Parse Value, Allowing Registers
|
||||
prsval(TRUE, TRUE); //Parse Value, Allow Registers & Constants
|
||||
return prcftm(alwint);
|
||||
}
|
||||
|
||||
|
@ -326,7 +344,10 @@ void prsxpi(char trmntr) {
|
|||
if (valtyp == FUNCTION) {
|
||||
strcpy(term, value);
|
||||
prsfnc(0); //Parse Expression Function
|
||||
} else if (valtyp == VARIABLE && varble.type == VTINT) {
|
||||
} else if (valtyp == STRUCTURE) {
|
||||
prsmbr(value);
|
||||
if (vartyp != VTINT) ERROR("Illegal Member %s In Integer Expression", value, EXIT_FAILURE)
|
||||
} else if (valtyp == VARIABLE && vartyp == VTINT) {
|
||||
prcvri(); //Process Integer Variable
|
||||
} else {
|
||||
ERROR("Illegal Variable %s In Integer Expression", value, EXIT_FAILURE)
|
||||
|
|
|
@ -18,6 +18,7 @@ int prcftm(int alwint); //Process First Term
|
|||
void prcvri(void); //Process Integer Variable
|
||||
int prcvar(int alwint); //Process Variable in Term
|
||||
void prsadr(int adract); //Parse and Compile Address of Operator
|
||||
void prsbop(void); //Parse Byte Operator
|
||||
void prsval(int alwreg, int alwcon); //Parse Value
|
||||
void prsfnc(char trmntr); //Parse function call
|
||||
void prsfpr(char trmntr); //Parse Function Paraeters or Return
|
||||
|
|
|
@ -22,6 +22,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 isbtop(void) {return TF(match('<') || match('>'));}
|
||||
int isdec(void) {return inbtwn('0', '9');}
|
||||
int iscpre(void) {return match('#');}
|
||||
int ishexd(void) {return TF(isdec() || inbtwn('A', 'Z'));}
|
||||
|
|
|
@ -29,6 +29,7 @@ int isanum(); //Is Next Character AlphaNumeric
|
|||
int isapos(); //Is Next Character an Apostrophe
|
||||
int isbin(); //Is Next Character a Binary Digit
|
||||
int isbpre(); //Is Next Character a Binary Prefix
|
||||
int isbtop(); //Is Next Character a Byte Operator
|
||||
int isdec(); //Is Next Character a Decimal Digit
|
||||
int iscpre(); //Is Next Character a Constant Prefix
|
||||
int ishexd(); //Is Next Character a Hexadecimal Digit
|
||||
|
|
17
src/stmnt.c
17
src/stmnt.c
|
@ -126,8 +126,8 @@ void prcasn(char trmntr) {
|
|||
void prcasi(char trmntr) {
|
||||
DEBUG("Processing Integer Assignment\n", 0);
|
||||
expect('=');
|
||||
strcpy(xsnvar, word); //Set Assignment LSB
|
||||
strcpy(ysnvar, word); strcat(ysnvar, "+1"); //Set Assignment MSB
|
||||
strcpy(xsnvar, vrname); //Set Assignment LSB
|
||||
strcpy(ysnvar, vrname); strcat(ysnvar, "+1"); //Set Assignment MSB
|
||||
ysnidx[0] = 0; //No Y Index
|
||||
prsxpi(trmntr);
|
||||
prcaxy();
|
||||
|
@ -145,13 +145,15 @@ int getidx(char* idx) {
|
|||
/* Process Assignment Variable(s) */
|
||||
void prcavr(char trmntr) {
|
||||
chksym(TRUE, FALSE, word);
|
||||
if (varble.type == VTINT) {
|
||||
if (ispopr()) {if (prspst(trmntr, TRUE, word, "")) expctd("post operator");}
|
||||
DEBUG("Processing assignment of variable %s\n", word);
|
||||
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");}
|
||||
else prcasi(trmntr); //Process Integer Assignment
|
||||
return;
|
||||
}
|
||||
strcpy(asnvar, word); //save variable to assign to
|
||||
if (valtyp == STRUCTURE) prsmbr(asnvar);
|
||||
strcpy(asnvar, vrname);
|
||||
asntyp = valtyp; //Set Assigned Variable Type
|
||||
DEBUG("Set STA variable to %s\n", asnvar)
|
||||
if (asntyp == VARIABLE && look(';')) {
|
||||
|
@ -210,6 +212,7 @@ void pasm(void) {
|
|||
/* 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);
|
||||
}
|
||||
|
||||
|
@ -343,7 +346,7 @@ void pinlne(void) {
|
|||
void ppop(void) {
|
||||
DEBUG("Parsing POP statement\n", 0)
|
||||
do {
|
||||
if (look('?')) term[0]=0;
|
||||
if (look('.')) term[0]=0;
|
||||
else {
|
||||
reqvar(TRUE);
|
||||
strcpy(term, value);
|
||||
|
|
115
src/vars.c
115
src/vars.c
|
@ -14,6 +14,7 @@
|
|||
#include "parse.h"
|
||||
#include "label.h"
|
||||
#include "vars.h"
|
||||
#include "dclrtn.h"
|
||||
|
||||
/* Lookup variable name in variable table *
|
||||
* Sets: varidx = index into vartbl array *
|
||||
|
@ -24,6 +25,7 @@ int fndvar(char *name) {
|
|||
for (varidx=0; varidx<varcnt; varidx++) {
|
||||
if (strcmp(vartbl[varidx].name, name) == 0) {
|
||||
memcpy(&varble, &vartbl[varidx], sizeof(varble));
|
||||
vartyp = varble.type;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +51,11 @@ int fndmbr(int idx, char *name) {
|
|||
DEBUG("Looking up member '%s'\n", word)
|
||||
for (mbridx=0; mbridx<mbrcnt; mbridx++) {
|
||||
if (membrs[mbridx].strcti != idx) continue;
|
||||
if (strcmp(membrs[mbridx].name, name) == 0) return TRUE;
|
||||
if (strcmp(membrs[mbridx].name, name) == 0) {
|
||||
memcpy(&membr, &membrs[mbridx], sizeof(membr));
|
||||
vartyp = membr.vartyp;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -84,7 +90,7 @@ void prcmbr(char* name) {
|
|||
if (valtyp == FUNCTION) ERROR("Illegal Function Reference\n", 0, EXIT_FAILURE)
|
||||
DEBUG("Checking for member %s", word) DETAIL(" with struct index %d\n", stcidx)
|
||||
if (!fndmbr(stcidx, word)) ERROR("Struct does Not Contain Member %s\n", word, EXIT_FAILURE)
|
||||
mbrofs += membrs[mbridx].offset; //Get Member Offet in Struct
|
||||
mbrofs += membr.offset; //Get Member Offet in Struct
|
||||
}
|
||||
|
||||
/* Parse next word as struct member *
|
||||
|
@ -95,9 +101,9 @@ void prsmbr(char* name) {
|
|||
mbrofs = 0;
|
||||
stcidx = varble.stcidx; //Get Struct Index
|
||||
prcmbr(name);
|
||||
while (membrs[mbridx].stype == STRUCTURE && nxtchr == '.') {
|
||||
stcidx = membrs[mbridx].symidx;
|
||||
prcmbr(membrs[mbridx].name);
|
||||
while (membr.vartyp == VTSTRUCT && nxtchr == '.') {
|
||||
stcidx = membr.symidx;
|
||||
prcmbr(membr.name);
|
||||
}
|
||||
sprintf(word, "+$%hhX", mbrofs); //Get Member Offet in Struct
|
||||
strcat(name, word); //Add Offset to Struct
|
||||
|
@ -133,8 +139,8 @@ int pidxof(void) {
|
|||
mbridx = -1; //Set Member Index to None
|
||||
reqvar(FALSE); //Parse Variable Name to get Size Of
|
||||
if (mbridx > -1) {
|
||||
sprintf(value, "$%hhX", membrs[mbridx].offset);
|
||||
return membrs[mbridx].offset;
|
||||
sprintf(value, "$%hhX", membr.offset);
|
||||
return membr.offset;
|
||||
}
|
||||
ERROR("IndexOf operator requires a struct member\n", 0, EXIT_FAILURE);
|
||||
return 0; //Suppress Warning
|
||||
|
@ -149,8 +155,8 @@ int psizof(void) {
|
|||
mbridx = -1; //Set Member Index to None
|
||||
reqvar(FALSE); //Parse Variable Name to get Size Of
|
||||
if (mbridx > -1) {
|
||||
sprintf(value, "$%hhX", membrs[mbridx].size);
|
||||
return membrs[mbridx].size;
|
||||
sprintf(value, "$%hhX", membr.size);
|
||||
return membr.size;
|
||||
}
|
||||
if (datlen[varidx]) {
|
||||
sprintf(value, "$%hhX", datlen[varidx]);
|
||||
|
@ -270,7 +276,7 @@ void addvar(int m, int t) {
|
|||
prsnum(0xFFFF);
|
||||
else {
|
||||
prsvar(FALSE, FALSE);
|
||||
if (t == VTINT && varble.type != t)
|
||||
if (t == VTINT && vartyp != t)
|
||||
ERROR("ALIAS Type Mismatch\n", 0, EXIT_FAILURE)
|
||||
if (t > VTINT) ERROR("Type may not be ALIASed\n", 0, EXIT_FAILURE)
|
||||
}
|
||||
|
@ -370,8 +376,10 @@ void wvrtbl(void) {
|
|||
void addstc(void) {
|
||||
if (!fndstc(word)) ERROR("Undefined Struct '%s\n", word,EXIT_FAILURE)
|
||||
strct = strcts[stcidx]; //Retrieve Structure
|
||||
getwrd(); //Get Variable Name
|
||||
addvar(MTNONE, VTSTRUCT);
|
||||
do {
|
||||
getwrd(); //Get Variable Name
|
||||
addvar(MTNONE, VTSTRUCT);
|
||||
} while (look(','));
|
||||
expect(';');
|
||||
}
|
||||
|
||||
|
@ -380,46 +388,63 @@ void addstc(void) {
|
|||
void defstc(void) {
|
||||
DEBUG("Parsing struct definition\n", 0)
|
||||
if (fndstc(word)) ERROR("Duplicate Declaration of Struct '%s\n", word,EXIT_FAILURE)
|
||||
int type;
|
||||
int prnidx = stcidx;
|
||||
strncpy(strct.name, word, STCLEN);
|
||||
DEBUG("Set struct name to '%s'\n", word);
|
||||
strct.size = 0; //Initialize Struct Length
|
||||
while (look('/')) skpcmt(FALSE); //Skip Comments
|
||||
do {
|
||||
getwrd(); //Get Member Name
|
||||
if (wordis("STRUCT")) {
|
||||
getwrd(); //Get Structure Name
|
||||
if (!fndstc(word)) ERROR("Structure '%s' Not Defined\n", word, EXIT_FAILURE)
|
||||
membr.stype = STRUCTURE;
|
||||
membr.size = strcts[stcidx].size;
|
||||
membr.symidx = stcidx;
|
||||
getwrd(); //Get Member Name
|
||||
} else {
|
||||
if (wordis("CHAR")) getwrd(); //Skip Optional Type Declaration
|
||||
membr.stype = VARIABLE;
|
||||
membr.size = 1;
|
||||
membr.symidx = -1;
|
||||
getwrd(); //Get Next word
|
||||
type = ctype(TRUE); //Check if word is a type declaration
|
||||
switch (type) {
|
||||
case TSTRUCT:
|
||||
vartyp = VTSTRUCT;
|
||||
getwrd(); //Get Structure Name
|
||||
if (!fndstc(word)) ERROR("Structure '%s' Not Defined\n", word, EXIT_FAILURE)
|
||||
mbrsiz = strcts[stcidx].size;
|
||||
break;
|
||||
case TINT:
|
||||
vartyp = VTINT;
|
||||
mbrsiz = 2;
|
||||
stcidx = -1;
|
||||
break;
|
||||
case TCHAR:
|
||||
vartyp = VTCHAR;
|
||||
mbrsiz = 1;
|
||||
stcidx = -1;
|
||||
break;
|
||||
default:
|
||||
ERROR("Invalid Type %s in Struct Definition\n", word, EXIT_FAILURE)
|
||||
}
|
||||
if (fndmbr(stccnt, word)) ERROR("Duplicate Declaration of Struct Member '%s\n", word,EXIT_FAILURE)
|
||||
DEBUG("Parsing member %s\n", word)
|
||||
strncpy(membr.name, word, STMLEN); //Set Member Name
|
||||
membr.strcti = prnidx; //Set Parent Struct Index
|
||||
membr.offset = strct.size; //Set Offset into Struct
|
||||
if (membr.stype == VARIABLE) {
|
||||
DEBUG("Checking for array definition\n", 0)
|
||||
if (match('[')) {
|
||||
CCMNT('[');
|
||||
skpchr();
|
||||
membr.stype = ARRAY;
|
||||
DEBUG("Parsing array size\n", 0)
|
||||
membr.size = prsnum(0xFF) + 1;
|
||||
expect(']');
|
||||
DEBUG("Parsing members of type %s\n", word)
|
||||
do {
|
||||
getwrd(); //Get Member Name
|
||||
DEBUG("Parsing member %s\n", word)
|
||||
if (fndmbr(stccnt, word)) ERROR("Duplicate Declaration of Struct Member '%s\n", word,EXIT_FAILURE)
|
||||
if (strlen(word) > STMLEN) ERROR("Member Name %s too long\n", word, EXIT_FAILURE)
|
||||
strcpy(membr.name, word); //Set Member Name
|
||||
membr.strcti = prnidx; //Set Parent Struct Index
|
||||
membr.vartyp = vartyp; //Set Member Variable Type
|
||||
membr.symidx = stcidx; //Set Member Symbol Index
|
||||
membr.offset = strct.size; //Set Offset into Struct
|
||||
membr.size = mbrsiz; //Set Member Size
|
||||
if (membr.vartyp == VTCHAR) {
|
||||
DEBUG("Checking member for array definition\n", 0)
|
||||
if (match('[')) {
|
||||
CCMNT('[');
|
||||
skpchr();
|
||||
membr.vartyp = VTARRAY;
|
||||
DEBUG("Parsing member array size\n", 0)
|
||||
membr.size = prsnum(0xFF) + 1;
|
||||
expect(']');
|
||||
}
|
||||
}
|
||||
}
|
||||
DEBUG("Set member type to %d", membr.stype) DETAIL(" and size to %d\n", membr.size);
|
||||
DEBUG("Adding member at index %d\n", mbrcnt);
|
||||
membrs[mbrcnt++] = membr;
|
||||
strct.size += membr.size;
|
||||
DEBUG("Set member type to %d", membr.vartyp) DETAIL(" and size to %d\n", membr.size);
|
||||
DEBUG("Adding member at index %d\n", mbrcnt);
|
||||
membrs[mbrcnt++] = membr;
|
||||
strct.size += membr.size;
|
||||
} while (look(','));
|
||||
expect(';');
|
||||
while (look('/')) skpcmt(FALSE); //Skip Comments
|
||||
} while (!look('}'));
|
||||
|
@ -440,7 +465,7 @@ void logstc(void) {
|
|||
for (mbridx=0; mbridx<mbrcnt; mbridx++) {
|
||||
membr = membrs[mbridx];
|
||||
fprintf(logfil, "%-8s %-8s", strcts[membr.strcti].name, membr.name);
|
||||
fprintf(logfil, " %5d %5d %6d %5d\n", membr.stype, membr.symidx, membr.offset, membr.size);
|
||||
fprintf(logfil, " %5d %5d %6d %5d\n", membr.vartyp, membr.symidx, membr.offset, membr.size);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ struct varrec varble; //Variable Table Entry
|
|||
int varcnt; //Number of Variables in Table
|
||||
int varidx; //Index into Variable Tables
|
||||
char vrname[MAXVAR+1]; //Variable Name
|
||||
int vartyp; //Variable/Member Type
|
||||
int vrwrtn; //Variables Written Flag
|
||||
|
||||
struct strctd { //Struct Definition
|
||||
|
@ -32,7 +33,7 @@ int stcidx; //Index into Struct Tables
|
|||
struct membrd { //Struct Membetr Definition
|
||||
char name[STMLEN+1]; //Member Name
|
||||
int strcti; //Parent Struct Index
|
||||
int stype; //Member Symbol Type
|
||||
int vartyp; //Member Symbol Type
|
||||
int symidx; //Member Symbol Index
|
||||
int offset; //Offset into Struct
|
||||
int size; //Member Size
|
||||
|
@ -43,6 +44,7 @@ struct membrd membr; //Defined Member
|
|||
int mbrcnt; //Number of Struct Members Defined
|
||||
int mbridx; //Index into Struct Member Tables
|
||||
int mbrofs; //Member Offset
|
||||
int mbrsiz; //Member Size
|
||||
|
||||
enum vtypes {VTVOID, VTREG, VTCHAR, VTINT, VTARRAY, VTSTRUCT}; //Variable Types
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**********************************************
|
||||
* STRINGS - Demonstrate string.h02 functions *
|
||||
**********************************************/
|
||||
/*********************************
|
||||
* STRUCTS - Test C02 structures *
|
||||
*********************************/
|
||||
|
||||
//Specify System Header using -H option
|
||||
#include <stddef.h02>
|
||||
|
@ -16,60 +16,64 @@ int yx;
|
|||
|
||||
//Define Structure
|
||||
struct record { /* Sample Record */
|
||||
char name[8]; //Name
|
||||
char index; //Index
|
||||
data[128]; //Data
|
||||
char name[8]; //Name
|
||||
char index; //Index
|
||||
int addr; //Address
|
||||
char data[128]; //Data
|
||||
};
|
||||
|
||||
//Declare Structure Variable
|
||||
struct record srcrec;
|
||||
struct record dstrec;
|
||||
|
||||
//Struct Containing Structs
|
||||
struct point { char xpos; char ypos; };
|
||||
//Structs Containing Structs
|
||||
struct point {char x, y; };
|
||||
struct point pnt;
|
||||
struct rect {struct point toplft; struct point btmrgt; };
|
||||
|
||||
struct rect {struct point toplft, btmrgt; };
|
||||
struct rect box;
|
||||
struct frame {struct rect outer; struct rect inner; };
|
||||
|
||||
struct frame {struct rect outer, inner; };
|
||||
struct frame fram;
|
||||
|
||||
main:
|
||||
|
||||
//Set Structure Members
|
||||
strdst(&srcrec.name); strcpy("RECNAME");
|
||||
strdst(srcrec.name); strcpy("RECNAME");
|
||||
srcrec.index = 1;
|
||||
srcrec.addr = &srcrec;
|
||||
for (i = 0; i<=@srcrec.data; i++)
|
||||
srcrec.data[i] = i;
|
||||
|
||||
//Clear Destination Record
|
||||
memclr(@dstrec,&dstrec);
|
||||
memclr(@dstrec, dstrec);
|
||||
prtdst();
|
||||
|
||||
//Copy Source Record into Destination Record
|
||||
memdst(&dstrec);
|
||||
memcpy(@srcrec, &srcrec);
|
||||
memdst(dstrec);
|
||||
memcpy(@srcrec, srcrec);
|
||||
|
||||
prtdst();
|
||||
|
||||
//Clear Box
|
||||
memclr(@box, &box); //Clear Box Members
|
||||
prtbox(); //Print Box Members
|
||||
memclr(@box, box); //Clear Box Members
|
||||
prtbox(""); //Print Box Members
|
||||
|
||||
//Set Box Members
|
||||
box.toplft.xpos=1; box.toplft.ypos=2;
|
||||
box.btmrgt.xpos=8; box.btmrgt.ypos=9;
|
||||
prtbox();
|
||||
box.toplft.x=1; box.toplft.y=2;
|
||||
box.btmrgt.x=8; box.btmrgt.y=9;
|
||||
prtbox("");
|
||||
newlin();
|
||||
|
||||
//Clear Frame
|
||||
memclr(@fram, &fram); //Clear Frame Members
|
||||
memclr(@fram, fram); //Clear Frame Members
|
||||
prtfrm(); //Print Frame Members
|
||||
|
||||
//Set Frame Members
|
||||
fram.outer.toplft.xpos=10; fram.outer.toplft.ypos=11;
|
||||
fram.outer.btmrgt.xpos=98; fram.outer.btmrgt.ypos=99;
|
||||
fram.inner.toplft.xpos=22; fram.inner.toplft.ypos=23;
|
||||
fram.inner.btmrgt.xpos=86; fram.inner.btmrgt.ypos=87;
|
||||
fram.outer.toplft.x=10; fram.outer.toplft.y=11;
|
||||
fram.outer.btmrgt.x=98; fram.outer.btmrgt.y=99;
|
||||
fram.inner.toplft.x=22; fram.inner.toplft.y=23;
|
||||
fram.inner.btmrgt.x=86; fram.inner.btmrgt.y=87;
|
||||
prtfrm();
|
||||
newlin();
|
||||
|
||||
|
@ -77,8 +81,9 @@ goto exit;
|
|||
|
||||
//Print Destination Record
|
||||
void prtdst() {
|
||||
setdst(&dstrec.name); printf("REC.NAME=\"%s\"%n");
|
||||
setdst(dstrec.name); printf("REC.NAME=\"%s\"%n");
|
||||
printf(dstrec.index, "REC.INDEX=%d%n");
|
||||
setdst(dstrec.addr); printf("REC.ADDR=$%w%n");
|
||||
puts("REC.DATA=[");
|
||||
for (i = 0; i<@dstrec.data; i++) {
|
||||
if (i) putc(',');
|
||||
|
@ -90,26 +95,26 @@ void prtdst() {
|
|||
|
||||
//Print Frame
|
||||
void prtfrm() {
|
||||
putln("OUTER."); cpybox(&fram.outer); prtbox();
|
||||
putln("INNER."); cpybox(&fram.inner); prtbox();
|
||||
cpybox(fram.outer); prtbox("OUTER.");
|
||||
cpybox(fram.inner); prtbox("INNER.");
|
||||
anykey();
|
||||
}
|
||||
|
||||
void cpybox() {
|
||||
savrxy(); setdst(&box);
|
||||
savrxy(); setdst(box);
|
||||
resrxy(); memcpy(@box);
|
||||
}
|
||||
|
||||
//Print Box
|
||||
void prtbox() {
|
||||
puts(" TOPLFT."); prtpnt(&box.toplft);
|
||||
puts(" BTMRGT."); prtpnt(&box.btmrgt);
|
||||
void prtbox(yx) {
|
||||
puts(yx); puts("TOPLFT."); prtpnt(box.toplft);
|
||||
puts(yx); puts("BTMRGT."); prtpnt(box.btmrgt);
|
||||
}
|
||||
|
||||
//Print Point
|
||||
void prtpnt() {
|
||||
savrxy(); setdst(&pnt);
|
||||
savrxy(); setdst(pnt);
|
||||
resrxy(); memcpy(@pnt);
|
||||
printf(pnt.xpos,"XPOS=%d,");
|
||||
printf(pnt.ypos,"YPOS=%d%n");
|
||||
printf(pnt.x,"X=%d,");
|
||||
printf(pnt.y,"Y=%d%n");
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#pragma zeropage $80
|
||||
|
||||
char b,d;
|
||||
char hi,lo;
|
||||
char s[128];
|
||||
char aa,yy,xx;
|
||||
|
||||
|
@ -15,6 +16,9 @@ int i,j;
|
|||
int m,n;
|
||||
int yx;
|
||||
|
||||
hi = >c; lo = <c;
|
||||
hi = >&c; lo = <&c;
|
||||
|
||||
i<<;
|
||||
j>>;
|
||||
m++;
|
||||
|
@ -31,13 +35,13 @@ d = fnd(b,c);
|
|||
i = fni(c);
|
||||
j = fnj(b,c);
|
||||
|
||||
int fnb(?,yy,xx) {
|
||||
return ?,xx,yy;
|
||||
int fnb(.,yy,xx) {
|
||||
return .,xx,yy;
|
||||
}
|
||||
|
||||
int fnd(aa,yy,xx) {
|
||||
if (aa) return ?,xx,yy;
|
||||
else return ?,yy,xx;
|
||||
if (aa) return .,xx,yy;
|
||||
else return .,yy,xx;
|
||||
}
|
||||
|
||||
int fni(yx) {
|
||||
|
|
|
@ -3,41 +3,77 @@
|
|||
#pragma origin 1000
|
||||
|
||||
char d, i;
|
||||
char lo, hi;
|
||||
char index, name[8], data[128];
|
||||
int addr;
|
||||
|
||||
//Define Structure
|
||||
struct record {
|
||||
char name[8];
|
||||
char index;
|
||||
char data[128];
|
||||
//Define Structures
|
||||
struct point {
|
||||
char x, y;
|
||||
};
|
||||
|
||||
//Declare Structure Variable
|
||||
struct line {
|
||||
struct point bgnpnt, endpnt;
|
||||
};
|
||||
|
||||
struct record {
|
||||
/* This is a Record */ //Extra Comment
|
||||
char name[8]; //Name
|
||||
char index; //Index
|
||||
int addr; //Address
|
||||
struct point pnt; //Point
|
||||
char data[128]; //Data
|
||||
};
|
||||
|
||||
//Declare Structure Variables
|
||||
struct point pnt;
|
||||
struct point bgnpnt, endpnt;
|
||||
struct line lin;
|
||||
struct record rec;
|
||||
|
||||
//Display Structure Info
|
||||
printf(?pnt.x,"?pnt.x=%d\t");
|
||||
printf(@pnt.x,"@pnt.x=%d\n");
|
||||
printf(?pnt.y,"?pnt.y=%d\t");
|
||||
printf(@pnt.y,"@pnt.y=%d\n");
|
||||
|
||||
printf(@rec,"@rec=%d\n");
|
||||
printf(?rec.name,"?rec.name=%d\t");
|
||||
printf(@rec.name,"@rec.name=%d\n");
|
||||
printf(?rec.index,"?rec.index=%d\t");
|
||||
printf(@rec.index,"@rec.index=%d\n");
|
||||
printf(?rec.addr,"?rec.addr=%d\t");
|
||||
printf(@rec.addr,"@rec.addr=%d\n");
|
||||
printf(?rec.pnt,"?rec.pnt=%d\t");
|
||||
printf(@rec.pnt,"@rec.pnt=%d\n");
|
||||
printf(?rec.data,"?rec.data=%d\t");
|
||||
printf(@rec.data,"@rec.data=%d\n");
|
||||
|
||||
//Get Member LSB & MSB
|
||||
hi = >rec.addr; lo = <rec.addr;
|
||||
hi = >&rec.data; lo = <&rec.data;
|
||||
|
||||
//Set Structure Members
|
||||
strdst(&rec.name); strcpy(name);
|
||||
rec.index = index;
|
||||
rec.addr = $ABCD;
|
||||
rec.pnt.x = 33;
|
||||
rec.pnt.y = 44;
|
||||
for (i = 0; i<=128; i++)
|
||||
rec.data[i] = d;
|
||||
|
||||
//Pass Entire Structure into Function
|
||||
blkput(@rec, &rec);
|
||||
|
||||
//Print Structure Members
|
||||
setdst(rec.name); putln("rec.name=\"%s\"");
|
||||
|
||||
//Copy Struct Member
|
||||
memdst(&data); memcpy(@rec.data, &rec.data);
|
||||
|
||||
//Get Structure Members
|
||||
index = rec.index;
|
||||
addr = rec.addr;
|
||||
for (i = 0; i<129; i++)
|
||||
d = rec.data[i];
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user