mirror of
https://github.com/RevCurtisP/C02.git
synced 2025-02-15 23:31:46 +00:00
Added logical operators 'and' and 'or' to conditionals
This commit is contained in:
parent
f35762abda
commit
fb9f396240
64
doc/c02.txt
64
doc/c02.txt
@ -420,10 +420,10 @@ Accumulator. However, due to the 6502 having only one Accumulatorm which
|
||||
is used for all operations between two bytes, there is no simple system
|
||||
agnostic method for allowing function calls in subsequent terms.
|
||||
|
||||
EVALUATIONS
|
||||
CONTENTIONS
|
||||
|
||||
An evaluation is a construct which generates either TRUE or FALSE condition.
|
||||
It may be an expression, a comparison, or a test.
|
||||
An contention is a construct which generates either TRUE or FALSE condition,
|
||||
and may be an expressions, comparisons, or test.
|
||||
|
||||
A stand-alone expression evaluates to TRUE if the result is non-zero, or
|
||||
FALSE if the result is zero.
|
||||
@ -455,8 +455,8 @@ a positive value upon succesful completion and a negative value if an error
|
||||
was encounters. They compile into smaller code than would be generated
|
||||
using the equivalent comparison operators.
|
||||
|
||||
A comparison may be preceded by negation operator (a ! character), which
|
||||
reverses the meaning of the entire comparison. For example,
|
||||
An contention may be preceded by negation operator (the ! character), which
|
||||
reverses the result of the entire contention. For example:
|
||||
! expr
|
||||
evaluates to TRUE if expr is zero, or FALSE if it is non-zero; while
|
||||
! expr = term
|
||||
@ -464,7 +464,7 @@ evaluates to TRUE if expr and term are not equal, or FALSE if they are; and
|
||||
! expr :+
|
||||
evaluates to TRUE if expr is negative, or FALSE if it is positive
|
||||
|
||||
Note: Evaluations are compiled directly into 6502 conditional branch
|
||||
Note: Contentions are compiled directly into 6502 conditional branch
|
||||
instructions, which precludes their use inside expressions. Standalone
|
||||
expressions and test-ops generate a single branch instruction, and
|
||||
therefore result in the most efficient code. Comparisons generate a
|
||||
@ -473,6 +473,29 @@ generate one, while <= and > generate two). A preceding negation operator
|
||||
will switch the number of branch instructions used in a comparison, but
|
||||
otherwise does not change the size of the generated code.
|
||||
|
||||
CONDITIONALS
|
||||
|
||||
A conditional consists of one or more contentions joined with the
|
||||
conjunctors "and" and "or".
|
||||
|
||||
If only one contention is present, the result of the conditional is the
|
||||
same as the result of the contention.
|
||||
|
||||
If two contentions are joined with "and", then the conditional is true only
|
||||
if both of the contentions are true. If either or both of the contentions
|
||||
are false, then the conditional is false.
|
||||
|
||||
If two contentions are joined with "or", then the conditional is true if
|
||||
either or both of the contentions are true. If both of the contentions are
|
||||
false, then the conditional is false.
|
||||
|
||||
When more three or more contentions are chained together, the conjunctors
|
||||
are evaluated in left to right order, using short-circuit evaluation. If
|
||||
the contention to the left of an "and" is false, then the entire conditional
|
||||
evaluates to false, and if the contention to the left of an "or" is true,
|
||||
then the entire conditional evaluates to true. In either case, no further
|
||||
contentions in the conditional are evaluated.
|
||||
|
||||
ARRAY SUBSCRIPTS
|
||||
|
||||
Individual elements of an array are accessed using subscript notation.
|
||||
@ -665,9 +688,9 @@ Examples:
|
||||
|
||||
SHORTCUT-IFS
|
||||
|
||||
A shortcut-if is a special form of assignment consisting of an evaluation
|
||||
A shortcut-if is a special form of assignment consisting of an contention
|
||||
and two expressions, of which one will be assigned based on the result
|
||||
of the evaluation. A shortcut-if is written as a condition surrounded
|
||||
of the contention. A shortcut-if is written as a condition surrounded
|
||||
by ( and ) characters, followed by a ? character, the expression to be
|
||||
evaluated if the condition was true, a : character, and the expression to
|
||||
be evaluated if the condition was false.
|
||||
@ -757,12 +780,13 @@ IF AND ELSE STATEMENTS
|
||||
The if then and else statements are used to conditionally execute blocks
|
||||
of code.
|
||||
|
||||
When using the if keyword, it is followed by an evaluation (surrounded by
|
||||
parenthesis) and the block of code to be executed if the evaluation was true.
|
||||
When using the if keyword, it is followed by a conditional (surrounded by
|
||||
parenthesis) and the block of code to be executed if the conditional was
|
||||
true.
|
||||
|
||||
An else statement may directly follow an if statement (with no other
|
||||
executable code intervening). The else keyword is followed by the block
|
||||
of code to be executed if the evaluation was false.
|
||||
of code to be executed if the conditional was false.
|
||||
|
||||
Examples:
|
||||
if (c = 27) goto end;
|
||||
@ -850,13 +874,13 @@ select expression will be executed.
|
||||
WHILE LOOPS
|
||||
|
||||
The while statement is used to conditionally execute code in a loop. When
|
||||
using the while keyword, it is followed by an evaluation (surrounded by
|
||||
parenthesis) and the the block of code to be executed while the evaluation
|
||||
is true. If the evaluation is false when the while statement is entered,
|
||||
using the while keyword, it is followed by a conditional (surrounded by
|
||||
parenthesis) and the the block of code to be executed while the conditional
|
||||
is true. If the conditional is false when the while statement is entered,
|
||||
the code in the block will never be executed.
|
||||
|
||||
Alternatively, the while keyword may be followed by a pair of empty
|
||||
parenthesis, in which case an evaluation of true is implied.
|
||||
parenthesis, in which case a conditional of true is implied.
|
||||
|
||||
Examples:
|
||||
c = 'A' ; while (c <= 'Z') {putc(c); c++;} //Print letters A-Z
|
||||
@ -869,10 +893,10 @@ DO WHILE LOOPS
|
||||
|
||||
The do statement used with to conditionally execute code in a loop at
|
||||
least once. When using the do keyword, it is followed by the block of
|
||||
code to be executed, a while statement, an evaluation (surrounded
|
||||
code to be executed, a while statement, a conditional (surrounded
|
||||
by parenthesis), and a terminating semicolon.
|
||||
|
||||
A while statement that follows a do loop must contain an evaluation.
|
||||
A while statement that follows a do loop must contain a conditional.
|
||||
The while statement is evaluated after each iteration of the loop, and
|
||||
if it is true, the code block is repeated.
|
||||
|
||||
@ -893,7 +917,7 @@ a set of values.
|
||||
|
||||
When using the if keyword, it is followed by a pair of parenthesis
|
||||
containing an initialization assignment statement (which is executed once),
|
||||
a semicolon separator, an evaluation (which determines if the code block
|
||||
a semicolon separator, a conditional (which determines if the code block
|
||||
is executed), another semicolon separator, and an increment assignment
|
||||
(which is executed after each iteration of the code block). This is then
|
||||
followed by the block of code to be conditionally executed.
|
||||
@ -926,8 +950,8 @@ break keyword, it is followed with a trailing semicolon.
|
||||
When a continue statement is encountered, program execution is transferred
|
||||
to the beginning of the block associated with the innermost do, for, or
|
||||
while statement. In the case of a for statement, the increment assignment
|
||||
is executed, followed by the evaluation, and in the case of a while
|
||||
statement, the evaluation is executed. When using the continue keyword, it
|
||||
is executed, followed by the conditional, and in the case of a while
|
||||
statement, the conditional is executed. When using the continue keyword, it
|
||||
is followed with a trailing semicolon.
|
||||
|
||||
Examples:
|
||||
|
@ -78,6 +78,22 @@ a function call as the first term).
|
||||
The sizeof operator in C02 is the at sign @. It may only be used with
|
||||
declared variables and struct members, not types.
|
||||
|
||||
CONDITIONALS
|
||||
|
||||
Conditional operations, including comparisons and logical operators,
|
||||
may not be used within or in place of normal expressions, and are only
|
||||
allowed in if, while, and for statements, as well as shortcut-ifs.
|
||||
|
||||
The comparison operators are ==, <, <=, >=, >, and <>. Unlike standard
|
||||
C, the not-equals operator is <> instead of !=. In addition, = may be
|
||||
substituted for ==. The logical not operator ! negates an entire
|
||||
comparison rather than an individual term within the comparison, thus
|
||||
the C02 code !b<x is equivalent to the C code !(b<x).
|
||||
|
||||
C02 uses the logical operators "and" and "or" instead of "&&" and "||",
|
||||
and performs short-circuit evaluation of logical operators, making them
|
||||
effectively right associative.
|
||||
|
||||
FUNCTIONS
|
||||
|
||||
Parameter passing uses the 6502's A, Y, and X registers. This limits
|
||||
|
@ -3,16 +3,86 @@
|
||||
****************************************/
|
||||
|
||||
#include <py65.h02>
|
||||
#include <stddef.h02>
|
||||
#include <stdlib.h02>
|
||||
#include <stdio.h02>
|
||||
#include <stdiox.h02>
|
||||
#include <test.h02>
|
||||
|
||||
char true = $FF;
|
||||
char false = $00;
|
||||
char pass = " Passed";
|
||||
char fail = " Failed";
|
||||
char n0=0, n1=1, n2=2, nff=255;
|
||||
char r,s; //Result & Summary
|
||||
|
||||
main:
|
||||
puts("if (true): "); if (true) putln(&pass); else putln(&fail);
|
||||
puts("if (false): "); if (false) putln(&fail); else putln(&pass);
|
||||
|
||||
puts( "if (#TRUE): "); if (#TRUE) passed(); else failed();
|
||||
puts("; if (#FALSE):"); if (#FALSE) failln(); else passln();
|
||||
newlin();
|
||||
|
||||
puts( "if (#TRUE and #TRUE ):"); if (#TRUE and #TRUE) passed(); else failed();
|
||||
puts("; if (#TRUE and #FALSE):"); if (#TRUE and #FALSE) failln(); else passln();
|
||||
puts( "if (#FALSE and #TRUE ):"); if (#FALSE and #TRUE) failed(); else passed();
|
||||
puts("; if (#FALSE and #FALSE):"); if (#FALSE and #FALSE) failln(); else passln();
|
||||
newlin();
|
||||
|
||||
puts( "if (#TRUE or #TRUE) :"); if (#TRUE or #TRUE) passed(); else failed();
|
||||
puts("; if (#TRUE or #FALSE):"); if (#TRUE or #FALSE) passln(); else failln();
|
||||
puts( "if (#FALSE or #TRUE) :"); if (#FALSE or #TRUE) passed(); else failed();
|
||||
puts("; if (#FALSE or #FALSE):"); if (#FALSE or #FALSE) failln(); else passln();
|
||||
newlin();
|
||||
|
||||
puts( "if (#TRUE and #TRUE and #TRUE) :"); if (#TRUE and #TRUE and #TRUE) passed(); else failed();
|
||||
puts("; if (#TRUE and #TRUE and #FALSE):"); if (#TRUE and #TRUE and #FALSE) failln(); else passln();
|
||||
puts( "if (#TRUE and #FALSE and #TRUE) :"); if (#TRUE and #FALSE and #TRUE) failed(); else passed();
|
||||
puts("; if (#TRUE and #FALSE and #FALSE):"); if (#TRUE and #FALSE and #FALSE) failln(); else passln();
|
||||
puts( "if (#FALSE and #TRUE and #TRUE) :"); if (#FALSE and #TRUE and #TRUE) failed(); else passed();
|
||||
puts("; if (#FALSE and #TRUE and #FALSE):"); if (#FALSE and #TRUE and #FALSE) failln(); else passln();
|
||||
puts( "if (#FALSE and #FALSE and #TRUE) :"); if (#FALSE and #FALSE and #TRUE) failed(); else passed();
|
||||
puts("; if (#FALSE and #FALSE and #FALSE):"); if (#FALSE and #FALSE and #FALSE) failln(); else passln();
|
||||
newlin();
|
||||
|
||||
puts( "if (#TRUE or #TRUE or #TRUE) :"); if (#TRUE or #TRUE or #TRUE) passed(); else failed();
|
||||
puts("; if (#TRUE or #TRUE or #FALSE):"); if (#TRUE or #TRUE or #FALSE) passln(); else failln();
|
||||
puts( "if (#TRUE or #FALSE or #TRUE) :"); if (#TRUE or #FALSE or #TRUE) passed(); else failed();
|
||||
puts("; if (#TRUE or #FALSE or #FALSE):"); if (#TRUE or #FALSE or #FALSE) passln(); else failln();
|
||||
puts( "if (#FALSE or #TRUE or #TRUE) :"); if (#FALSE or #TRUE or #TRUE) passed(); else failed();
|
||||
puts("; if (#FALSE or #TRUE or #FALSE):"); if (#FALSE or #TRUE or #FALSE) passln(); else failln();
|
||||
puts( "if (#FALSE or #FALSE or #TRUE) :"); if (#FALSE or #FALSE or #TRUE) passed(); else failed();
|
||||
puts("; if (#FALSE or #FALSE or #FALSE):"); if (#FALSE or #FALSE or #FALSE) failln(); else passln();
|
||||
anykey();
|
||||
|
||||
puts( "if (n0<n1): "); if (n0<n1) passed(); else failed();
|
||||
puts("; if (n2>n1): "); if (n2>n1) passln(); else failln();
|
||||
puts( "if (n1==n1):"); if (n1==n1) passed(); else failed();
|
||||
puts("; if (n0<>n2):"); if (n0<>n2) passln(); else failln();
|
||||
newlin();
|
||||
|
||||
puts( "if (n0<n1): "); if (n0<n1) passed(); else failed();
|
||||
puts("; if (n1<n2): "); if (n1<n2) passed(); else failed();
|
||||
puts("; if (n0<n2): "); if (n1<n2) passln(); else failln();
|
||||
|
||||
puts( "if (n1<=n1):"); if (n1<=n1) passed(); else failed();
|
||||
puts("; if (n1<=n2):"); if (n1<=n2) passed(); else failed();
|
||||
puts("; if (n1<n2): "); if (n1<=n2) passln(); else failln();
|
||||
|
||||
puts( "if (n1>=n1):"); if (n2>=n1) passed(); else failed();
|
||||
puts("; if (n2>=n1):"); if (n2>=n1) passed(); else failed();
|
||||
puts("; if (n2>n1): "); if (n2>n1) passln(); else failln();
|
||||
newlin();
|
||||
|
||||
puts( "if (n0): "); if (n0) failed(); else passed();
|
||||
puts("; if (n1): "); if (n1) passed(); else failed();
|
||||
puts("; if (n2): "); if (n1) passed(); else failed();
|
||||
puts("; if (nff): "); if (nff) passln(); else failln();
|
||||
|
||||
puts( "if (n0:+): "); if (n0:+) passed(); else failed();
|
||||
puts("; if (n1:+): "); if (n1:+) passed(); else failed();
|
||||
puts("; if (n2:+): "); if (n1:+) passed(); else failed();
|
||||
puts("; if (nff:+):"); if (nff:+) failln(); else passln();
|
||||
|
||||
puts( "if (n0:-): "); if (n0:-) failed(); else passed();
|
||||
puts("; if (n1:-): "); if (n1:-) failed(); else passed();
|
||||
puts("; if (n2:-): "); if (n1:-) failed(); else passed();
|
||||
puts("; if (nff:-):"); if (nff:-) passln(); else failln();
|
||||
newlin();
|
||||
|
||||
goto exit;
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
/* Initilize Compiler Variables */
|
||||
void init(void) {
|
||||
initim(); //Initialize Elapsed Time
|
||||
DEBUG("Initializing Compiler Variables\n",0)
|
||||
concnt = 0; //Number of Constants Defined
|
||||
varcnt = 0; //Number of Variables in Table
|
||||
|
17
src/common.c
17
src/common.c
@ -7,9 +7,11 @@
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <time.h>
|
||||
#include "common.h"
|
||||
|
||||
struct timespec curtim; //Current Time
|
||||
|
||||
/* Error - Print Input File name & position and exit */
|
||||
void exterr(int errnum) {
|
||||
fprintf(stderr, "Line %d Column %d of File %s\n", curlin, curcol, inpnam);
|
||||
@ -27,6 +29,19 @@ void expctd(char *expstr) {
|
||||
/* Print current position in file */
|
||||
void prtpos(void) { printf("(%s: %d,%d) ", inpnam, curlin, curcol); }
|
||||
|
||||
/* Initialize elapsed time counter */
|
||||
void initim(void) {
|
||||
timespec_get (&curtim, TIME_UTC);
|
||||
bgntim = curtim.tv_sec;
|
||||
}
|
||||
|
||||
/* Print elapsed time */
|
||||
void prttim(void) {
|
||||
timespec_get (&curtim, TIME_UTC);
|
||||
printf("[%d", curtim.tv_sec - bgntim);
|
||||
printf(".%06d]",curtim.tv_nsec/1000);
|
||||
}
|
||||
|
||||
/* Set comment to string */
|
||||
void setcmt(char *s) { strcpy(cmtasm, s); }
|
||||
|
||||
|
@ -36,8 +36,10 @@
|
||||
#define TRUE -1
|
||||
#define FALSE 0
|
||||
|
||||
void prtpos(); //Print current file name and position
|
||||
#define DEBUG(fmt, val) {if (debug) {prtpos(); printf(fmt, val);}}
|
||||
void initim(); //Initialize elapsed time counter
|
||||
void prtpos(); //Print current file name and position
|
||||
void prttim(); //Print elapsed time
|
||||
#define DEBUG(fmt, val) {if (debug) {prtpos(); prttim(); printf(fmt, val);}}
|
||||
#define DETAIL(fmt, val) {if (debug) printf(fmt, val);}
|
||||
#define ERROR(fmt, val, err) {fprintf(stderr, fmt, val);exterr(err);}
|
||||
|
||||
@ -49,6 +51,8 @@ char asmcmt[LINELEN]; //Processed Assembly Language Comment
|
||||
int curcol, curlin; //Position in Source Code
|
||||
int savcol, savlin; //Save Position in Source Code
|
||||
|
||||
int bgntim; //Starting Time
|
||||
|
||||
int nxtchr; //Next Character of Source File to Process
|
||||
int nxtupc; //Next Character Converted to Uppercase
|
||||
int savchr; //Holds nxtchr when switching input files
|
||||
|
79
src/cond.c
79
src/cond.c
@ -39,24 +39,31 @@ int enccmp(char c) {
|
||||
* Uses: term - Term Being Compared Against *
|
||||
* label - Branch Target if Comparison is FALSE */
|
||||
void prccmp(void) {
|
||||
DEBUG("Processing comparator %d\n", cmprtr)
|
||||
DEBUG("Processing comparator %d", cmprtr) DETAIL(" with REVCMP=%d\n", revcmp)
|
||||
if (cmprtr > 7) { //Process Flag
|
||||
cmprtr = (cmprtr ^ revcmp) & 1; //Apply Reversal
|
||||
if (cmprtr) asmlin("BPL", cmplbl);
|
||||
else asmlin("BMI", cmplbl);
|
||||
return;
|
||||
}
|
||||
cmprtr = (cmprtr ^ revcmp) & 7; //Apply reversal
|
||||
switch(cmprtr) {
|
||||
case 0: // Raw Expression (Skip)
|
||||
asmlin("BEQ", cndlbl); break;
|
||||
asmlin("BEQ", cmplbl); break;
|
||||
case 1: // = or ==
|
||||
asmlin("CMP", term); asmlin("BNE", cndlbl); break;
|
||||
asmlin("CMP", term); asmlin("BNE", cmplbl); break;
|
||||
case 2: // <
|
||||
asmlin("CMP", term); asmlin("BCS", cndlbl); break;
|
||||
asmlin("CMP", term); asmlin("BCS", cmplbl); break;
|
||||
case 3: // <= or =<
|
||||
asmlin("CLC", ""); asmlin("SBC", term); asmlin("BCS", cndlbl); break;
|
||||
asmlin("CLC", ""); asmlin("SBC", term); asmlin("BCS", cmplbl); break;
|
||||
case 4: // >
|
||||
asmlin("CLC", ""); asmlin("SBC", term); asmlin("BCC", cndlbl); break;
|
||||
asmlin("CLC", ""); asmlin("SBC", term); asmlin("BCC", cmplbl); break;
|
||||
case 5: // >= or =>
|
||||
asmlin("CMP", term); asmlin("BCC", cndlbl); break;
|
||||
asmlin("CMP", term); asmlin("BCC", cmplbl); break;
|
||||
case 6: // <> or ><
|
||||
asmlin("CMP", term); asmlin("BEQ", cndlbl); break;
|
||||
asmlin("CMP", term); asmlin("BEQ", cmplbl); break;
|
||||
case 7: // Raw Expression (Normal)
|
||||
asmlin("BNE", cndlbl); break;
|
||||
asmlin("BNE", cmplbl); break;
|
||||
default:
|
||||
ERROR("Unsupported comparison operator index %d\n", cmprtr, EXIT_FAILURE)
|
||||
}
|
||||
@ -73,33 +80,59 @@ void prscmp(int revrse) {
|
||||
}
|
||||
skpspc();
|
||||
if (cmprtr) prstrm();
|
||||
cmprtr = (cmprtr ^ revrse) & 7; //Apply reversal
|
||||
prccmp();
|
||||
//prccmp(); - Do after check for logical operator
|
||||
DEBUG("Parsed comparator %d\n", cmprtr)
|
||||
}
|
||||
|
||||
/* Parse Flag Operator */
|
||||
void prsflg(int revrse) {
|
||||
DEBUG("Parsing Flag Operator '%c'\n", nxtchr)
|
||||
if (match('+')) cmprtr = 0;
|
||||
else if (match('-')) cmprtr = 1;
|
||||
if (match('+')) cmprtr = 8; //Bit 0 = 0
|
||||
else if (match('-')) cmprtr = 9; //Bit 1 = 1
|
||||
else expctd("Flag operator");
|
||||
skpchr();
|
||||
cmprtr = (cmprtr ^ revrse) & 1; //Apply Reversal
|
||||
if (cmprtr) asmlin("BPL", cndlbl);
|
||||
else asmlin("BMI", cndlbl);
|
||||
}
|
||||
|
||||
/* Parse Logical Operator *
|
||||
* Sets: logops */
|
||||
void prslop(void) {
|
||||
DEBUG("Checking for Logical Operator\n", 0)
|
||||
logopr = LOPNONE;
|
||||
skpspc();
|
||||
if (isalph()) {
|
||||
getwrd(); //Get Logical Operator
|
||||
DEBUG("Parsing Logical Operator %s\n", word)
|
||||
if (wordis("AND")) logopr = LOPAND;
|
||||
else if (wordis("OR")) logopr = LOPOR;
|
||||
else ERROR("Encountered invalid token \"%s\"\n", word, EXIT_FAILURE)
|
||||
}
|
||||
DEBUG("Set LOGOPR to %d\n", logopr)
|
||||
}
|
||||
|
||||
/* Parse and Compile Conditional Expression *
|
||||
* Condition = <expression> <comparator> <term> */
|
||||
void prscnd(char trmntr, int revrse) {
|
||||
DEBUG("Parsing condition with REVRSE=%d\n", revrse)
|
||||
if (look('!')) {
|
||||
revrse = (revrse) ? FALSE: TRUE;
|
||||
DEBUG("Set REVRSE to %d\n", revrse)
|
||||
}
|
||||
if (!look('*')) prsxpr(0);
|
||||
if (look(':')) prsflg(revrse); //Parse Flag Operator
|
||||
else prscmp(revrse); //Parse Comparison Operator
|
||||
tmplbl[0] = 0;
|
||||
do {
|
||||
strcpy(cmplbl, cndlbl); DEBUG("Set CMPLBL to \"%s\"\n", cmplbl);
|
||||
revcmp = revrse;
|
||||
if (look('!')) revcmp = (revcmp) ? FALSE: TRUE;
|
||||
DEBUG("Set REVCMP to %d\n", revcmp)
|
||||
if (!look('*')) prsxpr(0);
|
||||
if (look(':')) prsflg(revcmp); //Parse Flag Operator
|
||||
else prscmp(revcmp); //Parse Comparison Operator
|
||||
prslop(); //Parse Logical Operator
|
||||
if (logopr == LOPOR) {
|
||||
revcmp = (revcmp) ? FALSE: TRUE;
|
||||
DEBUG("Set REVCMP to %d\n", revcmp)
|
||||
}
|
||||
if (logopr && revcmp) {
|
||||
if (!tmplbl[0]) newlbl(tmplbl);
|
||||
strcpy(cmplbl, tmplbl); DEBUG("Set CMPLBL to \"%s\"\n", cmplbl);
|
||||
}
|
||||
prccmp(); //Process Comparison/Flag Operator
|
||||
} while (logopr);
|
||||
if (tmplbl[0]) setlbl(tmplbl);
|
||||
expect(trmntr);
|
||||
}
|
||||
|
@ -2,4 +2,9 @@
|
||||
* C02 Conditional Parsing Routines *
|
||||
************************************/
|
||||
|
||||
enum LOGOPS {LOPNONE, LOPAND, LOPOR};
|
||||
|
||||
int revcmp; //Reverse Comparison
|
||||
int logopr; //Logical Operator (set to LOGOPS)
|
||||
|
||||
void prscnd(char trmntr, int revrse); //Parse Conditional Expression
|
||||
|
@ -3,6 +3,7 @@
|
||||
******************************************************/
|
||||
|
||||
char curlbl[LABLEN+1]; //Most recently generated label
|
||||
char cmplbl[LABLEN+1]; //Label for Comparison
|
||||
char cndlbl[LABLEN+1]; //Label for Conditional Code
|
||||
char endlbl[LABLEN+1]; //End Label
|
||||
char forlbl[LABLEN+1]; //For Loop Label
|
||||
|
@ -28,10 +28,10 @@ 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 islpre(); //Is Next Character a Literal Prefix
|
||||
int isdec(); //Is Next Character a Decimal Digit
|
||||
int iscpre(); //Is Next Character a Constant Prefix
|
||||
int ishexd(); //Is Next Character a Hexadecimal Digit
|
||||
int islpre(); //Is Next Character a Literal Prefix
|
||||
int isnl(); //Is Next Character a NewLine
|
||||
int isnpre(); //Is Next Character a Numeric Prfix
|
||||
int isoper(); //Is Next Character an Operator
|
||||
|
@ -48,11 +48,11 @@ void prssif(char trmntr) {
|
||||
prscnd(')', FALSE); //Parse Condition
|
||||
expect('?');
|
||||
prsxpr(':'); //Parse "if TRUE" expression
|
||||
newlbl(tmplbl); //Create End of Expression Label
|
||||
asmlin("JMP", tmplbl); //Jump over "if FALSE" expression
|
||||
newlbl(skplbl); //Create End of Expression Label
|
||||
asmlin("JMP", skplbl); //Jump over "if FALSE" expression
|
||||
setlbl(cndlbl); //Emit "if FALSE" label
|
||||
prsxpr(trmntr); //Parse "if FALSE" expression
|
||||
setlbl(tmplbl); //Emit End of Expression Label
|
||||
setlbl(skplbl); //Emit End of Expression Label
|
||||
}
|
||||
|
||||
/* Process Array Index */
|
||||
|
Loading…
x
Reference in New Issue
Block a user