mirror of
https://github.com/RevCurtisP/C02.git
synced 2025-04-21 09:38:12 +00:00
Added multiple return values on functions
This commit is contained in:
parent
792c67507f
commit
befddf1077
2
c02.c
2
c02.c
@ -45,6 +45,8 @@ void init()
|
||||
invasc = FALSE;
|
||||
mskasc = FALSE;
|
||||
fcase = FALSE;
|
||||
xsnvar[0] = 0;
|
||||
ysnvar[0] = 0;
|
||||
}
|
||||
|
||||
/* Reads and parses the next Word in Source File */
|
||||
|
35
doc/c02.txt
35
doc/c02.txt
@ -1,4 +1,4 @@
|
||||
INTRODUCTION
|
||||
INTRODUCTION
|
||||
|
||||
C02 is a simple C-syntax language designed to generate highly optimized
|
||||
code for the 6502 microprocessor. The C02 specification is a highly
|
||||
@ -60,7 +60,12 @@ DIRECTIVES
|
||||
|
||||
Directives are special instructions to the compiler. They do not directy
|
||||
generate compiled code. A directive is denoted by a leading # character.
|
||||
C02 currently supports only one directive.
|
||||
|
||||
DEFINE
|
||||
|
||||
The #define directive creates a named constant.
|
||||
|
||||
INCLUDE
|
||||
|
||||
The #include directive causes the compiler to read and process and external
|
||||
file. In most cases, #include directives will be used with libraries of
|
||||
@ -110,7 +115,7 @@ A decimal number consists of one to three decimal digits (0 through 9).
|
||||
A hexadecimal number consists of a $ followed by two hexadecimal digits
|
||||
(0 through 9 or A through F).
|
||||
|
||||
A character literals consists of a single character surrounded by ' symbols.
|
||||
A character literal consists of a single character surrounded by ' symbols.
|
||||
A ' character may be specified by escaping it with a \.
|
||||
|
||||
Examples:
|
||||
@ -478,6 +483,24 @@ Examples:
|
||||
Note: An implicit assignment generates an STA opcode with the variable
|
||||
as the operand.
|
||||
|
||||
PLURAL ASSIGNMENTS
|
||||
|
||||
C02 allows a function to return up to three values by specifying multiple
|
||||
variables, separated by commas, to the left of the assignment operator (=).
|
||||
|
||||
The first and second variables to be assigned may be either simple variables
|
||||
or subscripted array elements. The third variable, if used, may only be a
|
||||
simple variable. Registers are not allowed in plural assignments.
|
||||
|
||||
Examples:
|
||||
row, col = scnpos(); //Get current screen position
|
||||
cr, mn, mx = cpmnmx(a, b); //Compare two values, return min and max
|
||||
lwr[i], upr[i] = tolwup(txt[i]); //Convert char to lower and upper case
|
||||
|
||||
Note: When compiled, a plural assignment generates an STX for the third
|
||||
assignment (if specified), an STY for the second assignment and an STA for
|
||||
the first assignment.
|
||||
|
||||
GOTO STATEMENT
|
||||
|
||||
A goto statement unconditionally transfers program execution to the
|
||||
@ -512,9 +535,9 @@ Examples:
|
||||
Note: In order to optimize the compiled code, the if and else statements
|
||||
are to 6502 relative branch instructions. This limits the amount of
|
||||
generated code between the if statement and the end of the if/else block
|
||||
to slightly less than 127 characters. This should be sufficient in most
|
||||
cases, but larger code blocks can be accommodated using function calls or
|
||||
goto statements.
|
||||
to slightly less than 127 bytes. This should be sufficient in most cases,
|
||||
but larger code blocks can be accommodated using function calls or goto
|
||||
statements.
|
||||
|
||||
SELECT, CASE, AND DEFAULT STATEMENTS
|
||||
|
||||
|
15
parse.c
15
parse.c
@ -71,7 +71,7 @@ char getnxt()
|
||||
void skpspc()
|
||||
{
|
||||
//DEBUG("Skipping Spaces\n", 0);
|
||||
if (isspc()) CCMNT(' ');
|
||||
if (isspc()) CCMNT(' '); //Add only the first space to comments
|
||||
while (isspc())
|
||||
getnxt();
|
||||
}
|
||||
@ -387,14 +387,6 @@ void prsopr()
|
||||
skpspc();
|
||||
}
|
||||
|
||||
/* Process Array Index */
|
||||
void prcidx(char *name, char *index)
|
||||
{
|
||||
if (strlen(index)) {
|
||||
asmlin("LDX", index);
|
||||
strcat(name,",X");
|
||||
}
|
||||
}
|
||||
|
||||
/* Generate Post-Operation Error */
|
||||
void poperr(char* name)
|
||||
@ -407,7 +399,10 @@ void poperr(char* name)
|
||||
void prcpst(char* name, char *index)
|
||||
{
|
||||
DEBUG("Processing post operation '%c'\n", oper);
|
||||
prcidx(name, index);
|
||||
if (strlen(index)) {
|
||||
asmlin("LDX", index);
|
||||
strcat(name,",X");
|
||||
}
|
||||
switch(oper)
|
||||
{
|
||||
case '+':
|
||||
|
2
parse.h
2
parse.h
@ -4,7 +4,7 @@
|
||||
|
||||
#define TF(x) (x) ? TRUE : FALSE;
|
||||
|
||||
enum stypes {CONSTANT, VARIABLE, ARRAY, FUNCTION}; //Symbol Types
|
||||
enum stypes {CONSTANT, VARIABLE, REGISTER, ARRAY, FUNCTION}; //Symbol Types
|
||||
enum etypes {ETDEF, ETMAC}; //Definition Types
|
||||
|
||||
char nxtwrd[LINELEN]; //Next Word (from DEFINE lookup)
|
||||
|
100
stmnt.c
100
stmnt.c
@ -59,61 +59,115 @@ void prssif(char trmntr) {
|
||||
setlbl(tmplbl); //Emit End of Expression Label
|
||||
}
|
||||
|
||||
/* Process Array Index */
|
||||
void prcidx(int idxtyp, char *name, char *index)
|
||||
{
|
||||
if (strlen(index)) {
|
||||
if (idxtyp == CONSTANT) {
|
||||
strcat(name, "+");
|
||||
strcat(name, index);
|
||||
}
|
||||
else {
|
||||
asmlin("LDX", index);
|
||||
strcat(name,",X");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Process Assignment */
|
||||
void prcasn(char trmntr)
|
||||
{
|
||||
expect('=');
|
||||
DEBUG("Processing assignment of variable '%s'\n", asnvar);
|
||||
if (look('('))
|
||||
prssif(trmntr); //Parse Shortcut If
|
||||
else
|
||||
prsxpr(trmntr); //Parse Expression
|
||||
DEBUG("Processing X assignment variable '%s'\n", xsnvar);
|
||||
if (xsnvar[0]) {
|
||||
asmlin("STX", xsnvar);
|
||||
xsnvar[0] = 0;
|
||||
}
|
||||
DEBUG("Processing Y assignment variable '%s'\n", ysnvar);
|
||||
if (ysnvar[0]) {
|
||||
if (strlen(ysnidx))
|
||||
prcidx(ysnivt, ysnvar, ysnidx);
|
||||
asmlin("STY", ysnvar);
|
||||
ysnvar[0] = 0;
|
||||
}
|
||||
DEBUG("Processing assignment variable '%s'\n", asnvar);
|
||||
if (strcmp(asnvar, "X")==0)
|
||||
asmlin("TAX", "");
|
||||
else if (strcmp(asnvar, "Y")==0)
|
||||
asmlin("TAY", "");
|
||||
else if ((strcmp(asnvar, "A")!=0))
|
||||
{
|
||||
if (strlen(asnidx)) {
|
||||
if (asnivt == CONSTANT) {
|
||||
strcat(asnvar, "+");
|
||||
strcat(asnvar, asnidx);
|
||||
}
|
||||
else {
|
||||
asmlin("LDX", asnidx);
|
||||
strcat(asnvar,",X");
|
||||
}
|
||||
}
|
||||
if (strlen(asnidx))
|
||||
prcidx(asnivt, asnvar, asnidx);
|
||||
asmlin("STA", asnvar);
|
||||
}
|
||||
}
|
||||
|
||||
/* Process Variable at Beginning of Statement */
|
||||
/* Parse and Return Array Index and Type */
|
||||
int getidx(char* idx)
|
||||
{
|
||||
prsidx(); //Parse Array Index
|
||||
if (valtyp == CONSTANT)
|
||||
strncpy(idx, word, VARLEN);
|
||||
else
|
||||
strncpy(idx, value, VARLEN);
|
||||
DEBUG("Set assigned index to %s\n", asnidx);
|
||||
return valtyp;
|
||||
}
|
||||
|
||||
/* Process Assignment Variable(s) */
|
||||
void prcvar(char trmntr)
|
||||
{
|
||||
chksym(TRUE, word);
|
||||
strcpy(asnvar, word); //sav variable to assign to
|
||||
if (valtyp == VARIABLE && look(';')) {
|
||||
strcpy(asnvar, word); //save variable to assign to
|
||||
asntyp = valtyp; //Set Assigned Varable Type
|
||||
DEBUG("Set STA variable to %s\n", asnvar);
|
||||
if (asntyp == VARIABLE && look(';')) {
|
||||
asmlin("STA", asnvar);
|
||||
return;
|
||||
}
|
||||
if (valtyp == ARRAY) {
|
||||
prsidx(); //Parse Array Index
|
||||
asnivt = valtyp;
|
||||
if (asnivt == CONSTANT)
|
||||
strncpy(asnidx, word, VARLEN);
|
||||
else
|
||||
strncpy(asnidx, value, VARLEN);
|
||||
if (asntyp == ARRAY) {
|
||||
asnivt = getidx(asnidx); //Get Array Index and Type
|
||||
DEBUG("Set STA index to %s\n", asnidx);
|
||||
DEBUG("Set STA index type to %d\n", asnivt);
|
||||
}
|
||||
else
|
||||
asnidx[0] = 0;
|
||||
if (ispopr()) {
|
||||
if (prspst(trmntr, asnvar, asnidx)) //Parse Post Operator
|
||||
expctd("post operator");
|
||||
/*refactor - put a return here and remove followig else*/
|
||||
}
|
||||
else
|
||||
else {
|
||||
if (look(',')) {
|
||||
if (asntyp == REGISTER) {
|
||||
ERROR("Register %s not allowed in plural assignment\n", asnvar, EXIT_FAILURE);
|
||||
}
|
||||
prsvar(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
|
||||
DEBUG("Set STY index to %s\n", ysnidx);
|
||||
DEBUG("Set STY index type to %d\n", ysnivt);
|
||||
}
|
||||
else
|
||||
ysnidx[0] = 0;
|
||||
if (look(',')) {
|
||||
prsvar(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
prcasn(trmntr);
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse 'asm' String Parameter */
|
||||
@ -141,7 +195,7 @@ void pasm()
|
||||
asmlin(opcode, word);
|
||||
}
|
||||
|
||||
/* Parse and Compile and Assignment */
|
||||
/* Parse and Compile an Assignment */
|
||||
void prsasn(char trmntr)
|
||||
{
|
||||
getwrd(); //Get Variable to be Assigned
|
||||
|
5
stmnt.h
5
stmnt.h
@ -3,8 +3,13 @@
|
||||
************************************/
|
||||
|
||||
char asnvar[VARLEN+1]; //Assigned Variable Name
|
||||
int asntyp; //Assigned Variable Type
|
||||
char asnidx[VARLEN+1] ; //Assigned Variable Index
|
||||
int asnivt; //Assigned Index Variable Type
|
||||
char ysnvar[VARLEN+1]; //Assigned Y Variable Name
|
||||
char ysnidx[VARLEN+1] ; //Assigned Variable Index
|
||||
int ysnivt; //Assigned Index Variable Type
|
||||
char xsnvar[VARLEN+1]; //Assigned X Variable Name
|
||||
|
||||
char xstmnt[LINELEN]; //Expected Statement
|
||||
|
||||
|
7
vars.c
7
vars.c
@ -36,8 +36,11 @@ int fndvar(char *name)
|
||||
void chksym(int alwreg, char *name)
|
||||
{
|
||||
if (strlen(name) == 1 && strchr("AXY", name[0])) {
|
||||
if (alwreg) return;
|
||||
else ERROR("Illegal reference to register %s\n", name, EXIT_FAILURE);
|
||||
if (alwreg && valtyp != ARRAY) {
|
||||
valtyp = REGISTER;
|
||||
return;
|
||||
}
|
||||
ERROR("Illegal reference to register %s\n", name, EXIT_FAILURE);
|
||||
}
|
||||
if (!fndvar(name))
|
||||
ERROR("Undeclared variable '%s' encountered\n", name, EXIT_FAILURE);
|
||||
|
Loading…
x
Reference in New Issue
Block a user