4 ; Table drive expression evaluator for TermScript
9 ;----- Standard Header ------------------------------------------------------
16 ;----- External dependencies ------------------------------------------------
18 ;----- Main code ------------------------------------------------------------
20 AREA |Termscript$$Code|,CODE,READONLY
24 ; On entry: R7, R8, R9 == lookahead token
25 ; R10 == pointer into tokenised buffer
26 ; R11 == evaluation stack pointer
27 ; R12 == anchor pointer
29 ; On exit: R7, R8, R9 == lookahead token
30 ; R0, R1 == result of expression
31 ; R10 == moved on to first char after expression
33 ; Use: Reads an expression for the current point in the tokenised
34 ; file, and returns it's result. The implementation is
35 ; table driven and should be very fast.
40 10val_readExp BL val__operand
44 ; --- Now work out the result ---
46 BL val__copyRest ;Copy rest of tokens over
51 ; --- val__operand ---
53 ; On entry: R7, R8, R9 == lookahead token
54 ; R10 == pointer into tokenised buffer
55 ; R11 == evaluation stack pointer
56 ; R12 == anchor pointer
58 ; On exit: R0 corrupted
59 ; R7, R8, R9 == lookahead token
60 ; R10 modified appropriately
61 ; CS if operand found,
64 ; Use: Reads an operand from the input, and does appropriate
65 ; stack like things with it.
69 STMFD R13!,{R14} ;Stack registers
70 00val__operand CMP R9,#'&' ;Start a hex number?
71 BEQ %10val__operand ;Yes -- jump ahead
72 CMP R9,#'%' ;Start of a binary number?
73 BEQ %20val__operand ;Yes -- jump ahead
74 CMP R9,#'!' ;An indirection operand?
77 BEQ %40val__operand ;Yes -- jump ahead
78 CMP R9,#'+' ;Unary operator then?
80 BEQ %50val__operand ;Yes -- jump ahead
81 CMPNE R9,#'(' ;A nice bracket?
82 BEQ %60val__operand ;Yes -- jump ahead
83 SUB R14,R9,#'0' ;Set up for a range check
84 CMP R14,#10 ;Is it a digit?
85 MOVCC R0,#0 ;Yes -- set up accumulator
86 BCC %30val__operand ;Yes -- deal with that
87 B %70val__operand ;Assume it's an identifier
89 ; --- Read a hex number ---
91 10val__operand BL getToken ;Get another token
92 MOV R0,#0 ;The number so far
93 SUB R14,R9,#'A' ;Check if it's a letter
94 CMP R14,#6 ;But only A-F
95 ADDCC R14,R14,#10 ;If so, add 10 on
96 SUBCS R14,R9,#'0' ;Otherwise check for digit
97 CMPCS R14,#10 ;Make sure it's OK
98 BCC %12val__operand ;And jump head
99 MOV R0,#err_badHex ;Point to error message
100 B error_report ;And return the error
102 11val__operand SUB R14,R9,#'A' ;Check if it's a letter
103 CMP R14,#6 ;But only A-F
104 ADDCC R14,R14,#10 ;If so, add 10 on
105 SUBCS R14,R9,#'0' ;Otherwise check for digit
106 CMPCS R14,#10 ;Make sure it's OK
107 BCS %35val__readSimple ;No -- that's it then
109 12val__operand ADD R0,R14,R0,LSL #4 ;Multiply by 16 and add digit
110 BL getToken ;Load a character
111 B %11val__readSimple ;Keep on reading more
113 ; --- Read a binary number ---
115 20val__operand BL getToken ;Get another token
116 MOV R0,#0 ;The number so far
117 SUB R14,R9,#'0' ;Set up for a range check
118 CMP R14,#1 ;Is it a digit
119 BLS %22val__readSimple ;Yes -- jump ahead
120 MOV R0,#err_badBinary ;Point to error message
121 B error_report ;And return the error
123 21val__operand SUB R14,R9,#'0' ;Set up for a range check
124 CMP R14,#1 ;Is it a digit
125 BHI %35val__readSimple ;Nope -- jump ahead then
127 22val__operand ADC R0,R0,R0 ;Multiply by 2
128 BL getToken ;Load a character
129 B %21val__readSimple ;Keep on reading more
131 ; --- Read a decimal number ---
133 30val__operand SUB R14,R9,#'0' ;Set up for a range check
134 CMP R14,#10 ;Is it a digit
135 BCS %35val__readSimple ;Nope -- jump ahead then
137 32val__operand ADD R0,R0,R0,LSL #2 ;Multiply by 5
138 ADD R0,R14,R0,LSL #1 ;And then by 2 (* 10)
139 BL getToken ;Load the next token
140 B %30val__readSimple ;Keep on reading more
142 ; --- Finished reading a number ---
144 35val__operand BL val__stackNumber ;Put a number on the stack
145 B %90val__operand ;Jump ahead
147 ; --- Read an indirection operator ---
149 40val__operand MOV R0,#0 ;Get the offset ready
150 BL val__stackNumber ;Put it on the stack
151 BL val__stackToken ;And put operator on too
152 BL getToken ;Get the next token
153 B %00val__operand ;Need another operand
155 ; --- Deal with unary signs ---
157 50val__operand CMP R9,#'-' ;Is is a unary minus
158 BLEQ val__stackToken ;Yes -- put it on the stack
159 BL getToken ;Get another token
160 B %00val__operand ;Need another operand
162 ; --- We have just read a '(' ---
164 60val__operand BL val__stackToken ;Stackit immediately
165 BL getToken ;Get another token
166 B %00val__operand ;Need another operand
168 ; --- Assume it's an identifier then ---
170 70val__operand ADR R1,sail_misc ;Point to a nice block
171 MOV R0,#vType_integer ;The current variable type
173 75val__operand SUBS R14,R9,#'_' ;Is it an underscore?
174 SUBNE R14,R9,#'0' ;Or a number?
176 SUBCS R14,R9,#'A' ;Or a capital letter?
178 SUBCS R14,R9,#'a' ;Or a lowercase letter?
180 STRCCB R9,[R1],#1 ;Yes -- store it away
181 BLCC getToken ;Read the next byte
182 BCS %95val_readLvalue ;Ouch -- not an identifier
184 CMP R9,#'$' ;Is it a dollar sign?
185 MOVEQ R0,#vType_string ;It's a string now
186 CMPNE R9,#'%' ;Or a percentage?
187 STREQB R9,[R2],#1 ;Yes -- store it then
188 CMPNE R9,#' ' ;Just check for a space
190 BNE %75val_readLvalue ;Go round for more
192 MOV R14,#0 ;The terminator
193 STRB R14,[R1],#0 ;Store that in the var name
194 BL getToken ;Read the next token ready
196 ; --- The identifier name is in the buffer ---
198 ADR R1,sail_misc ;Point to the name
199 BL var_find ;Try to find the variable
200 MOVCC R0,#err_unknown ;Not there, get the error
201 BCC error_report ;And report a possible error
203 LDR R1,[R0,#0] ;Load out the variable type
204 LDR R0,[R0,#4] ;Load out the value
205 CMP R1,#vType_integer ;Is it an integer?
206 BLEQ val__stackInteger ;Yes -- stack it
207 BLNE val__stackString ;No -- it's a string then
209 90val__operand LDMFD R13!,{R14} ;Load back registers
210 ORRS PC,R14,#C_flag ;We found an operand
212 95val__operand LDMFD R13!,{R14} ;Load back registers
213 BICS PC,R14,#C_flag ;No operand was found
217 ; --- val__operator ---
219 ; On entry: R7, R8, R9 == lookahead token
220 ; R10 == pointer into tokenised buffer
221 ; R11 == evaluation stack pointer
222 ; R12 == anchor pointer
224 ; On exit: R7, R8, R9 == lookahead token
225 ; R10 modified appropriately
226 ; CS if operator found,
229 ; Use: Reads an operator from the input, and does appropriate
230 ; stack like things with it.
234 val__operator STMFD R13!,{R14} ;Stack registers
235 00val__operator CMP R9,#')' ;Is it a close bracket?
236 BEQ %10val__operator ;Yes -- jump ahead
237 ; --- Make sure we recognise it ---
239 CMP R9,#'!' ;An indirection operator?
241 CMPNE R7,#tClass__andOp
242 CMPNE R7,#tClass__orOp
243 CMPNE R7,#tClass__addOp
244 CMPNE R7,#tClass__multOp
245 CMPNE R7,#tClass__relOp
246 BNE %95val__operator ;Nope -- just return
247 BL val__stackToken ;Stack this token
248 BL getToken ;Get another one
249 B %90val__operator ;And return success
251 ; --- We have read a ')' ---
253 BL val__stackToken ;Stack this token
254 BL getToken ;Get another one
255 B %00val__operator ;We expect another operator
257 90val__operator LDMFD R13!,{R14} ;Load back registers
258 ORRS PC,R14,#C_flag ;We found an operand
260 95val__operator LDMFD R13!,{R14} ;Load back registers
261 BICS PC,R14,#C_flag ;No operand was found
265 ;----- Workspace ------------------------------------------------------------
267 val__precTable DCD val__andOp-val__precTable
271 DCD val__multOp-val__precTable
272 DCD val__orOp-val__precTable
274 DCD val__relOp-val__precTable
275 DCD val__addOp-val__precTable
278 ; --- The precedence tables ---
280 ; Each byte indicates whether or not the given type of
281 ; toke has a higher or lower precedence than another type.
282 ; The order of the bytes is:
284 ; and,-,-,-,mult,or,-,-,rel,add,-
286 val__andOp DCB 0, 0, 0, 0,-1, 1, 0, 0,-1,-1, 0
287 val__multOp DCB 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0
288 val__orOp DCB -1, 0, 0, 0,-1, 0, 0, 0,-1,-1, 0
289 val__relOp DCB 1, 0, 0, 0,-1, 1, 0, 0, 0,-1, 0
290 val__addOp DCB 1, 0, 0, 0,-1, 1, 0, 0, 1, 0, 0
292 ;----- That's all, folks ----------------------------------------------------