mirror of
https://github.com/RevCurtisP/C02.git
synced 2024-09-28 20:56:53 +00:00
Added Integer Variables and Bitmask Enums
This commit is contained in:
parent
7252710f70
commit
dd4debeaaf
@ -79,7 +79,7 @@ void prscmp(int revrse) {
|
|||||||
if (cmpenc != 0) cmprtr = cmprtr | cmpenc; //Combine Encoded Comparator
|
if (cmpenc != 0) cmprtr = cmprtr | cmpenc; //Combine Encoded Comparator
|
||||||
}
|
}
|
||||||
skpspc();
|
skpspc();
|
||||||
if (cmprtr) prstrm();
|
if (cmprtr) prstrm(FALSE);
|
||||||
//prccmp(); - Do after check for logical operator
|
//prccmp(); - Do after check for logical operator
|
||||||
DEBUG("Parsed comparator %d\n", cmprtr)
|
DEBUG("Parsed comparator %d\n", cmprtr)
|
||||||
}
|
}
|
||||||
|
46
src/dclrtn.c
46
src/dclrtn.c
@ -17,10 +17,16 @@
|
|||||||
#include "stmnt.h"
|
#include "stmnt.h"
|
||||||
#include "dclrtn.h"
|
#include "dclrtn.h"
|
||||||
|
|
||||||
void addprm(char* prmtr) {
|
int addprm(char* prmtr) {
|
||||||
reqvar(FALSE); //Get Variable Name
|
reqvar(FALSE); //Get Variable Name
|
||||||
|
if (vartyp[varidx] == VTINT) {
|
||||||
|
strcpy(prmtrx, value);
|
||||||
|
strcpy(prmtry, value);
|
||||||
|
strcat(prmtry, "+1");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
strcpy(prmtr, value); //Copy to Parameter Variable
|
strcpy(prmtr, value); //Copy to Parameter Variable
|
||||||
prmcnt++; //Increment # of Parameters
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add Function Definition */
|
/* Add Function Definition */
|
||||||
@ -28,25 +34,28 @@ void addfnc(void) {
|
|||||||
if (infunc) ERROR("Nested Function Definitions Not Allowed\n", 0, EXIT_FAILURE)
|
if (infunc) ERROR("Nested Function Definitions Not Allowed\n", 0, EXIT_FAILURE)
|
||||||
expect('(');
|
expect('(');
|
||||||
strcpy(fncnam, word); //Save Function Name
|
strcpy(fncnam, word); //Save Function Name
|
||||||
prmcnt = 0; //Initialze Number of Parameters
|
prmtra[0] = 0; //Initialze Parameters
|
||||||
|
prmtry[0] = 0;
|
||||||
|
prmtrx[0] = 0;
|
||||||
skpspc(); //Skip Spaces
|
skpspc(); //Skip Spaces
|
||||||
if (isalph()) { //Parse Parameters
|
if (isalph() || match('*')) { //Parse Parameters
|
||||||
addprm(prmtra); //Get First Parameter
|
if (!look('*')) {if (addprm(prmtra)) goto addfne;} //Get First Parameter
|
||||||
if (look(',')) { //Look for Comma
|
if (look(',')) { //Look for Comma
|
||||||
addprm(prmtry); //Get Second Parameter
|
if (addprm(prmtry)) goto addfne; //Get Second Parameter
|
||||||
if (look(',')) { //Look for Comma
|
if (look(',')) { //Look for Comma
|
||||||
addprm(prmtrx); //Get Third Parameter
|
addprm(prmtrx); //Get Third Parameter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
addfne:
|
||||||
expect(')');
|
expect(')');
|
||||||
if (look(';')) return; //Forward Definition
|
if (look(';')) return; //Forward Definition
|
||||||
infunc = TRUE; //Set Inside Function Definition Flag
|
infunc = TRUE; //Set Inside Function Definition Flag
|
||||||
DEBUG("Set infunc to %d\n", infunc)
|
DEBUG("Set infunc to %d\n", infunc)
|
||||||
setlbl(fncnam); //Set Function Entry Point
|
setlbl(fncnam); //Set Function Entry Point
|
||||||
if (prmcnt > 0) asmlin("STA", prmtra); //Store First Parameter
|
if (prmtra[0]) asmlin("STA", prmtra); //Store First Parameter
|
||||||
if (prmcnt > 1) asmlin("STY", prmtry); //Store Second Parameter
|
if (prmtry[0]) asmlin("STY", prmtry); //Store Second Parameter
|
||||||
if (prmcnt > 2) asmlin("STX", prmtrx); //Store Third Parameter
|
if (prmtrx[0]) asmlin("STX", prmtrx); //Store Third Parameter
|
||||||
endlbl[0] = 0; //Create Dummy End Label
|
endlbl[0] = 0; //Create Dummy End Label
|
||||||
pshlbl(LTFUNC, endlbl); //and Push onto Stack
|
pshlbl(LTFUNC, endlbl); //and Push onto Stack
|
||||||
bgnblk('{'); //Start Program Block
|
bgnblk('{'); //Start Program Block
|
||||||
@ -67,18 +76,22 @@ void addcon(int numval) {
|
|||||||
if (!alcvar) SCMNT(""); //Clear Comment
|
if (!alcvar) SCMNT(""); //Clear Comment
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse Enum Declaration*/
|
/* Parse Enum Declaration
|
||||||
void penum(int m) {
|
*/
|
||||||
int enmval = 0;
|
void penum(int m, int bitmsk) {
|
||||||
DEBUG("Processing Enum Declarations\n", 0)
|
int enmval = (bitmsk) ? 1 : 0;
|
||||||
|
DEBUG("Processing Enum Declarations with BITMSK %d\n", bitmsk)
|
||||||
if (m != MTNONE) ERROR("Illegal Modifier %d in Enum Definition", m, EXIT_FAILURE)
|
if (m != MTNONE) ERROR("Illegal Modifier %d in Enum Definition", m, EXIT_FAILURE)
|
||||||
expect('{');
|
expect('{');
|
||||||
do {
|
do {
|
||||||
getwrd(); //get defined identifier
|
getwrd(); //get defined identifier
|
||||||
DEBUG("Enumerating '%s'\n", word)
|
DEBUG("Enumerating '%s'\n", word)
|
||||||
|
if (enmval > 0xFF) ERROR("Maximum ENUM or BITMASK value exceeded\n", 0, EXIT_FAILURE)
|
||||||
strncpy(defnam, word, VARLEN);
|
strncpy(defnam, word, VARLEN);
|
||||||
sprintf(value, "%d", enmval);
|
sprintf(value, "%d", enmval);
|
||||||
addcon(enmval++);
|
addcon(enmval);
|
||||||
|
if (bitmsk) enmval = enmval << 1;
|
||||||
|
else enmval++;
|
||||||
} while (look(','));
|
} while (look(','));
|
||||||
expect('}');
|
expect('}');
|
||||||
expect(';');
|
expect(';');
|
||||||
@ -115,8 +128,9 @@ void pdecl(int m, int t) {
|
|||||||
* Args: m - Modifier Type */
|
* Args: m - Modifier Type */
|
||||||
int ptype(int m) {
|
int ptype(int m) {
|
||||||
int reslt = TRUE;
|
int reslt = TRUE;
|
||||||
if (wordis("STRUCT")) pstrct(m); //Parse 'const' declaration
|
if (wordis("STRUCT")) pstrct(m); //Parse 'struct' declaration
|
||||||
else if (wordis("ENUM")) penum(m); //Parse 'enum' 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("CHAR")) pdecl(m, VTCHAR); //Parse 'char' declaration
|
||||||
else if (wordis("INT")) pdecl(m, VTINT); //Parse 'int' declaration
|
else if (wordis("INT")) pdecl(m, VTINT); //Parse 'int' declaration
|
||||||
else if (wordis("VOID")) pdecl(m, VTVOID); //Parse 'void' declaration
|
else if (wordis("VOID")) pdecl(m, VTVOID); //Parse 'void' declaration
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
char fncnam[VARLEN+1]; //Function Name
|
char fncnam[VARLEN+1]; //Function Name
|
||||||
char prmtra[VARLEN+1]; //Function Parameter A
|
char prmtra[VARLEN+1]; //Function Parameter A
|
||||||
char prmtrx[VARLEN+1]; //Function Parameter X
|
char prmtrx[VARLEN+1]; //Function Parameter X
|
||||||
char prmtry[VARLEN+1]; //Function Parameter Y
|
char prmtry[VARLEN+3]; //Function Parameter Y
|
||||||
int prmcnt; //Number of Parameters
|
int prmcnt; //Number of Parameters
|
||||||
//int lpemtd; //Location Prefix Emitted
|
//int lpemtd; //Location Prefix Emitted
|
||||||
|
|
||||||
|
104
src/expr.c
104
src/expr.c
@ -85,7 +85,7 @@ void prcsix(void) {
|
|||||||
void prcxix(void) {
|
void prcxix(void) {
|
||||||
pshtrm(); //Push Array Variable onto Term Stack
|
pshtrm(); //Push Array Variable onto Term Stack
|
||||||
if (trmcnt) asmlin("PHA", ""); //Save Accumulator if not first term
|
if (trmcnt) asmlin("PHA", ""); //Save Accumulator if not first term
|
||||||
prcftm(); //Process First Term of Expression
|
prcftm(FALSE); //Process First Term of Expression
|
||||||
prsrxp(']'); //Parse Rest of Expression
|
prsrxp(']'); //Parse Rest of Expression
|
||||||
asmlin("TAX", ""); //Transfer Result of Expression to Index Register
|
asmlin("TAX", ""); //Transfer Result of Expression to Index Register
|
||||||
if (trmcnt) asmlin("PLA", ""); //Restore Accumator if not first term
|
if (trmcnt) asmlin("PLA", ""); //Restore Accumator if not first term
|
||||||
@ -112,14 +112,20 @@ void chkidx(void) {
|
|||||||
|
|
||||||
/* Parse Term in Expression *
|
/* Parse Term in Expression *
|
||||||
* Sets: term - the term (as a string) */
|
* Sets: term - the term (as a string) */
|
||||||
void prstrm(void) {
|
int prstrm(int alwint) {
|
||||||
DEBUG("Parsing term\n", 0)
|
DEBUG("Parsing term\n", 0)
|
||||||
prsval(FALSE, TRUE); //Parse Term - Disallow Registers
|
prsval(FALSE, TRUE); //Parse Term - Disallow Registers
|
||||||
if (valtyp == FUNCTION) ERROR("Function call only allowed in first term\n", 0, EXIT_FAILURE)
|
if (valtyp == FUNCTION) ERROR("Function call only allowed in first term\n", 0, EXIT_FAILURE)
|
||||||
strcpy(term, value);
|
strcpy(term, value);
|
||||||
|
if (valtyp == VARIABLE && vartyp[varidx] == VTINT) {
|
||||||
|
if (!alwint) ERROR("Illegal Use of Integer Variable %s\n", term, EXIT_FAILURE)
|
||||||
|
prcvri(); //Process Integer Variable
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
DEBUG("Parsed term %s\n", term)
|
DEBUG("Parsed term %s\n", term)
|
||||||
chkidx(); //Check for Array Index
|
chkidx(); //Check for Array Index
|
||||||
skpspc();
|
skpspc();
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process Address Reference
|
/* Process Address Reference
|
||||||
@ -178,6 +184,22 @@ int chkadr(int adract, int alwstr) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Parse Function Parameters or Return Values */
|
||||||
|
void prsfpr(char trmntr) {
|
||||||
|
if (!chkadr(ADLDYX, TRUE) && isxpre() || match('*')) {
|
||||||
|
if (!look('*')) {if (prsxpf(0)) goto prsfne;}
|
||||||
|
if (look(',') && !chkadr(ADLDYX, TRUE)) {
|
||||||
|
if (!look('*')) {
|
||||||
|
if (prstrm(TRUE)) goto prsfne;
|
||||||
|
asmlin("LDY", term);
|
||||||
|
}
|
||||||
|
if (look(',')) { prsval(FALSE, TRUE); asmlin("LDX", value); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prsfne:
|
||||||
|
expect(trmntr);
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse function call */
|
/* Parse function call */
|
||||||
void prsfnc(char trmntr) {
|
void prsfnc(char trmntr) {
|
||||||
DEBUG("Processing Function Call '%s'\n", term)
|
DEBUG("Processing Function Call '%s'\n", term)
|
||||||
@ -185,38 +207,43 @@ void prsfnc(char trmntr) {
|
|||||||
pshtrm(); //Push Function Name onto Term Stack
|
pshtrm(); //Push Function Name onto Term Stack
|
||||||
skpchr(); //skip open paren
|
skpchr(); //skip open paren
|
||||||
CCMNT('(');
|
CCMNT('(');
|
||||||
if (!chkadr(ADLDYX, TRUE) && isxpre() || match('*')) {
|
prsfpr(')'); //Parse Function Parameters
|
||||||
if (!look('*')) prsxpr(0);
|
|
||||||
if (look(',') && !chkadr(ADLDYX, TRUE)) {
|
|
||||||
if (!look('*')) {
|
|
||||||
prstrm(); asmlin("LDY", term);
|
|
||||||
}
|
|
||||||
if (look(',')) { prsval(FALSE, TRUE); asmlin("LDX", value); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect(')');
|
|
||||||
expect(trmntr);
|
expect(trmntr);
|
||||||
poptrm(); //Pop Function Name off Term Stack
|
poptrm(); //Pop Function Name off Term Stack
|
||||||
asmlin("JSR", term);
|
asmlin("JSR", term);
|
||||||
skpspc();
|
skpspc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Process Integer Variable */
|
||||||
|
void prcvri(void) {
|
||||||
|
DEBUG("Processing Integer Variable '%s'\n", value)
|
||||||
|
asmlin("LDX", value);
|
||||||
|
strcat(value, "+1");
|
||||||
|
asmlin("LDY", value);
|
||||||
|
}
|
||||||
|
|
||||||
/* Process first term of expression */
|
/* Process first term of expression */
|
||||||
void prcftm(void) {
|
int prcftm(int alwint) {
|
||||||
DEBUG("Processing first term '%s'\n", value)
|
DEBUG("Processing first term '%s'\n", value)
|
||||||
strcpy(term, value);
|
strcpy(term, value);
|
||||||
|
if (valtyp == VARIABLE && vartyp[varidx] == VTINT) {
|
||||||
|
if (!alwint) ERROR("Illegal Use of Integer Variable %s\n", word, EXIT_FAILURE)
|
||||||
|
prcvri();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
if (valtyp == FUNCTION) prsfnc(0); //Parse Expression Function
|
if (valtyp == FUNCTION) prsfnc(0); //Parse Expression Function
|
||||||
else if (wordis("A")) return;
|
else if (wordis("A")) return FALSE;
|
||||||
else if (wordis("X")) asmlin("TXA", "");
|
else if (wordis("X")) asmlin("TXA", "");
|
||||||
else if (wordis("Y")) asmlin("TYA", "");
|
else if (wordis("Y")) asmlin("TYA", "");
|
||||||
else { chkidx(); asmlin("LDA", term); }
|
else { chkidx(); asmlin("LDA", term); }
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse first term of expession *
|
/* Parse first term of expession *
|
||||||
* First term can include function calls */
|
* First term can include function calls */
|
||||||
void prsftm(void) {
|
int prsftm(int alwint) {
|
||||||
prsval(TRUE, TRUE); //Parse Value, Allowing Registers
|
prsval(TRUE, TRUE); //Parse Value, Allowing Registers
|
||||||
prcftm();
|
return prcftm(alwint);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process Arithmetic or Bitwise Operator *
|
/* Process Arithmetic or Bitwise Operator *
|
||||||
@ -241,19 +268,56 @@ void prsrxp(char trmntr) {
|
|||||||
while (isoper()) {
|
while (isoper()) {
|
||||||
trmcnt++; //Increment Expression Depth
|
trmcnt++; //Increment Expression Depth
|
||||||
prsopr(); //Parse Operator
|
prsopr(); //Parse Operator
|
||||||
prstrm(); //Parse Term
|
prstrm(FALSE); //Parse Term
|
||||||
prcopr(); //Process Operator
|
prcopr(); //Process Operator
|
||||||
trmcnt--; //Decrement Expression Depth
|
trmcnt--; //Decrement Expression Depth
|
||||||
}
|
}
|
||||||
expect(trmntr);
|
expect(trmntr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse and compile expression */
|
int prsxpp(char trmntr, int alwint) {
|
||||||
void prsxpr(char trmntr) {
|
|
||||||
DEBUG("Parsing expression\n", 0)
|
DEBUG("Parsing expression\n", 0)
|
||||||
skpspc();
|
skpspc();
|
||||||
trmcnt = 0; //Initialize Expression Depth
|
trmcnt = 0; //Initialize Expression Depth
|
||||||
if (match('-')) prcmns(); //Process Unary Minus
|
if (match('-')) prcmns(); //Process Unary Minus
|
||||||
else prsftm(); //Parse First Term
|
else if (prsftm(alwint)) return TRUE; //Parse First Term
|
||||||
prsrxp(trmntr); //Parse Remainder of Express
|
prsrxp(trmntr); //Parse Remainder of Express
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse and compile expression */
|
||||||
|
void prsxpr(char trmntr) {
|
||||||
|
prsxpp(trmntr, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse and compile function parameter expression *
|
||||||
|
* Returns: TRUE if Integer Expression */
|
||||||
|
int prsxpf(char trmntr) {
|
||||||
|
return prsxpp(trmntr, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse and compile integer expression */
|
||||||
|
void prsxpi(char trmntr) {
|
||||||
|
skpspc();
|
||||||
|
if (!chkadr(TRUE, FALSE)) {
|
||||||
|
if (isnpre()) {
|
||||||
|
DEBUG("Parsing Integer Literal\n", 0)
|
||||||
|
int number = prsnum(0xFFFF);
|
||||||
|
sprintf(value, "%d", number & 0xFF); asmlin("LDX", value);
|
||||||
|
sprintf(value, "%d", number >> 8); asmlin("LDY", value);
|
||||||
|
} else if (isalph()) {
|
||||||
|
prsvar(FALSE, TRUE);
|
||||||
|
if (valtyp == FUNCTION) {
|
||||||
|
strcpy(term, value);
|
||||||
|
prsfnc(0); //Parse Expression Function
|
||||||
|
} else if (valtyp == VARIABLE && vartyp[varidx] == VTINT) {
|
||||||
|
prcvri(); //Process Integer Variable
|
||||||
|
} else {
|
||||||
|
ERROR("Illegal Variable %s In Integer Expression", value, EXIT_FAILURE)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ERROR("Expected Integer Value or Function\n", 0, EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect(trmntr);
|
||||||
}
|
}
|
||||||
|
11
src/expr.h
11
src/expr.h
@ -14,12 +14,15 @@ int trmcnt; //Number of total terms in current expression
|
|||||||
|
|
||||||
int chkadr(int adract, int alwstr); //Check for and Process Address or String
|
int chkadr(int adract, int alwstr); //Check for and Process Address or String
|
||||||
void chkidx(); //Check for, Parse, and Process Index
|
void chkidx(); //Check for, Parse, and Process Index
|
||||||
void prcftm(); //Process First Term
|
int prcftm(int alwint); //Process First Term
|
||||||
|
void prcvri(void); //Process Integer Variable
|
||||||
void prsadr(int adract); //Parse and Compile Address of Operator
|
void prsadr(int adract); //Parse and Compile Address of Operator
|
||||||
|
void prsval(int alwreg, int alwcon); //Parse Value
|
||||||
void prsfnc(char trmntr); //Parse function call
|
void prsfnc(char trmntr); //Parse function call
|
||||||
|
void prsfpr(char trmntr); //Parse Function Paraeters or Return
|
||||||
void prsidx(); //Parse Array Index
|
void prsidx(); //Parse Array Index
|
||||||
void prstrm(); //Parse Term in Expression
|
int prstrm(int alwint); //Parse Term in Expression
|
||||||
void prsrxp(char trmntr); //Parse Rest of Expression
|
void prsrxp(char trmntr); //Parse Rest of Expression
|
||||||
|
int prsxpf(char trmntr); //Parse Expression in Function Call
|
||||||
void prsxpr(char trmntr); //Parse Expression
|
void prsxpr(char trmntr); //Parse Expression
|
||||||
|
void prsxpi(char trmntr); //Parse Integer Expression
|
||||||
|
|
||||||
|
41
src/parse.c
41
src/parse.c
@ -12,11 +12,13 @@
|
|||||||
#include "files.h"
|
#include "files.h"
|
||||||
#include "asm.h"
|
#include "asm.h"
|
||||||
#include "parse.h"
|
#include "parse.h"
|
||||||
|
#include "label.h"
|
||||||
|
|
||||||
/* Various tests against nxtchr */
|
/* Various tests against nxtchr */
|
||||||
int match(char c) {return TF(nxtchr == c);}
|
int match(char c) {return TF(nxtchr == c);}
|
||||||
int inbtwn(char mn, char mx) {return TF(nxtupc >= mn && nxtupc <= mx);}
|
int inbtwn(char mn, char mx) {return TF(nxtupc >= mn && nxtupc <= mx);}
|
||||||
int isalph(void) {return isalpha(nxtchr);}
|
int isalph(void) {return isalpha(nxtchr);}
|
||||||
|
int isalst(void) {return TF(isalph() || match('*'));}
|
||||||
int isanum(void) {return isalnum(nxtchr);}
|
int isanum(void) {return isalnum(nxtchr);}
|
||||||
int isapos(void) {return match('\'');}
|
int isapos(void) {return match('\'');}
|
||||||
int isbin(void) {return inbtwn('0', '1');}
|
int isbin(void) {return inbtwn('0', '1');}
|
||||||
@ -354,8 +356,10 @@ void poperr(char* name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Process Post Operator */
|
/* Process Post Operator */
|
||||||
void prcpst(char* name, char *index) {
|
void prcpst(int isint, char* name, char *index) {
|
||||||
DEBUG("Processing post operation '%c'\n", oper)
|
DEBUG("Processing post operation '%c'\n", oper)
|
||||||
|
char name1[VARLEN+3];
|
||||||
|
strcpy(name1, name); strcat(name1, "+1");
|
||||||
if (strlen(index)) {
|
if (strlen(index)) {
|
||||||
asmlin("LDX", index);
|
asmlin("LDX", index);
|
||||||
strcat(name,",X");
|
strcat(name,",X");
|
||||||
@ -365,25 +369,48 @@ void prcpst(char* name, char *index) {
|
|||||||
if (strcmp(name, "X")==0) asmlin("INX", "");
|
if (strcmp(name, "X")==0) asmlin("INX", "");
|
||||||
else if (strcmp(name, "Y")==0) asmlin("INY", "");
|
else if (strcmp(name, "Y")==0) asmlin("INY", "");
|
||||||
else if (strcmp(name, "A")==0) poperr(name); //65C02 supports implicit INC, 6502 does not
|
else if (strcmp(name, "A")==0) poperr(name); //65C02 supports implicit INC, 6502 does not
|
||||||
else asmlin("INC", name);
|
else {
|
||||||
|
asmlin("INC", name);
|
||||||
|
if (isint) {
|
||||||
|
newlbl(skplbl);
|
||||||
|
asmlin("BNE", skplbl);
|
||||||
|
asmlin("INC", name1);
|
||||||
|
setlbl(skplbl);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case '-':
|
case '-':
|
||||||
if (strcmp(name, "X")==0) asmlin("DEX", "");
|
if (strcmp(name, "X")==0) asmlin("DEX", "");
|
||||||
else if (strcmp(name, "Y")==0) asmlin("DEY", "");
|
else if (strcmp(name, "Y")==0) asmlin("DEY", "");
|
||||||
else if (strcmp(name, "A")==0) poperr(name); //65C02 supports implicit DEC, 6502 does not
|
else if (strcmp(name, "A")==0) poperr(name); //65C02 supports implicit DEC, 6502 does not
|
||||||
else asmlin("DEC", name);
|
else {
|
||||||
|
if (isint) {
|
||||||
|
newlbl(skplbl);
|
||||||
|
asmlin("LDA", name);
|
||||||
|
asmlin("BNE", skplbl);
|
||||||
|
asmlin("DEC", name1);
|
||||||
|
setlbl(skplbl);
|
||||||
|
}
|
||||||
|
asmlin("DEC", name);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case '<':
|
case '<':
|
||||||
if (strcmp(name, "X")==0) poperr(name); //Index Register Shift not Supported
|
if (strcmp(name, "X")==0) poperr(name); //Index Register Shift not Supported
|
||||||
else if (strcmp(name, "Y")==0) poperr(name); //Index Register Shift not Supported
|
else if (strcmp(name, "Y")==0) poperr(name); //Index Register Shift not Supported
|
||||||
else if (strcmp(name, "A")==0) asmlin("ASL", "");
|
else if (strcmp(name, "A")==0) asmlin("ASL", "");
|
||||||
else asmlin("ASL", name);
|
else {
|
||||||
|
asmlin("ASL", name);
|
||||||
|
if (isint) asmlin("ROL", name1);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case '>':
|
case '>':
|
||||||
if (strcmp(name, "X")==0) poperr(name); //Index Register Shift not Supported
|
if (strcmp(name, "X")==0) poperr(name); //Index Register Shift not Supported
|
||||||
else if (strcmp(name, "Y")==0) poperr(name); //Index Register Shift not Supported
|
else if (strcmp(name, "Y")==0) poperr(name); //Index Register Shift not Supported
|
||||||
else if (strcmp(name, "A")==0) asmlin("LSR", "");
|
else if (strcmp(name, "A")==0) asmlin("LSR", "");
|
||||||
else asmlin("LSR", name);
|
else {
|
||||||
|
asmlin("LSR", name);
|
||||||
|
if (isint) asmlin("ROR", name1);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ERROR("Unrecognized post operator '%c'\n", oper, EXIT_FAILURE)
|
ERROR("Unrecognized post operator '%c'\n", oper, EXIT_FAILURE)
|
||||||
@ -391,7 +418,7 @@ void prcpst(char* name, char *index) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Parse Post Operator */
|
/* Parse Post Operator */
|
||||||
int prspst(char trmntr, char* name, char* index) {
|
int prspst(char trmntr, int isint, char* name, char* index) {
|
||||||
oper = getnxt();
|
oper = getnxt();
|
||||||
CCMNT(oper);
|
CCMNT(oper);
|
||||||
DEBUG("Checking for post operation '%c'\n", oper)
|
DEBUG("Checking for post operation '%c'\n", oper)
|
||||||
@ -399,7 +426,7 @@ int prspst(char trmntr, char* name, char* index) {
|
|||||||
skpchr();
|
skpchr();
|
||||||
CCMNT(oper);
|
CCMNT(oper);
|
||||||
expect(trmntr);
|
expect(trmntr);
|
||||||
prcpst(name, index); //Process Post-Op
|
prcpst(isint, name, index); //Process Post-Op
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
DEBUG("Not a post operation\n", 0)
|
DEBUG("Not a post operation\n", 0)
|
||||||
|
@ -25,6 +25,7 @@ int mskasc; //Set High Bit Flag
|
|||||||
|
|
||||||
int match(char c); //Does Next Character match c
|
int match(char c); //Does Next Character match c
|
||||||
int isalph(); //Is Next Character Alphabetic
|
int isalph(); //Is Next Character Alphabetic
|
||||||
|
int isalst(); //Is Next Character Alpha or Asterisk
|
||||||
int isanum(); //Is Next Character AlphaNumeric
|
int isanum(); //Is Next Character AlphaNumeric
|
||||||
int isapos(); //Is Next Character an Apostrophe
|
int isapos(); //Is Next Character an Apostrophe
|
||||||
int isbin(); //Is Next Character a Binary Digit
|
int isbin(); //Is Next Character a Binary Digit
|
||||||
@ -54,7 +55,7 @@ int prsbyt(); //Parse Numeric Byte
|
|||||||
void prslit(); //Parse Literal
|
void prslit(); //Parse Literal
|
||||||
int prsnum(int maxval); //Parse Numeric
|
int prsnum(int maxval); //Parse Numeric
|
||||||
void prsopr(); //Parse Arithmetic Operator
|
void prsopr(); //Parse Arithmetic Operator
|
||||||
int prspst(char trmntr, char* name, char* index); //Parse Post Operator
|
int prspst(char trmntr, int isint, char* name, char* index); //Parse Post Operator
|
||||||
int psizof(void); //Parse SizeOf Operator
|
int psizof(void); //Parse SizeOf Operator
|
||||||
int pidxof(void); //Parse SizeOf Operator
|
int pidxof(void); //Parse SizeOf Operator
|
||||||
void skpchr(); //Skip Next Character
|
void skpchr(); //Skip Next Character
|
||||||
|
40
src/stmnt.c
40
src/stmnt.c
@ -77,11 +77,8 @@ void setasn(char *name) {
|
|||||||
if (wrtofs[0]) strcat(word, wrtofs);
|
if (wrtofs[0]) strcat(word, wrtofs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process Assignment */
|
/* Process Assignment of X and Y variables */
|
||||||
void prcasn(char trmntr) {
|
void prcaxy(void) {
|
||||||
expect('=');
|
|
||||||
if (look('(')) prssif(trmntr); //Parse Shortcut If
|
|
||||||
else prsxpr(trmntr); //Parse Expression
|
|
||||||
DEBUG("Processing X assignment variable '%s'\n", xsnvar)
|
DEBUG("Processing X assignment variable '%s'\n", xsnvar)
|
||||||
if (xsnvar[0]) {
|
if (xsnvar[0]) {
|
||||||
setasn(xsnvar);
|
setasn(xsnvar);
|
||||||
@ -107,6 +104,14 @@ void prcasn(char trmntr) {
|
|||||||
asmlin("STY", word); //Store Return Value
|
asmlin("STY", word); //Store Return Value
|
||||||
ysnvar[0] = 0;
|
ysnvar[0] = 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process Assignment */
|
||||||
|
void prcasn(char trmntr) {
|
||||||
|
expect('=');
|
||||||
|
if (look('(')) prssif(trmntr); //Parse Shortcut If
|
||||||
|
else prsxpr(trmntr); //Parse Expression
|
||||||
|
prcaxy(); //Process X and Y assignments
|
||||||
DEBUG("Checking if '%s' is a register\n", asnvar)
|
DEBUG("Checking if '%s' is a register\n", asnvar)
|
||||||
if (strcmp(asnvar, "X")==0) asmlin("TAX", "");
|
if (strcmp(asnvar, "X")==0) asmlin("TAX", "");
|
||||||
else if (strcmp(asnvar, "Y")==0) asmlin("TAY", "");
|
else if (strcmp(asnvar, "Y")==0) asmlin("TAY", "");
|
||||||
@ -117,6 +122,17 @@ void prcasn(char trmntr) {
|
|||||||
asmlin("STA", word); //Store Return Value
|
asmlin("STA", word); //Store Return Value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Process Integer Assignment */
|
||||||
|
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
|
||||||
|
ysnidx[0] = 0; //No Y Index
|
||||||
|
prsxpi(trmntr);
|
||||||
|
prcaxy();
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse and Return Array Index and Type */
|
/* Parse and Return Array Index and Type */
|
||||||
int getidx(char* idx) {
|
int getidx(char* idx) {
|
||||||
prsidx(TRUE); //Parse Array Index
|
prsidx(TRUE); //Parse Array Index
|
||||||
@ -129,9 +145,14 @@ int getidx(char* idx) {
|
|||||||
/* Process Assignment Variable(s) */
|
/* Process Assignment Variable(s) */
|
||||||
void prcvar(char trmntr) {
|
void prcvar(char trmntr) {
|
||||||
chksym(TRUE, FALSE, word);
|
chksym(TRUE, FALSE, word);
|
||||||
|
if (vartyp[varidx] == VTINT) {
|
||||||
|
if (ispopr()) {if (prspst(trmntr, TRUE, word, "")) expctd("post operator");}
|
||||||
|
else prcasi(trmntr); //Process Integer Assignment
|
||||||
|
return;
|
||||||
|
}
|
||||||
strcpy(asnvar, word); //save variable to assign to
|
strcpy(asnvar, word); //save variable to assign to
|
||||||
if (valtyp == VARIABLE && match('.')) prsmbr(asnvar);
|
if (valtyp == VARIABLE && match('.')) prsmbr(asnvar);
|
||||||
asntyp = valtyp; //Set Assigned Varable Type
|
asntyp = valtyp; //Set Assigned Variable Type
|
||||||
DEBUG("Set STA variable to %s\n", asnvar)
|
DEBUG("Set STA variable to %s\n", asnvar)
|
||||||
if (asntyp == VARIABLE && look(';')) {
|
if (asntyp == VARIABLE && look(';')) {
|
||||||
asmlin("STA", asnvar);
|
asmlin("STA", asnvar);
|
||||||
@ -141,7 +162,7 @@ void prcvar(char trmntr) {
|
|||||||
else asnidx[0] = 0;
|
else asnidx[0] = 0;
|
||||||
DEBUG("Set STA index to '%s'", asnidx) DETAIL(" and type to %d\n", asnivt)
|
DEBUG("Set STA index to '%s'", asnidx) DETAIL(" and type to %d\n", asnivt)
|
||||||
if (ispopr()) {
|
if (ispopr()) {
|
||||||
if (prspst(trmntr, asnvar, asnidx)) expctd("post operator");
|
if (prspst(trmntr, FALSE, asnvar, asnidx)) expctd("post operator");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (look(',')) {
|
if (look(',')) {
|
||||||
@ -349,7 +370,8 @@ void ppush(void) {
|
|||||||
/* parse and compile return statement */
|
/* parse and compile return statement */
|
||||||
void pretrn(void) {
|
void pretrn(void) {
|
||||||
DEBUG("Parsing RETURN statement\n", 0)
|
DEBUG("Parsing RETURN statement\n", 0)
|
||||||
if (!look(';')) prsxpr(';');
|
skpspc();
|
||||||
|
prsfpr(';'); //Parse Function Return Valuea
|
||||||
asmlin("RTS", "");
|
asmlin("RTS", "");
|
||||||
lsrtrn = TRUE; //Set RETURN flag
|
lsrtrn = TRUE; //Set RETURN flag
|
||||||
}
|
}
|
||||||
@ -382,7 +404,7 @@ void pcase(void) {
|
|||||||
newlbl(cndlbl); //Create Conditional Label
|
newlbl(cndlbl); //Create Conditional Label
|
||||||
pshlbl(LTCASE, cndlbl); //and Push onto Stack
|
pshlbl(LTCASE, cndlbl); //and Push onto Stack
|
||||||
while(TRUE) {
|
while(TRUE) {
|
||||||
prstrm(); //Parse CASE argument
|
prstrm(FALSE); //Parse CASE argument
|
||||||
if (!fcase || valtyp != LITERAL || litval)
|
if (!fcase || valtyp != LITERAL || litval)
|
||||||
asmlin("CMP", term); //Emit Comparison
|
asmlin("CMP", term); //Emit Comparison
|
||||||
if (look(',')) {
|
if (look(',')) {
|
||||||
|
29
src/vars.c
29
src/vars.c
@ -198,6 +198,12 @@ void setdat(void) {
|
|||||||
dlen = 1;
|
dlen = 1;
|
||||||
datvar[dsize++] = litval;
|
datvar[dsize++] = litval;
|
||||||
}
|
}
|
||||||
|
else if (dtype == DTINT) {
|
||||||
|
DEBUG("Setting variable data to '%d'\n", litval)
|
||||||
|
dlen = 2;
|
||||||
|
datvar[dsize++] = litval & 0xFF;
|
||||||
|
datvar[dsize++] = litval >> 8;
|
||||||
|
}
|
||||||
else if (dtype == DTARRY) {
|
else if (dtype == DTARRY) {
|
||||||
DEBUG("Setting variable data to array of length %d\n", dlen)
|
DEBUG("Setting variable data to array of length %d\n", dlen)
|
||||||
for (i=0; i<dlen; i++) datvar[dsize++] = dattmp[i];
|
for (i=0; i<dlen; i++) datvar[dsize++] = dattmp[i];
|
||||||
@ -213,15 +219,16 @@ void setdat(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Parse and store variable data */
|
/* Parse and store variable data */
|
||||||
void prsdat(int m) {
|
void prsdat(int m, int t) {
|
||||||
if ((m & MTCONST) == 0) ERROR("Initialization allowed only on variables declared CONST\n", 0, EXIT_FAILURE);
|
if ((m & MTCONST) == 0) ERROR("Initialization allowed only on variables declared CONST\n", 0, EXIT_FAILURE);
|
||||||
DEBUG("Parsing variable data\n", 0)
|
DEBUG("Parsing variable data\n", 0)
|
||||||
skpspc();
|
skpspc();
|
||||||
if (islpre()) {dtype = DTBYTE; prslit(); } //Parse Data Literal
|
if (t == VTINT) {dtype = DTINT; litval = prsnum(0xFFFF); } //Parse Integer
|
||||||
|
else if (islpre()) {dtype = DTBYTE; prslit(); } //Parse Data Literal
|
||||||
else if (match('"')) prsdts(); //Parse Data String
|
else if (match('"')) prsdts(); //Parse Data String
|
||||||
else if (match('{')) prsdta(); //Parse Data Array
|
else if (match('{')) prsdta(); //Parse Data Array
|
||||||
else expctd("numeric or string literal");
|
else expctd("numeric or string literal");
|
||||||
if (alcvar || dtype == DTBYTE) setdat(); //Store Data Value
|
if (alcvar || dtype <= DTINT) setdat(); //Store Data Value
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add Variable to Variable table *
|
/* Add Variable to Variable table *
|
||||||
@ -240,13 +247,14 @@ void setvar(int m, int t) {
|
|||||||
/* Parse and Compile Variable Declaration *
|
/* Parse and Compile Variable Declaration *
|
||||||
* Uses: word - variable name */
|
* Uses: word - variable name */
|
||||||
void addvar(int m, int t) {
|
void addvar(int m, int t) {
|
||||||
if (t == VTINT) ERROR("Integer Variables not yet Implemented", 0, EXIT_FAILURE)
|
//if (t == VTINT) ERROR("Integer Variables not yet Implemented\n", 0, EXIT_FAILURE)
|
||||||
strcpy(vrname, word); //Save Variable Name
|
strcpy(vrname, word); //Save Variable Name
|
||||||
if (fndvar(vrname)) ERROR("Duplicate declaration of variable '%s\n", vrname, EXIT_FAILURE)
|
if (fndvar(vrname)) ERROR("Duplicate declaration of variable '%s\n", vrname, EXIT_FAILURE)
|
||||||
if (t == VTVOID) ERROR("Illegal Variable Type\n", 0, EXIT_FAILURE)
|
if (t == VTVOID) ERROR("Illegal Variable Type\n", 0, EXIT_FAILURE)
|
||||||
if (m & MTZP) {
|
if (m & MTZP) {
|
||||||
setlbl(vrname);
|
setlbl(vrname);
|
||||||
sprintf(word, "$%hhX", zpaddr++);
|
sprintf(word, "$%hhX", zpaddr++);
|
||||||
|
if (t == VTINT) zpaddr++; //int uses two bytes
|
||||||
asmlin(EQUOP, word);
|
asmlin(EQUOP, word);
|
||||||
strcpy(value, "*"); //Set Variable to Non Allocated
|
strcpy(value, "*"); //Set Variable to Non Allocated
|
||||||
}
|
}
|
||||||
@ -255,7 +263,13 @@ void addvar(int m, int t) {
|
|||||||
skpspc();
|
skpspc();
|
||||||
expect('=');
|
expect('=');
|
||||||
skpspc();
|
skpspc();
|
||||||
if (isnpre()) prsnum(0xFFFF); else prsvar(FALSE, FALSE);
|
if (isnpre())
|
||||||
|
prsnum(0xFFFF);
|
||||||
|
else {
|
||||||
|
prsvar(FALSE, FALSE);
|
||||||
|
if (t == VTINT && vartyp[varidx] != t)
|
||||||
|
ERROR("ALIAS Type Mismatch\n", 0, EXIT_FAILURE)
|
||||||
|
}
|
||||||
asmlin(EQUOP, word);
|
asmlin(EQUOP, word);
|
||||||
strcpy(value, "*"); //Set Variable to Non Allocated
|
strcpy(value, "*"); //Set Variable to Non Allocated
|
||||||
}
|
}
|
||||||
@ -263,6 +277,9 @@ void addvar(int m, int t) {
|
|||||||
if (t == VTSTRUCT) {
|
if (t == VTSTRUCT) {
|
||||||
DEBUG("Setting variable size to %d\n", strct.size)
|
DEBUG("Setting variable size to %d\n", strct.size)
|
||||||
sprintf(value, "%d", strct.size);
|
sprintf(value, "%d", strct.size);
|
||||||
|
} else if (t == VTINT) {
|
||||||
|
DEBUG("Setting variable size to %d\n", 2)
|
||||||
|
sprintf(value, "%d", 2);
|
||||||
} else if (match('[')) {
|
} else if (match('[')) {
|
||||||
CCMNT('[')
|
CCMNT('[')
|
||||||
skpchr();
|
skpchr();
|
||||||
@ -276,7 +293,7 @@ void addvar(int m, int t) {
|
|||||||
if (!alcvar) strcpy(value, "*");
|
if (!alcvar) strcpy(value, "*");
|
||||||
}
|
}
|
||||||
setvar(m, t); //Add to Variable Table
|
setvar(m, t); //Add to Variable Table
|
||||||
if (look('=')) prsdat(m); //Parse Variable Data
|
if (look('=')) prsdat(m, t); //Parse Variable Data
|
||||||
varcnt++; //Increment Variable Counter
|
varcnt++; //Increment Variable Counter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ int dtype; //Data Type
|
|||||||
int dlen; //Length of Variable Data
|
int dlen; //Length of Variable Data
|
||||||
int dsize; //Total Data Length
|
int dsize; //Total Data Length
|
||||||
|
|
||||||
enum dtypes {DTBYTE, DTSTR, DTARRY}; //Variable Data Types
|
enum dtypes {DTBYTE, DTINT, DTSTR, DTARRY}; //Variable Data Types
|
||||||
|
|
||||||
/* Variable Modifier Types (Bit Mask) */
|
/* Variable Modifier Types (Bit Mask) */
|
||||||
#define MTNONE 0 //No Modifier
|
#define MTNONE 0 //No Modifier
|
||||||
|
29
work/addrs.c02
Normal file
29
work/addrs.c02
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/***************************
|
||||||
|
* Test Address References *
|
||||||
|
***************************/
|
||||||
|
char b , i; //byte type has been removed
|
||||||
|
char c,d,f; //a char is an unsigned 8 bit number
|
||||||
|
char r[15]; //reserves dimension bytes
|
||||||
|
char z[15];
|
||||||
|
const char s = "This is a string.";
|
||||||
|
|
||||||
|
|
||||||
|
funcx:
|
||||||
|
f = testfn(&s); //Pointer
|
||||||
|
f = testfn(b,&s); //Byte and Pointer
|
||||||
|
f = testfn(r[i],&s); //Array Element and Pointer
|
||||||
|
f = testfn(r[1],&s); //Array Element and Pointer
|
||||||
|
f = testfn(b+c+d,&s); //Expression in Function Call
|
||||||
|
f = testfn(getkey(b)+c); //Nested Function Call
|
||||||
|
|
||||||
|
funcs:
|
||||||
|
testfn(&s); //Print a String
|
||||||
|
|
||||||
|
goto &$C000;
|
||||||
|
|
||||||
|
push &s, b+c+d, r[i];
|
||||||
|
isort(); inline &r;
|
||||||
|
|
||||||
|
blkbgn(&$C000);
|
||||||
|
blkend(&$C400);
|
||||||
|
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
enum {SOLO};
|
enum {SOLO};
|
||||||
enum {ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN};
|
enum {ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN};
|
||||||
|
bitmask {BLUE, GREEN, RED, BRIGHT, INVERT, BLINK, FLIP, BKGRND};
|
||||||
|
|
||||||
const char b = {#TRUE, #FALSE};
|
const char b = {#TRUE, #FALSE};
|
||||||
char c, i;
|
char c, i;
|
||||||
|
52
work/ints.c02
Normal file
52
work/ints.c02
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/* Test Integer Variables */
|
||||||
|
|
||||||
|
#pragma origin $F000
|
||||||
|
#pragma zeropage $80
|
||||||
|
|
||||||
|
char b,d;
|
||||||
|
char s[128];
|
||||||
|
char aa,yy,xx;
|
||||||
|
|
||||||
|
zeropage int zp80, zp82;
|
||||||
|
alias int c0 = $C000;
|
||||||
|
const int c = $1234;
|
||||||
|
int e;
|
||||||
|
int i,j;
|
||||||
|
int m,n;
|
||||||
|
int yx;
|
||||||
|
|
||||||
|
i<<;
|
||||||
|
j>>;
|
||||||
|
m++;
|
||||||
|
n--;
|
||||||
|
|
||||||
|
e = $5678;
|
||||||
|
e = c;
|
||||||
|
e = &$D000;
|
||||||
|
e = &s;
|
||||||
|
|
||||||
|
b = fnb(e);
|
||||||
|
d = fnd(b,c);
|
||||||
|
|
||||||
|
i = fni(c);
|
||||||
|
j = fnj(b,c);
|
||||||
|
|
||||||
|
int fnb(*,yy,xx) {
|
||||||
|
return *,xx,yy;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fnd(aa,yy,xx) {
|
||||||
|
if (aa) return *,xx,yy;
|
||||||
|
else return *,yy,xx;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fni(yx) {
|
||||||
|
yx++;
|
||||||
|
return yx;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fnj(aa, yx) {
|
||||||
|
if (aa:-) yx--;
|
||||||
|
else {if (aa) yx++;}
|
||||||
|
return yx;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user