From 84d9a7ce82b6184639caeeac7a4026818833d6ee Mon Sep 17 00:00:00 2001 From: Lawrence Kesteloot Date: Sun, 5 Aug 2018 16:43:50 -0700 Subject: [PATCH] Add unary minus (negative). --- README.md | 4 ++-- exporter.h | 1 + exporter.s | 2 ++ main.c | 20 +++++++++++++++++--- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 0d7afe8..855ecd0 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,8 @@ line numbers, 16-bit integer variables, `HOME`, `PRINT`, `IF/THEN`, `FOR/NEXT`, `GOTO`, low-res graphics (`GR`, `PLOT`, `COLOR=`, `TEXT`), `POKE`, and integer and boolean arithmetic. -Not supported: Floating point, strings, negative -integers, high-res graphics, `DATA/READ/RESUME`, `GOSUB/RETURN/POP`, +Not supported: Floating point, strings, +high-res graphics, `DATA/READ/RESUME`, `GOSUB/RETURN/POP`, `DIM` (arrays), `REM`, keyboard input, exponentiation (`A^B`), and cassette I/O. # Dependencies diff --git a/exporter.h b/exporter.h index bd03554..3a848bb 100644 --- a/exporter.h +++ b/exporter.h @@ -16,6 +16,7 @@ extern void tosgtax(); extern void tosleax(); extern void tosgeax(); extern void bnegax(); +extern void negax(); // Two bytes each. extern unsigned int ptr1; diff --git a/exporter.s b/exporter.s index e44c9a0..ee47161 100644 --- a/exporter.s +++ b/exporter.s @@ -31,6 +31,8 @@ .export _tosgeax := tosgeax .import bnegax .export _bnegax := bnegax +.import negax +.export _negax := negax .importzp ptr1 .exportzp _ptr1 = ptr1 diff --git a/main.c b/main.c index c2a5098..69e8485 100644 --- a/main.c +++ b/main.c @@ -516,6 +516,10 @@ static void pop_operator_stack() { add_call(bnegax); break; + case OP_NEG: + add_call(negax); + break; + case OP_OPEN_PARENS: // No-op. break; @@ -535,7 +539,7 @@ static void pop_operator_stack() { */ static void push_operator_stack(uint8_t op) { // Don't pop anything off if op is unary. - if (op != OP_NOT) { + if (op != OP_NOT && op != OP_NEG) { // All our operators are left-associative, so no special check for the case // of equal precedence. while (g_op_stack_size > 0 && @@ -556,6 +560,7 @@ static void push_operator_stack(uint8_t op) { */ static uint8_t *compile_expression(uint8_t *s) { char have_value_in_ax = 0; + uint8_t expect_unary_minus = 1; // Expect unary minus at start of expression. while (1) { if (IS_DIGIT(*s)) { @@ -567,6 +572,9 @@ static uint8_t *compile_expression(uint8_t *s) { compile_load_ax(parse_uint16(&s)); have_value_in_ax = 1; + + // Expect binary minus after operand. + expect_unary_minus = 0; } else if (IS_FIRST_VARIABLE_LETTER(*s)) { // Variable reference. uint8_t var = find_variable(&s); @@ -590,6 +598,9 @@ static uint8_t *compile_expression(uint8_t *s) { g_c += 4; } have_value_in_ax = 1; + + // Expect binary minus after operand. + expect_unary_minus = 0; } else { // Check if it's an operator. uint8_t op = OP_INVALID; @@ -597,8 +608,7 @@ static uint8_t *compile_expression(uint8_t *s) { if (*s == T_PLUS) { op = OP_ADD; } else if (*s == T_MINUS) { - // TODO check for unary. - op = OP_SUB; + op = expect_unary_minus ? OP_NEG : OP_SUB; } else if (*s == T_ASTERISK) { op = OP_MULT; } else if (*s == T_SLASH) { @@ -656,6 +666,10 @@ static uint8_t *compile_expression(uint8_t *s) { } } + // Expect unary minus after operators or open parenthesis. Expect + // binary minus after close parenthesis. + expect_unary_minus = op != OP_CLOSE_PARENS; + if (op != OP_INVALID) { s += 1; if (op != OP_CLOSE_PARENS) {