/media/sda-magnetic/david/Dok-15-2023-11-27/informatik/eepromatmega20240110/bool01.asm


.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