        $MACRO all VAR
        JSR PC,$$RES
        RES.STR #@{1} @#$$RES1
        $ENDM
;
        $MACRO fre
        MOV (SP),R0
        ADD R0,SP
        $ENDM
        $MACRO RES.STR ;  NAME,SIZE
        SUB #@2,SP
        SUB #10.,SP
        MOV #1,-(SP)
        MOV #@2,-(SP)
        ADD #8.,(SP)
        MOV SP,#@1
        MOV #@1,-(SP)
        JSR PC,INI
        ADD #6.,(SP)
        JSR PC,$$$STK
        $ENDM
/
        .psect let2
        PROGRAM let2


x1c:    .ascii /:/
x1b:    .ascii /%/
x1a:    .ascii /#/
x1:     .asciz 'CL@ #@=1(2:Z) <#@2> <#@*(3_Z)>'
x2:     .asciz 'CL% <#@*(1"Z)>'
;y1:     .asciz 'm%ov r1,#@{2}'
y1:     .asciz 'CL@1 <#@2>'
y2:     .asciz '	mov #@{2},r1'
z1:     .asciz '	add ##@1,r1'
z2:     .asciz '	add #@1(r5),r1'
z3:     .asciz '	add r5,r1'
z4:     .asciz '	mov (r1),r0'
z5:     .asciz '	movb (r1),r0'
z6:     .asciz '	mov #@1(r1),r0'
z7:     .asciz '	movb #@1(r1),r0'
c1:     .asciz '	add ##@1,r1'
c2:     .asciz '	mov r1,r0'
b1:     .asciz 'LET #@#0.(r5) = #@*(1"N)'
b2:     .asciz 'LET #@#0.(r5) = <#@*(1"N)>'
b3:     .asciz '	mov #@#0.(r5),r1'

a1:     .ascii '	add #'
a2:     .asciz '000,sp'
        .even

        dot='.
        cross='#
        percent='%
colon=':



;-
; more array and function stuff
; still only recognition stuff here
;
;+
        AUTO pm lab1 n1 t1 s1

