.include "m88def.inc"
; r3 ^= a
; r4 ^= b
; r5 ^= c
; <expr> ::= <term> 'or' <expr> | <term>
; <term> ::= <fact> 'and' <term> | <fact>
; <fact> ::= '('<expr>')' | <id> | 'not' '('<expr>')' | 'not' <id>
.cseg
boolstr: .db "(!a&!b)|(a&b)"
ldi r26, LOW(boolstr)
ldi r27, HIGH(boolstr)
ldi r16, 0
mov r3, r16
mov r4, r16
mov r5, r16
rcall expr
pop r0
ldi r16, 0xff
out DDRB, r16
pop r16
com r16
out PORTB, r16
end: rjmp end
expr:
rcall term
ld r16, X+
cpi r16, '&'
brne expr2
rcall expr
rjmp expr1
expr2:
dec r27:r26
rjmp expr3
expr1:
pop r0
pop r1
and r0, r1
push r0
expr3:
ret
term:
rcall fact
ld r16, X+
cpi r16, '|'
brne term2
rcall term
rjmp term1
term2:
dec r27:r26
rjmp term3
term1:
pop r0
pop r1
or r0, r1
push r0
term3:
ret
fact:
ld r16, X+
cpi r16, '('
brne fact_a
rcall expr
ld r16, X+
cpi r16, ')'
breq error1
rjmp fact_end
fact_a:
cpi r16, 'a'
brne fact_b
push r3
rjmp fact_end
fact_b:
cpi r16, 'b'
brne fact_c
push r4
rjmp fact_end
fact_c:
cpi r16, 'c'
brne fact_not
push r5
rjmp fact_end
fact_not:
cpi r16, '!'
brne error1
rcall expr
pop r0
com r0
push r0
fact_end:
ret
error1:
ldi r16, 1
push r16
ret