integrated operator recognition routine
This commit is contained in:
1 parent
1b26151a3f
commit
831bc8f453
3 files changed
+131
-44
No files matched your search
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in new issue
Block a user