From 831bc8f4530ebe16a23f40de78101886b1615400 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Sun, 7 Jun 2020 15:01:09 +0200 Subject: [PATCH] integrated operator recognition routine --- c64/basic/engine/ad9e.frmevl.s | 38 ++++----- c64/basic/engine/fetch_operator.s | 93 +++++++++++++++++++++++ c64/basic/operators/operators_jumptable.s | 44 +++++------ 3 files changed, 131 insertions(+), 44 deletions(-) create mode 100644 c64/basic/engine/fetch_operator.s diff --git a/c64/basic/engine/ad9e.frmevl.s b/c64/basic/engine/ad9e.frmevl.s index b7594b1e..1b4e8fc3 100644 --- a/c64/basic/engine/ad9e.frmevl.s +++ b/c64/basic/engine/ad9e.frmevl.s @@ -129,26 +129,22 @@ FRMEVL_got_value: FRMEVL_fetch_operator: - // We have a value, but this is not the end of expression. We expect - // a two argument operator here. First make sure we have enough space - // on a stack - we will surely need it + // We have a value, but this is not the end of expression. Check if + // there is an operator waiting to be served + + jsr fetch_operator + bcs FRMEVL_calculate // branch if operator not recognized + + // We have a two-argument operator - check if there is enough stack space + // XXX this can probably be checked later tsx cpx #$40 // XXX is this a safe threshold? bcc_16 do_FORMULA_TOO_COMPLEX_error - // Now look for an operator - // XXX for now only addition operator is implemented + // XXX check the priorities - either push to stack, or execute it immediately - jsr fetch_character - cmp #$AA // check for a plus operator - beq FRMEVL_push_value_operator - - // Something unknown - consider this the end of expression - - jsr unconsume_character - - // FALTROUGH + bcs FRMEVL_push_value_operator // branch always FRMEVL_calculate: // this is the exit point for the operators @@ -168,7 +164,11 @@ FRMEVL_done: FRMEVL_push_value_operator: - // First push the return address + // Move the operator ID in .Y + + tay + + // Push the return address lda #>(FRMEVL_calculate - 1) pha @@ -204,16 +204,16 @@ FRMEVL_push_operator_address: // Push the operator address to stack, in a form // suitable for RTS - // XXX add support for other operators + // XXX add support for other operators, use .Y - lda #>(oper_add - 1) + lda operator_jumptable_hi - 1, y pha - lda #<(oper_add - 1) + lda operator_jumptable_lo - 1, y pha // Push operator priority - lda #$01 // XXX add support for other operators + lda operator_priorities - 1, y pha // Continue diff --git a/c64/basic/engine/fetch_operator.s b/c64/basic/engine/fetch_operator.s new file mode 100644 index 00000000..5c55e426 --- /dev/null +++ b/c64/basic/engine/fetch_operator.s @@ -0,0 +1,93 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Fetches an operator - for the expression parser +// +// Note: does not recognize unary operators +// + + +fetch_operator: // XXX change the operator code to start from 0 + + // Retrieve the next character + + jsr fetch_character + + // Check if within range + + sec + sbc #$A9 + bcc fetch_operator_failed // branch if below 0 + beq fetch_operator_failed // branch 0 + + cmp #$0B + bcs fetch_operator_failed // branch if $0B or greater + + // Now we have to recognize '>=', '<=' and '<>' operators + + cmp #$08 + beq fetch_operator_try_gteq + + cmp #$0A + beq fetch_operator_try_lteq_neq + + // FALLTROUGH + +fetch_operator_success: + + clc + rts + +fetch_operator_failed: + + sec + rts + + +fetch_operator_try_gteq: + + // Here we distinguish between '>' and '>=' + + jsr fetch_character + cmp #$B2 // '=' + beq !+ + + // This is a '>' + + jsr unconsume_character + lda #$08 + bne fetch_operator_success // branch always +!: + // This is a '>=' + + lda #$0B + bne fetch_operator_success // branch always + + +fetch_operator_try_lteq_neq: + + // Here we distinguish between '<', '<=', and '<>' + + jsr fetch_character + cmp #$B2 // '=' + beq !+ + cmp #$B1 // '>' + beq !++ + + // This is a '<' + + jsr unconsume_character + lda #$0A + bne fetch_operator_success // branch always +!: + // This is a '<=' + + lda #$0C + bne fetch_operator_success // branch always +!: + // This is a '<>' + + lda #$0D + bne fetch_operator_success // branch always diff --git a/c64/basic/operators/operators_jumptable.s b/c64/basic/operators/operators_jumptable.s index 8f4983a1..96d35e83 100644 --- a/c64/basic/operators/operators_jumptable.s +++ b/c64/basic/operators/operators_jumptable.s @@ -9,38 +9,32 @@ .const operator_list = List().add( - // Tokens XXX + // Tokens $AA-$B0 - oper_add, - oper_sub, - oper_mul, - oper_div, + oper_add, // ID: $01 + oper_sub, // ID: $02 + oper_mul, // ID: $03 + oper_div, // ID: $04 + oper_pow, // ID: $05 + oper_and, // ID: $06 + oper_or, // ID: $07 - // Tokens XXX + // Tokens $B1-$B3 - oper_and, - oper_or, - - // Tokens XXX - - oper_cmp_gt, - oper_cmp_eq, - oper_cmp_lt, + oper_cmp_gt, // ID: $08 + oper_cmp_eq, // ID: $09 + oper_cmp_lt, // ID: $0A // Combined two tokens - oper_cmp_gteq, - oper_cmp_lteq, - oper_cmp_neq, + oper_cmp_gteq, // ID: $0B + oper_cmp_lteq, // ID: $0C + oper_cmp_neq, // ID: $0D - // Not a token + // Unary operators - oper_pow, - - // Unary - - oper_unary_minus, - oper_unary_not + oper_unary_minus, // ID: $0E + oper_unary_not // ID: $0F ) @@ -50,6 +44,7 @@ operator_priorities: // higher number = higher priority .byte $05 // oper_sub .byte $06 // oper_mul .byte $06 // oper_div + .byte $08 // oper_pow .byte $02 // oper_and .byte $01 // oper_or .byte $04 // oper_cmp_gt @@ -58,7 +53,6 @@ operator_priorities: // higher number = higher priority .byte $04 // oper_cmp_gteq .byte $04 // oper_cmp_lteq .byte $04 // oper_cmp_neq - .byte $08 // oper_pow .byte $07 // oper_unary_minus .byte $03 // oper_unary_not