/media/sda-magnetic/david/Dok-15-2023-11-27/informatik/eepromatmega20240110/bool02.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>

.macro              ypush
                    st      -Y, @0
.endmacro

.macro              ypop
                    ld      @0, Y+
.endmacro

.dseg

YStapel:            .byte 128
YStpAnf:



.cseg
    .org 0x00
    rjmp main
    main:

    ldi R16, HIGH(RAMEND)
    out SPH, R16
    ldi R16, LOW(RAMEND)
    out SPL, R16

    ldi     r29, HIGH(YStpAnf)
    ldi     r28, LOW(YStpAnf)
    ldi     ZH, HIGH(boolstr*2)
    ldi     ZL, LOW(boolstr*2)

    ldi     r16, 1
    mov     r3, r16
    ldi     r16, 1
    mov     r4, r16
    ldi     r16, 0
    mov     r5, r16

    rcall expr


    ldi     r16, 0xff
    out     DDRB, r16

    ypop    r16
    com     r16
    out     PORTB, r16

    end: rjmp end



expr:
    rcall term
    lpm r16, Z+
    cpi r16, '&'
    brne expr2
    rcall expr
    rjmp expr1

    expr2:
    dec ZH:ZL
    rjmp expr3

    expr1:
    ypop r0
    ypop r1
    and r0, r1
    ypush r0

    expr3:
    ret

term:
    rcall fact
    lpm r16, Z+
    cpi r16, '|'
    brne term2
    rcall term
    rjmp term1

    term2:
    dec ZH:ZL
    rjmp term3

    term1:
    ypop r0
    ypop r1
    or r0, r1
    ypush r0

    term3:
    ret

fact:
    lpm r16, Z+
    cpi r16, '('
    brne fact_a
    rcall expr
    lpm r16, Z+
    cpi r16, ')'
    brne error1
    rjmp fact_end

    fact_a:
    cpi r16, 'a'
    brne fact_b
    ypush r3
    rjmp fact_end

    fact_b:
    cpi r16, 'b'
    brne fact_c
    ypush r4
    rjmp fact_end

    fact_c:
    cpi r16, 'c'
    brne fact_not
    ypush r5
    rjmp fact_end

    fact_not:
    cpi r16, '!'
    brne fact_end2
    rcall expr
    ypop r0
    com r0
    ypush r0

    fact_end:

    ret

    fact_end2:
    dec ZH:ZL
    ret


    error1:

    ldi r16, 0x01
    ypush    r16
    ret
text:
    boolstr:        .db      "!!(b&!a|(c&!a))&!c", 0