Added multiple return values on functions

This commit is contained in:
Curtis F Kaylor 2018-03-01 21:47:16 -05:00
parent 792c67507f
commit befddf1077
7 changed files with 124 additions and 42 deletions

2
c02.c
View File

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

View File

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

@ -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 '+':

View File

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

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

View File

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

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