//    LEX1


GET "SYNHDR"

LET NEXTSYMB() BE
$(1   NLPENDING := FALSE

NEXT: IF PPTRACE DO WRCH(CH)

    SWITCHON CH INTO

    $( CASE '*P':
       CASE '*N': LINECOUNT := LINECOUNT + 1
                  NLPENDING := TRUE  // IGNORABLE CHARACTERS
       CASE '*T':
       CASE '*S': RCH() REPEATWHILE CH='*S'
                  GOTO NEXT

       CASE '0':CASE '1':CASE '2':CASE '3':CASE '4':
       CASE '5':CASE '6':CASE '7':CASE '8':CASE '9':
            SYMB := S.NUMBER
            READNUMBER(10)
            RETURN

       CASE 'A':CASE 'B':CASE 'C':CASE 'D':CASE 'E':
       CASE 'F':CASE 'G':CASE 'H':CASE 'I':CASE 'J':
       CASE 'K':CASE 'L':CASE 'M':CASE 'N':CASE 'O':
       CASE 'P':CASE 'Q':CASE 'R':CASE 'S':CASE 'T':
       CASE 'U':CASE 'V':CASE 'W':CASE 'X':CASE 'Y':
       CASE 'Z':
       CASE 'a':CASE 'b':CASE 'c':CASE 'd':CASE 'e':CASE 'f':
       CASE 'g':CASE 'h':CASE 'i':CASE 'j':CASE 'k':CASE 'l':
       CASE 'm':CASE 'n':CASE 'o':CASE 'p':CASE 'q':CASE 'r':
       CASE 's':CASE 't':CASE 'u':CASE 'v':CASE 'w':CASE 'x':
       CASE 'y':CASE 'z':
              RDTAG(CH)
              SYMB := LOOKUPWORD()
              IF SYMB=S.GET DO $( PERFORMGET(); GOTO NEXT  $)
              RETURN

       CASE '$': RCH()
                 UNLESS CH='(' LOGOR CH=')' DO CAEREPORT(91)
                 SYMB := CH='(' -> S.LSECT, S.RSECT
                 RDTAG('$')
                 LOOKUPWORD()
                 RETURN

       CASE '[':
       CASE '(': SYMB := S.LPAREN; GOTO L
       CASE ']':
       CASE ')': SYMB := S.RPAREN; GOTO L

       CASE '#': SYMB := S.NUMBER
                 RCH()
                 IF '0'<=CH<='7' DO $( READNUMBER(8); RETURN  $)
                 CH := UPPER(CH)                           // $$$$$
                 IF CH='B' DO $( RCH(); READNUMBER(2); RETURN  $)
                 IF CH='O' DO $( RCH(); READNUMBER(8); RETURN  $)
                 IF CH='X' DO $( RCH(); READNUMBER(16); RETURN  $)
                 CAEREPORT(33)

       CASE '?': SYMB := S.QUERY; GOTO L
       CASE '+': SYMB := S.PLUS; GOTO L
       CASE ',': SYMB := S.COMMA; GOTO L
       CASE ';': SYMB := S.SEMICOLON; GOTO L
       CASE '@': SYMB := S.LV; GOTO L
       CASE '&': SYMB := S.LOGAND; GOTO L
       CASE '=': SYMB := S.EQ; GOTO L
       CASE '!': SYMB := S.VECAP; GOTO L
       CASE '%': SYMB := S.BYTEAP; GOTO L
       CASE '**': SYMB := S.MULT; GOTO L

       CASE '/': RCH()
                 IF CH='\' DO $( SYMB := S.LOGAND; GOTO L $)
                 IF CH='/' GOTO COMMENT
                 UNLESS CH='**' DO $( SYMB := S.DIV; RETURN  $)

                 RCH()

                 UNTIL CH=ENDSTREAMCH DO TEST CH='**'

                       THEN $( RCH()
                               UNLESS CH='/' LOOP
                               RCH()
                               GOTO NEXT  $)

                       OR $( IF CH='*N' DO LINECOUNT := LINECOUNT+1
                             RCH()  $)

                 CAEREPORT(63)


       COMMENT: RCH() REPEATUNTIL CH='*N' LOGOR CH='*P' LOGOR CH=ENDSTREAMCH
                GOTO NEXT

       CASE '|': RCH()
                 IF CH='|' GOTO COMMENT
                 SYMB := S.LOGOR
                 RETURN

       CASE '~': RCH()
                 IF CH='=' DO $( SYMB := S.NE; GOTO L $)
                 SYMB := S.NOT
                 RETURN

       CASE '\': RCH()
                 IF CH='/' DO $( SYMB := S.LOGOR; GOTO L  $)
                 IF CH='=' DO $( SYMB := S.NE; GOTO L  $)
                 SYMB := S.NOT
                 RETURN

       CASE '<': RCH()
                 IF CH='=' DO $( SYMB := S.LE; GOTO L  $)
                 IF CH='<' DO $( SYMB := S.LSHIFT; GOTO L $)
                 SYMB := S.LS
                 RETURN

       CASE '>': RCH()
                 IF CH='=' DO $( SYMB := S.GE; GOTO L  $)
                 IF CH='>' DO $( SYMB := S.RSHIFT; GOTO L  $)
                 SYMB := S.GR
                 RETURN

       CASE '-': RCH()
                 IF CH='>' DO $( SYMB := S.COND; GOTO L  $)
                 SYMB := S.MINUS
                 RETURN

       CASE ':': RCH()
                 IF CH='=' DO $( SYMB := S.ASS; GOTO L  $)
                 SYMB := S.COLON
                 RETURN

        CASE '*'':CASE '*"':
             $(1 LET QUOTE = CH
                 CHARP := 0

              $( RCH()
                 IF CH=QUOTE LOGOR CHARP=255 DO
                        $( UNLESS CH=QUOTE DO CAEREPORT(95)
                           IF CHARP=1 & CH='*'' DO
                                   $( SYMB := S.NUMBER
                                      GOTO L  $)
                           CHARV!0 := CHARP
                           WORDSIZE := PACKSTRING(CHARV, WORDV)
                           SYMB := S.STRING
                           GOTO L   $)


                 IF CH='*N' DO LINECOUNT := LINECOUNT + 1

                 IF CH='**' DO
                        $( RCH()
                           IF CH='*N' DO
                               $( LINECOUNT := LINECOUNT+1
                                  RCH() REPEATWHILE CH='*S' LOGOR CH='*T'
                                  UNLESS CH='**' DO CAEREPORT(34)
                                  LOOP  $)
                           CH := UPPER(CH)                 // $$$$$
                           IF CH='T' DO CH := '*T'
                           IF CH='S' DO CH := '*S'
                           IF CH='N' DO CH := '*N'
                           IF CH='E' DO CH := #X27
                              // ABOVE GOES TO #X1B IN ASCII (ESC)
                           IF CH='B' DO CH := '*B'
                           IF CH='C' DO CH := '*C'
                           IF CH='P' DO CH := '*P'
                           IF CH='X' LOGOR '0'<=CH<='9' THEN
                           $( LET K, R, N = ?, 8, 3
                              IF CH='X' DO
                              $( R, N := 16, 2
                                 RCH()
                              $)
                              K := VALOCTALORHEX(R)
                              FOR I = 2 TO N DO
                              $( RCH()
                                 K := K*R + VALOCTALORHEX(R)
                              $)
                              IF K>255 DO CAEREPORT(33)
                              CH := K
                              GOTO NOTRAN // DO NOT TRANSLATE
                               // to get untranslated characters use
                               // *Xnn for hex or *nnn for octal
                            $)
                                                     $)

          DOTRAN: CH := CHARCODE(CH)
           NOTRAN:
                 DECVAL, CHARP := CH, CHARP+1
                 CHARV!CHARP := CH  $) REPEAT  $)1



       DEFAULT: IF CH=ENDSTREAMCH DO
       CASE '.':    $( IF GETP=0 DO
                             $( SYMB := S.END
                                RETURN   $)

                       ENDREAD()
                       GETP := GETP - 3
                       SOURCESTREAM := GETV!GETP
                       SELECTINPUT(SOURCESTREAM)
                       LINECOUNT := GETV!(GETP+1)
                       CH := GETV!(GETP+2)
                       GOTO NEXT  $)

                   CH := '*S'
                   CAEREPORT(94)
                   RCH()
                   GOTO NEXT

       L: RCH()   $)1

AND READNUMBER(RADIX) BE
    $( LET D = VALUE(CH)
       DECVAL := D
       IF D>=RADIX DO CAEREPORT(33)

       $( RCH()
          D := VALUE(CH)
          IF D>=RADIX RETURN
          DECVAL := RADIX*DECVAL + D  $) REPEAT
    $)


AND VALOCTALORHEX(RADIX) = VALOF
$( LET VALCH = VALUE(CH)
   IF VALCH>=RADIX THEN CAEREPORT(33)
   RESULTIS VALCH
$)


AND VALUE(CH) = '0'<=CH<='9' -> CH-'0',
                'A'<=CH<='F' -> CH-'A'+10,
                100

.