This commit is contained in:
Lawrence Kesteloot 2018-08-05 16:27:33 -07:00
parent 007cf3e670
commit fb323943ce
4 changed files with 23 additions and 9 deletions

View File

@ -7,11 +7,11 @@ Runs between 5 and 30 times faster.
Supported features: The classic way to enter programs with
line numbers, 16-bit integer variables, `HOME`, `PRINT`, `IF/THEN`,
`FOR/NEXT`, `GOTO`, low-res graphics (`GR`, `PLOT`, `COLOR=`, `TEXT`),
`POKE`, and basic arithmetic.
`POKE`, and integer and boolean arithmetic.
Not supported: Floating point, strings, `NOT`, negative
Not supported: Floating point, strings, negative
integers, high-res graphics, `DATA/READ/RESUME`, `GOSUB/RETURN/POP`,
`DIM` (arrays), `REM`, keyboard input, and cassette I/O.
`DIM` (arrays), `REM`, keyboard input, exponentiation (`A^B`), and cassette I/O.
# Dependencies

View File

@ -15,6 +15,7 @@ extern void tosltax();
extern void tosgtax();
extern void tosleax();
extern void tosgeax();
extern void bnegax();
// Two bytes each.
extern unsigned int ptr1;

View File

@ -29,6 +29,8 @@
.export _tosleax := tosleax
.import tosgeax
.export _tosgeax := tosgeax
.import bnegax
.export _bnegax := bnegax
.importzp ptr1
.exportzp _ptr1 = ptr1

23
main.c
View File

@ -55,6 +55,7 @@ uint8_t title_length = 9;
#define T_TO 0x98
#define T_STEP 0x99
#define T_NEXT 0x9A
#define T_NOT 0x9B
// Operators. These encode both the operator (high nybble) and the precedence
// (low nybble). Lower precedence has a lower low nybble value. For example,
@ -153,6 +154,7 @@ static uint8_t *TOKEN[] = {
"TO",
"STEP",
"NEXT",
"NOT",
};
static int16_t TOKEN_COUNT = sizeof(TOKEN)/sizeof(TOKEN[0]);
@ -510,6 +512,10 @@ static void pop_operator_stack() {
g_c += 4;
break;
case OP_NOT:
add_call(bnegax);
break;
case OP_OPEN_PARENS:
// No-op.
break;
@ -528,13 +534,16 @@ static void pop_operator_stack() {
* https://en.wikipedia.org/wiki/Shunting-yard_algorithm
*/
static void push_operator_stack(uint8_t op) {
// All our operators are left-associative, so no special check for the case
// of equal precedence.
while (g_op_stack_size > 0 &&
g_op_stack[g_op_stack_size - 1] != OP_OPEN_PARENS &&
OP_PRECEDENCE(g_op_stack[g_op_stack_size - 1]) >= OP_PRECEDENCE(op)) {
// Don't pop anything off if op is unary.
if (op != OP_NOT) {
// All our operators are left-associative, so no special check for the case
// of equal precedence.
while (g_op_stack_size > 0 &&
g_op_stack[g_op_stack_size - 1] != OP_OPEN_PARENS &&
OP_PRECEDENCE(g_op_stack[g_op_stack_size - 1]) >= OP_PRECEDENCE(op)) {
pop_operator_stack();
pop_operator_stack();
}
}
// TODO Check for g_op_stack overflow.
@ -598,6 +607,8 @@ static uint8_t *compile_expression(uint8_t *s) {
op = OP_AND;
} else if (*s == T_OR) {
op = OP_OR;
} else if (*s == T_NOT) {
op = OP_NOT;
} else if (*s == T_EQUAL) {
if (s[1] == T_LESS_THAN) {
s += 1;