        $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 let3
        PROGRAM LET3
        optimize with r2
        SETLAB LT



a1:     .asciz 'M%-OV <#@*(1"Z)>'
a2:     .asciz 'I%ERR <#@*(1_Z) invalid as a function arg>'
b1:     .asciz 'LET #@#0.(r5) = <#@*(1"Z)>'
b2:     .asciz '	MOV #@1,-(SP)'
b3:     .asciz 'LET #@#0.(r5) = <<#@*(1"Z)>>'
b4:     .asciz '	MOV #@#0.(r5),-(SP)'
        .even
;-
; push function arguments onto stack (runtime stack)
;
;
;+
        AUTO lab1 n1 t1 s1 flag
FUNCTION pshx[s,t,n,lab]
        LET r4 = fndstr[t,#2]
        clr flag(r5)
        IFB (r4) NE #0  AND  1(r4) = #unop3
            inc flag(r5)
        FI

        all s1
        all t1
        . instr[t1,#20.]
        . expand["<#@{1}>",s1,&s]
        mov #-1,xx.switch+6
        LET n1 = toks[s1,t1]
        clr xx.switch+6
        . copy[t,#2,t1,#1]
        IF flag = #1 AND n GT #2
            . exstat[#a2,&s,s1]
        ELSE
            IF flag = #0
                . expand[#a1,s1,&s]
                clr lab1(r5)
                LET n1 = toks[s1,t1]
                . movx[s1,t1,n1,lab1]
            FI
        FI
        fre
        fre
        RET



        AUTO s1
FUNCTION movx[s,t,n,lab]
        LET r4 = fndstr[t,#3]
        all s1
        IFB (r4) = #0
            . exstat[#b2,&s,s1]
        ELSE
            sub #2,num$	;number 1 is temp counter
            IF num$ LT num$+2
                mov num$,num$+2  ;number 2 is minimum (max temps)
            FI
            SELECT char 1(r4) of
            CASEB #'+ OR
            CASEB #'- OR
            CASEB #'* OR
            CASEB #'/
                . exstat[#b1,&s,s1]
                . exstat[#b4,&s,s1]
                BREAK
            DEFAULT
                . exstat[#b3,&s,s1]
                . exstat[#b4,&s,s1]
            ESAC
            add #2,num$
        FI
        fre
        RET

;-
; test if an argument is recursive, i.e. if it is <...> type of thing
; with multiple nested arguments. note: a[b] is <a,b>
;
;+
FUNCTION ifrec[s,t,n,l]
        LET r4 = ifrec1[fndstr[t,#2]]
        IF r4 NE #0   ;tru = recursive
            LET r3 = fndstr[t,#3]
            IFB (r3) NE #0
                . exstate["#@2",&s,#0]
            FI
        ELSE
            IF n GT #3
                . exstate["#@3",&s,#0]
            FI
        FI
        RET


        .end