FUNCTION clx[s,t,n,lab]
;. exstat["yy-xx <#@*(1_<42>_Z)>",&s,#0]
;        . exstat["yy-clx <#@*(1_<42>_Z)>",&s,#0]
        IF lab LT #0
            mov #2,pm(r5)
        ELSE
            mov #1,pm(r5)
        FI

        LET r4 = fndstr[t,<pm + #1>]              ;address of 1st parm


        IFB (r4) NE #0 AND 1(r4) = #dot           ; if its an array
            LET r3 = #clx1                        ; yes
            LET r2 = #x1
        ELSEIFB (r4) NE #0 AND 1(r4) = #cross     ; if its structure member
            LET r3 = #clx1
            LET r2 = #x1a
        ELSEIFB (r4) NE #0 AND 1(r4) = #percent   ; if its address of array
            LET r3 = #clx1                        ; element.
            LET r2 = #x1b
        ELSEIFB (r4) NE #0 AND 1(r4) = #colon     ; if its address of s
            LET r3 = #clx1                        ; structure member
            LET r2 = #x1c
        ELSE
            LET r3 = #clx2                        ; otherwise its a function
            LET r2 = #x2
        FI
        . exjsr[r3,r2,&s]
        RET



        AUTO np,cent
FUNCTION clx1[s,t,n,lab]                          ;arrays and structures
;        . exstat["yy-clx1 <#@*(1_<42>_Z)>",&s,#0]
        LET R0 = fndstr[t,#4]
        clr np(r5)
        movb (r0),np(r5)
        all r4
        LET r2 = ifrec1[fndstr[t,#3]]
        IF r2 = #1
            . exjsr[#clx1a,#y1,&s]      ;evaluate complicated subsc array
        ELSE
            . exstat[#y2,&s,r4]         ;same but its not
        FI                              ;an expression

        LET r3 = fndstr[t,#1]
        let cent = #0
        ifb 1(r3) = #percent or 1(r3) = #colon   ;set flag if address of fuop
            inc cent(r5)
        fi
        IFB 1(r3) NE #cross and 1(r3) ne #colon  ;only subscripts of
            IF np =  #0                          ;integer arrays require
                				;mult by 2 of subscript
                . strng[r4,"	asl r1"]
                . outst[r4]
            FI
        FI

        . mvstr[r4,t,#2]
        clr r3
        IF @#..nsym GT #0                        ;look up the symbol
            LET r0 = fndstr[r4,#1]               ;so we can determine
            IFB (r0) = #0                        ;what type of array we got
                clr r0
            FI
            LET r3 = ifnstr[@#..nsym,#..symbols,r0]
            IF r3 NE #0
                LET r2 = #..types + r3 + r3 - #2
                mov (r2),r3                      ;type code
if r3 = 3 or r3 gt 10 ;if its global, or register
clr r3	;then treat same
fi
            FI
        FI
        SELECT case r3 of                        ;select type of data
        CASE #0                                  ;global data
            if cent = #0                         ;not auto or function
                if np = #0                       ;check if byte offset
                    mov #z6,r0                   ;no
                else
                    mov #z7,r0                   ;yes
                fi
            else
                mov #c1,r0                       ;its global
            fi
            break
        CASE #1                                  ;auto variable
            mov #z1,r0
            BREAK
        CASE #2                                  ;function parm
            mov #z2,r0
        ESAC
        . exstat[r0,&s,r4]
        IF r3 = #1                               ;was it in symbol table
            . exstat[#z3,&s,r4]
        FI
        if cent = #0                             ;was it addr of operation
            if r3 ne #0                          ;and in symbol table
                IF np = #0
                    mov #z4,r0                   ;word operation
                ELSE
                    mov #z5,r0                   ;byte operation
                FI

                . exstat[r0,&s,r4]
            fi
        else
            . exstat[#c2,&s,r4]
        fi
        fre
        RET

FUNCTION clx1a[s,t,n,l]
;        . exstat["yy-clx1a <#@*(1_<42>_Z)>",&s,#0]
        sub #2,num$                           ;number 1 is temp counter
        IF num$ LT num$+2
            mov num$,num$+2                   ;number 2 is minimum (max temps)
        FI
        LET r4 =  exjsr[#clx1b,"cl@1a #@1",&s]   ;evaluate subscript expression
        IF r4 = #1
            . exstat[#b1,&s,#0]                  ;expression
        ELSE
            . exstat[#b2,&s,#0]                  ;function call
        FI
        . exstat[#b3,&s,#0]                      ;result into r1
        add #2,num$
        RET

FUNCTION clx1b[s,t,n,l]                          ;check for expressions
;        . exstat["yy-clx1b <#@*(1_<42>_Z)>",&s,#0]
        RET isexp[t,#3]



        AUTO count lab1 n1 t1 s1

FUNCTION clx2[s,t,n,lab]    ;functions
;        . exstat["yy-clx2 <#@*(1_<42>_Z)>",&s,#0]
        LET count = n - #2
        all t1
        all s1
        LET n1 = #2
        clr lab1(r5)
        . instr[t1,#20.]
        LOOP for r3 = n DOWNTO #3 STEP #-1
            . copy[t1,#2,t,r3]
            LET n1 = #2
            . expand["P%SH #@1",s1,&s1]          ;push args onto runtime stk
            LET n1 = toks[s1,t1]
            . pshx[s1,t1,n1,lab1]
        NEXT r3
        . exstat["      jsr pc,#@1",&s,s1]       ;call the routine
        LET r0 = count  + count
        mov r0,r2
        SELECT case r2 of                        ;pop off args
        CASE #2
            . exstat["  tst (sp)+",&s,s1]        ;1 arg = short form add 2,sp
            BREAK
        CASE #4
            . exstat["  cmp (sp)+,(sp)+",&s,s1]  ;2 arg = short form add 4,sp
            BREAK
        DEFAULT
            mov r0,r1                            ;otherwise we have to
            call rs1                             ;do an actual add
            movb r1,a2+2                         ;to sp

            mov r0,r1                            ;this stuffs the
            call rs                              ;template at a1:
            call rs1
            movb r1,a2+1

            mov r0,r1
            call rs
            call rs
            call rs1
            movb r1,a2

            . exstat[#a1,&s,s1]                  ;output the add
            fre
        ESAC
        fre

        RET

;-
; exjsr - expand str ("string") into s (smp)
; and then call pfun as @pfun[s,t,n,l]
; s,t,n,l have usual meaning of string,toked-string,num-tokes,label-boolean
;+
        AUTO ll nn tt ss
FUNCTION exjsr[pfun,str,s]
        all ss
        all tt
        . instr[tt,#20.]
        . expand[str,ss,s]
        LET nn = toks[ss,tt]
        clr ll(r5)
        LET r4 = @pfun(r5)[ss,tt,nn,ll]
        fre
        fre
        RET r4



rs:
        asr r1
        asr r1
        asr r1
        rts pc
rs1:
        bic #177770,r1
        add #'0,r1
        rts pc
        .end
