//    CAE2


GET "SYNHDR"
LET RBEXP() = VALOF
  $(1   LET A, OP = 0, SYMB

        SWITCHON SYMB INTO

    $(  DEFAULT:
            CAEREPORT(32)

        CASE S.QUERY:
            NEXTSYMB(); RESULTIS LIST1(S.QUERY)

        CASE S.TRUE:
        CASE S.FALSE:
        CASE S.NAME:
            A := WORDNODE
            NEXTSYMB()
            RESULTIS A

        CASE S.STRING:
            A := NEWVEC(WORDSIZE+1)
            A!0 := S.STRING
            FOR I = 0 TO WORDSIZE DO A!(I+1) := WORDV!I
            NEXTSYMB()
            RESULTIS A

        CASE S.NUMBER:
            A := LIST2(S.NUMBER, DECVAL)
            NEXTSYMB()
            RESULTIS A

        CASE S.LPAREN:
            NEXTSYMB()
            A := REXP(0)
            CHECKFOR(S.RPAREN, 15)
            RESULTIS A

        CASE S.VALOF:
            NEXTSYMB()
            RESULTIS LIST2(S.VALOF, RCOM())

        CASE S.VECAP: OP := S.RV
        CASE S.LV:
        CASE S.RV: NEXTSYMB(); RESULTIS LIST2(OP, REXP(35))

        CASE S.PLUS: NEXTSYMB(); RESULTIS REXP(34)

        CASE S.MINUS: NEXTSYMB()
                      A := REXP(34)
                      TEST H1!A=S.NUMBER
                          THEN H2!A := - H2!A
                            OR A := LIST2(S.NEG, A)
                      RESULTIS A

        CASE S.NOT: NEXTSYMB(); RESULTIS LIST2(S.NOT, REXP(24))

        CASE S.ABS: NEXTSYMB(); RESULTIS LIST2(S.ABS, REXP(35))

        CASE S.TABLE: NEXTSYMB()
                      RESULTIS LIST2(S.TABLE, REXPLIST())   $)1



AND REXP(N) = VALOF
    $(1 LET A = RBEXP()

        LET B, C, P, Q = 0, 0, 0, 0

  L: $( LET OP = SYMB

        IF NLPENDING RESULTIS A

        SWITCHON OP INTO
    $(B DEFAULT: RESULTIS A

        CASE S.LPAREN: NEXTSYMB()
                       B := 0
                       UNLESS SYMB=S.RPAREN DO B := REXPLIST()
                       CHECKFOR(S.RPAREN, 19)
                       A := LIST3(S.FNAP, A, B)
                       GOTO L

        CASE S.VECAP: P := 40; GOTO LASSOC

        CASE S.BYTEAP: P := 36; GOTO LASSOC

        CASE S.REM:CASE S.MULT:CASE S.DIV: P := 35; GOTO LASSOC

        CASE S.PLUS:CASE S.MINUS: P := 34; GOTO LASSOC

        CASE S.EQ:CASE S.NE:
        CASE S.LE:CASE S.GE:
        CASE S.LS:CASE S.GR:
                IF N>=30 RESULTIS A

            $(R NEXTSYMB()
                B := REXP(30)
                A := LIST3(OP, A, B)
                TEST C=0 THEN C :=  A
                           OR C := LIST3(S.LOGAND, C, A)
                A, OP := B, SYMB  $)R REPEATWHILE S.EQ<=OP<=S.GE

                A := C
                GOTO L

        CASE S.LSHIFT:CASE S.RSHIFT: P, Q := 25, 30; GOTO DIADIC

        CASE S.LOGAND: P := 23; GOTO LASSOC

        CASE S.LOGOR: P := 22; GOTO LASSOC

        CASE S.EQV:CASE S.NEQV: P := 21; GOTO LASSOC

        CASE S.COND:
                IF N>=13 RESULTIS A
                NEXTSYMB()
                B := REXP(0)
                CHECKFOR(S.COMMA, 30)
                A := LIST4(S.COND, A, B, REXP(0))
                GOTO L

        LASSOC: Q := P

        DIADIC: IF N>=P RESULTIS A
                NEXTSYMB()
                A := LIST3(OP, A, REXP(Q))
                GOTO L                     $)B     $)1

LET REXPLIST() = VALOF
    $(1 LET A = 0
        LET PTR = @A

     $( LET B = REXP(0)
        UNLESS SYMB=S.COMMA DO $( !PTR := B
                                  RESULTIS A  $)
        NEXTSYMB()
        !PTR := LIST3(S.COMMA, B, 0)
        PTR := @H3!(!PTR)  $) REPEAT
    $)1

LET RDEF() = VALOF
    $(1 LET N = RNAMELIST()

        SWITCHON SYMB INTO

     $( CASE S.LPAREN:
             $( LET A = 0
                NEXTSYMB()
                UNLESS H1!N=S.NAME DO CAEREPORT(40)
                IF SYMB=S.NAME DO A := RNAMELIST()
                CHECKFOR(S.RPAREN, 41)

                IF SYMB=S.BE DO
                     $( NEXTSYMB()
                        RESULTIS LIST5(S.RTDEF, N, A, RCOM(), 0)  $)

                IF SYMB=S.EQ DO
                     $( NEXTSYMB()
                        RESULTIS LIST5(S.FNDEF, N, A, REXP(0), 0)  $)

                CAEREPORT(42)  $)

        DEFAULT: CAEREPORT(44)

        CASE S.EQ:
                NEXTSYMB()
                IF SYMB=S.VEC DO
                     $( NEXTSYMB()
                        UNLESS H1!N=S.NAME DO CAEREPORT(43)
                        RESULTIS LIST3(S.VECDEF, N, REXP(0))  $)
                RESULTIS LIST3(S.VALDEF, N, REXPLIST())  $)1

.