1 //  Rexp --  read an expression.
  2 //  Last modified on 06/06/74 at 18:03:27 by R F Mabee.
  3 //  Prepared for installation as part of Version 3.4, R F Mabee.
  4 //  First installed as Version 2.7 by R F Mabee.
  5 
  6 //  Copyright (c) 1974 by Massachusetts Institute of Technology and Honeywell Information Systems, Inc.
  7 
  8 //  General permission is granted to copy and use this program, but not to sell it, provided that the above
  9 //  copyright statement is given.  Contact Information Processing Services, MIT, for further information.
 10 //  Please contact R F Mabee at MIT for information on this program and versions for other machines.
 11 
 12 get "bcpl_cae_head"
 13 
 14 let Rexp (n) = valof                    //  n is minimum precedence to be read.  It is zero except on recursive calls.
 15      $(   let A, B, C = nil, nil, nil
 16           let Op = Symb logor LineCount lshift Left
 17           A := valof switchon Symb into
 18                $(   default:  CaeReport (ExpressionMissing)
 19                               resultis ErrorNode
 20 
 21                     case NAME_S:
 22                     case NUMBER_S:
 23                     case CHARCONST_S:
 24                     case STRINGCONST_S:
 25                               B := DictionaryEntry
 26                               Nextsymb ()
 27                               resultis B
 28 
 29                     case NIL_S:
 30                     case TRUE_S:
 31                     case FALSE_S:
 32                               Nextsymb ()
 33                               resultis List1 (Op)
 34 
 35                     case PLUS_F:
 36                               Op := POS_F
 37                               goto Arith
 38                     case PLUS_S:
 39                               Op := POS_S
 40                               goto Arith
 41                     case MINUS_F:
 42                               Op := NEG_F
 43                               goto Arith
 44                     case MINUS_S:
 45                               Op := NEG_S
 46                       Arith:  Op := Op logor LineCount lshift Left
 47                               B := 32
 48                               goto Unary
 49                     case NOT_S:
 50                               B := 22
 51                               goto Unary
 52                     case LV_S:
 53                     case RV_S:
 54                               B := 40
 55                       Unary:  Nextsymb ()
 56                               B := Rexp (B)
 57                               resultis List2 (Op, B)
 58 
 59                     case VEC_S:
 60                               Nextsymb ()
 61                               B := Rexp (0)
 62                               resultis List2 (Op, B)
 63 
 64                     case LIST_S:
 65                     case TABLE_S:
 66                               Nextsymb ()
 67                               B := ReadList (true)
 68                               resultis List2 (Op, B)
 69 
 70                     case VALOF_S:
 71                               Nextsymb ()
 72                               B := Rcom (8)
 73                               resultis List2 (Op, B)
 74 
 75                     case RBRA_S:
 76                               Nextsymb ()
 77                               B := Rexp (0)
 78                               test Symb = RKET_S
 79                               then Nextsymb ()
 80                               or CaeReport (MissingRKET)
 81                               resultis B
 82                $)
 83 
 84   MORE:
 85           Op := Symb logor LineCount lshift Left
 86           B := valof switchon Symb into
 87                $(   default:  goto EXIT
 88 
 89                     case RBRA_S:
 90                               Op := FNAP_S logor LineCount lshift Left
 91                               Nextsymb ()
 92                               B := Symb = RKET_S -> 0, ReadList (true)
 93                               test Symb = RKET_S
 94                               then Nextsymb ()
 95                               or CaeReport (MissingRKET)
 96                               A := List3 (Op, A, B)
 97                               goto MORE
 98 
 99                     case VECAP_S:
100                               resultis 44
101 
102                     case SBRA_S:
103                               if n ge 44 goto EXIT
104                               Op := VECAP_S logor LineCount lshift Left
105                               Nextsymb ()
106                               B := Rexp (0)
107                               test Symb = SKET_S
108                               then Nextsymb ()
109                               or CaeReport (MissingSKET)
110                               A := List3 (Op, A, B)
111                               goto MORE
112 
113                     case MULT_S:
114                     case MULT_F:
115                     case DIV_S:
116                     case DIV_F:
117                     case REM_S:
118                               resultis 36
119 
120                     case PLUS_S:
121                     case PLUS_F:
122                     case MINUS_S:
123                     case MINUS_F:
124                               resultis 32
125 
126                     case VALDEF_S:
127                               Op := EQ_S logor LineCount lshift Left
128                     case EQ_S:
129                     case EQ_F:
130                     case NE_S:
131                     case NE_F:
132                     case LS_S:
133                     case LS_F:
134                     case LE_S:
135                     case LE_F:
136                     case GR_S:
137                     case GR_F:
138                     case GE_S:
139                     case GE_F:
140                               if n > 28 goto EXIT
141                               Nextsymb ()
142                               B := Rexp (28)
143                               A := List3 (Op, A, B)
144                               unless n = 28 do A := List2 (REL_S logor LineCount lshift Left, A)
145                               goto MORE
146 
147                     case LSHIFT_S:
148                     case RSHIFT_S:
149                               resultis 24
150 
151                     case LOGAND_S:
152                               resultis 20
153 
154                     case LOGOR_S:
155                               resultis 16
156 
157                     case EQV_S:
158                               resultis 14
159 
160                     case NEQV_S:
161                               resultis 12
162 
163                     case COND_S:
164                               if n > 8 goto EXIT
165                               Nextsymb ()
166                               B := Rexp (8)
167                               test Symb = COMMA_S
168                               then Nextsymb ()
169                               or CaeReport (MissingCOMMA)
170                               C := Rexp (8)
171                               A := List4 (Op, A, B, C)
172                               goto MORE
173 
174                     case CHAR_S:
175                     case BIT_S:
176                     case TYPE_S:
177                     case OFFSET_S:
178                     case LENGTH_S:
179                               resultis 6
180 
181                     case FIXED_S:
182                     case FLOAT_S:
183                     case DOUBLE_S:
184                     case POINTER_S:
185                     case STRING_S:
186                               if n ge 6 goto EXIT
187                               A := List2 (Op, A)
188                               Nextsymb ()
189                               goto MORE
190                $)
191           if n ge B goto EXIT
192           Nextsymb ()
193           B := Rexp (B)
194           A := List3 (Op, A, B)
195           goto MORE
196 
197   EXIT:
198           resultis A
199      $)