1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 get "head"
22 get "runoff_head"
23
24
25 let ReadNumber (b) = valof
26 $( let n = 0
27 while 0 le Rawchar!Nrx - '0' < b & Nrx < Nr do
28 $( n := n * b + Rawchar!Nrx - '0'
29 Nrx := Nrx + 1
30 $)
31 while Rawchar!Nrx = '*s' & Nrx < Nr do Nrx := Nrx + 1
32 resultis n
33 $)
34 and MakeN (v) = valof
35 $( let x = 0
36 for i = 1 to Length (v) do x := x lshift ByteBits logor Subch (v, i)
37 resultis x
38 $)
39
40 let ReadExp (n, v) = valof
41
42 $( if Nrx ge Nr do
43 $( ExpError := true
44 resultis 0
45 $)
46 let String = false
47 let A = valof switchon Rawchar!Nrx into
48 $( case '^': Skip ()
49 resultis ^ ReadExp (3, v)
50 case '-': Skip ()
51 resultis - ReadExp (5, v)
52 case '(': Skip ()
53 A := ReadExp (0, v)
54 test Rawchar!Nrx = ')'
55 then Skip ()
56 or ExpError := true
57 resultis A
58 case '0': case '1': case '2': case '3': case '4':
59 case '5': case '6': case '7': case '8': case '9':
60 resultis ReadNumber (10)
61 case '#': Skip ()
62 resultis ReadNumber (8)
63 case '"': String := true
64 ReadString (v)
65 resultis MakeN (v)
66
67 default: ExpError := true
68 resultis 0
69 $)
70
71 while Nrx < Nr do
72 $( let Op = Rawchar!Nrx
73 let NewNrx = Nrx
74 if Rawchar!(Nrx + 1) = '*b' do
75 $( Op := (Op lshift ByteBits logor '*b') lshift ByteBits logor Rawchar!(Nrx + 2)
76 NewNrx := NewNrx + 2
77 $)
78
79 let p = valof switchon Op into
80 $( case '=^H_':
81 case '|': resultis 2
82 case '&': resultis 3
83 case '=': case '<': case '>':
84 case '/^H=': case '<^H_': case '>^H_':
85 resultis 4
86 case '+': case '-':
87 resultis 5
88 case '**': case '/': case '\':
89 resultis 6
90 case '#': unless String break
91 A := Length (v)
92 Nrx := NewNrx
93 Skip ()
94 String := false
95 loop
96 default: break // Not a known operator, end of expression.
97 $)
98 if p le n break // Operator less binding, return.
99
100 Nrx := NewNrx
101 Skip () // Over operator.
102 let B = 0
103 test String & Rawchar!Nrx = '"' & p = 4 // Check for string comparison.
104 then $( let w = vec Maxline
105 ReadString (w)
106 A := CompareStrings (v, w)
107 $)
108 or B := ReadExp (p, v)
109 String := false
110
111 A := valof switchon Op into // Apply the operator.
112 $( case '|': resultis A | B
113 case '=^H_': resultis A eqv B
114 case '&': resultis A & B
115 case '=': resultis A = B
116 case '<': resultis A < B
117 case '>': resultis A > B
118 case '/^H=': resultis A ne B
119 case '<^H_': resultis A le B
120 case '>^H_': resultis A ge B
121 case '+': resultis A + B
122 case '-': resultis A - B
123 case '**':resultis A * B
124 case '/': resultis B = 0 -> 0, A / B
125 case '\': resultis B = 0 -> 0, A rem B
126 $)
127 $) // Repeat until done.
128
129 resultis A
130 $)
131 and Skip () be // Skip over current character and following blank space.
132 Nrx := Nrx + 1 repeatwhile Rawchar!Nrx = '*s' & Nrx < Nr
133 and ReadParam (P) = valof // Read parameter where leading + or - means add or subtract from current value.
134 $( ExpError := false
135 let v = vec Maxline
136
137 test Rawchar!Nrx = '+' // Adding.
138 then $( Skip ()
139 P := P + ReadExp (4, v)
140 $)
141 or test Rawchar!Nrx = '-' // Subtracting.
142 then $( Skip ()
143 P := P - ReadExp (4, v)
144 $)
145 or P := ReadExp (0, v) // Or just setting.
146 if ExpError | Nrx < Nr do Report ("Malformed expression")
147 resultis P
148 $)
149 and ReadString (w) be // Read string expression into vector.
150 $( let i, v = 0, vec Maxline
151 $( Nrx := Nrx + 1
152 let c = Rawchar!Nrx
153 test c = '**' // Escape convention.
154 then $( Nrx := Nrx + 1
155 c := valof switchon Rawchar!Nrx into
156 $( case 'n': resultis '*n'
157 case 't': resultis '*t'
158 case 's': resultis '*s'
159 case 'b': resultis '*b'
160 case 'c': c := 0
161 for i = 1 to 3 do
162 $( unless '0' le Rawchar!(Nrx + 1) le '9' break
163 Nrx := Nrx + 1
164 c := c * 10 + Rawchar!Nrx - '0'
165 $)
166 resultis c & $8177
167 default: resultis Rawchar!Nrx
168 $)
169 $)
170 or if c = '"' do // End of string.
171 $( Skip ()
172 while Nrx < Nr & Rawchar!Nrx = '(' do i := SubscriptString (v, i)
173 if Nrx < Nr & Rawchar!Nrx = '"' loop
174 break
175 $)
176 i := i + 1
177 v!i := c
178 $) repeatwhile Nrx < Nr // Gather characters of string until end of line.
179
180 v!0 := i
181 Packstring (v, w)
182 $)
183 and GetString () = valof // Read string and store in new vector.
184 $( let v = vec Maxline
185 ExpError := false
186 ReadString (v)
187 if ExpError | Nrx < Nr do Report ("Malformed string expression")
188 resultis StoreString (v)
189 $)
190 and SubscriptString (v, i) = valof // Take substring, read subscript expression.
191 $( Skip ()
192 let w = vec Maxline
193 let a = MinI (ReadExp (4, w), i + 1) // Character index for beginning of substring.
194 if a < 0 do a := a + i + 1 // Negative first indicates offset from end.
195 if a le 0 do a := 1
196 let b = i - a + 1
197 if Rawchar!Nrx = ',' do
198 $( Skip () // Second operand, length of substring.
199 b := MinI (ReadExp (4, w), b)
200 if b < 0 do b := MaxI (b + i - a + 2, 0)
201 $)
202 if Rawchar!Nrx ne ')' do
203 $( ExpError := true
204 resultis i
205 $)
206 for i = 1 to b do v!i := v!(a + i - 1) // Take the indicated substring.
207 Skip ()
208 resultis b
209 $)