-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathexpr.s
executable file
·357 lines (329 loc) · 6.32 KB
/
expr.s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
|CompileExpression
OpenBrackPrec = 1
AddOpPrec = 2
MulOpPrec = 3
BangOpPrec = 4 |of the binary ! operator
UnaryOpPrec = 50
|CompileExpression
|
CompileExpression:
mov bx , #1 |last was operator(bh) = 0 start (bl) = 1
movb dl, #0 |operand count.
movb dh, #0 |operands needed
pushf
xor ax,ax
stosw
popf
push ax
jmps FirstTokenThere
CompileNext:
call GetToken
FirstTokenThere:
jnc TokenGot
jmp EndofExpression
TokenGot:
movb al,InputWord
call IsAlphaNumDotAL
jc ConstantGot
cmpb al,#'''
jnz NotNumber
ConstantGot:
orb bh,bh
jnz CanGetConstNow
orb bl,bl
jnz CanGetConstNow
SyntaxErrorMessage:
mov bx,#SyntaxErrMessage
call PanicRecover
CanGetConstNow:
call GetIdForToken
stosw
xor bx,bx |Last was operator = 0 | start = 0
incb dl |operand count
incb dh
jmps CompileNext
NotNumber:
call IsOperator
jnz NotAnOperator
or bx,bx |last was operator or start
jz LastWasNotOperator
call IsUnaryOperator
jz WasUnaryOperator
jmp SyntaxErrorMessage
WasUnaryOperator:
incb dh |unary ops need 0 operands
addb al,#0x80
movb ah,#UnaryOpPrec
LastWasNotOperator:
mov cx,ax
decb dh
ContinuePopping:
mov bp,sp
cmpb 1[bp],ah |if the operator on stack has a higher
jc FinishedPopping |or same precedence
cmp 0[bp],#0 |if the stack isn't finished
jz FinishedPopping
testb cl,#0x80
jnz FinishedPopping
pop ax
call PatchLastOperator
stosw
jmps ContinuePopping
FinishedPopping:
push cx
movb bh,#1 |last was operator = 1
testb cl,#0x80
jnz dontchangestart
xorb bl,bl | Start = 0
dontchangestart:
jmp CompileNext
NotAnOperator:
cmpb al,#'('
jnz NotOpenBraces
movb ah,#OpenBrackPrec
push ax
mov bx,#1 |Last was operator = 0, Start = 1
jmp CompileNext
NotOpenBraces:
cmpb al,#')'
jnz NotCloseBraces
HaveNotFoundOpen:
pop ax
cmp ax,#0
jnz NoUnmatchedBraces
mov bx,#BracketsErrMessage
call PanicRecover
NoUnmatchedBraces:
cmpb al,#'('
jnz StoreThisOne
jmp CompileNext
StoreThisOne:
call PatchLastOperator
stosw
jmps HaveNotFoundOpen
NotCloseBraces:
EndofExpression:
orb bl,bl |start
jz FoundSomething
jmp SyntaxErrorMessage
FoundSomething:
decb dh
jz OperatorCountOK
jmp SyntaxErrorMessage
OperatorCountOK:
pop ax
call PatchLastOperator
stosw
cmpb al,#'('
jnz Notextraleft
mov bx,#BracketsErrMessage
call PanicRecover
Notextraleft:
or ax,ax
jnz OperatorCountOK
| mov si, #PostFixBufferStart
| call DisplayMessage
| db 'Compiled Expr is :',0
|NextOperator:
| lodsw
| call DisplayRegister
| call DisplayMessage
| db ' ',0
| mov cl,ah
| or ax,ax
| jz ExpressionEnd
| or cl,cl
| jz NextOperator
|moretodisplay:
| lodsw
| call DisplayRegister
| call DisplayMessage
| db ' ',0
| dec cl
| jnz moretodisplay
| jmp short NextOperator
|ExpressionEnd:
| mov ax, StringSpace
| call DisplayRegister
| call DisplayMessage
| db 0dh,0ah,0
ret
PatchLastOperator:
push di
push dx
xorb dh,dh
inc dx
sal dx
sub di,dx
sarb dl
decb dl
movb 1[di],dl
pop dx
pop di
xorb dl,dl
ret
Overflow:
mov bx,#OverFlowMessage
call PanicRecover
EvalErrorEnd:
mov sp,bp
stc
ret
EvaluateExpression:
mov bp,sp
lodsw
orb ah,ah
jz EvalErrorEnd
movb cl,ah
NextCycle:
orb cl,cl
jz OperatorFound
MoreConsts:
lodsw
call FindValue
jc EvalErrorEnd
push ax
decb cl
jnz MoreConsts
OperatorFound:
lodsw
or ax,ax
jz EvalEnd
movb cl,ah
cmpb al,#'+'
jnz notplus
pop bx
pop ax
add ax,bx
jc Overflow
push ax
jmp NextCycle
notplus:
cmpb al,#'-'
jnz notminus
pop bx
pop ax
sub ax,bx
jc Overflow
push ax
jmp NextCycle
notminus:
cmpb al,#'*'
jnz notstar
pop bx
pop ax
xor dx,dx
mul bx
jc Overflow
push ax
jmp NextCycle
notstar:
cmpb al,#'!'
jnz notbang
pop ax
orb ah,ah
jnz Overflow
movb bl,al
pop ax
orb ah,ah
jnz Overflow
movb ah,al
movb al,bl
push ax
jmp NextCycle
notbang:
cmpb al,#'/'
jnz notslash
pop bx
pop ax
xor dx,dx
div bx
push ax
jmp NextCycle
notslash:
cmpb al,#'-'+0x80
jnz notuminus
pop ax
neg ax
push ax
jmp NextCycle
notuminus:
cmpb al,#'%'
jnz notmod
pop bx
pop ax
xor dx,dx
div bx
push dx
jmp NextCycle
notmod:
cmpb al,#'!'+0x80
jnz notnot
pop ax
not ax
push ax
jmp NextCycle
notnot:
jmp NextCycle
EvalEnd:
pop ax
ret
|Identifies unary as well as binary operators. For binary operators,
|it returns with ah as the precedence of the operator. For unary operators,
|ah might not make sense, 'cos some operators are binary as well as unary
|operators - specifically + and -. In such cases, it returns the precedence
|of the binary operator even if the usage was as a unary operator. This
|distinction is done later on.
IsOperator:
movb ah,#AddOpPrec
cmpb al,#'+'
jz IsOperatorEnd
cmpb al,#'-'
jz IsOperatorEnd
movb ah,#MulOpPrec
cmpb al,#'*'
jz IsOperatorEnd
cmpb al,#'/'
jz IsOperatorEnd
cmpb al,#'%'
jz IsOperatorEnd
movb ah,#BangOpPrec
cmpb al,#'!'
IsOperatorEnd:
ret
IsUnaryOperator:
cmpb al,#'-'
jz IsUnaryOperatorEnd
cmpb al,#'+'
jz IsUnaryOperatorEnd
cmpb al,#'!'
IsUnaryOperatorEnd:
ret
GetIdForToken:
push bx
push cx
push dx
push si
push di
movb al,InputWord
call IsAlphaAL
jc IsName
call DecimalConvertNumber
call FindFakeSymbol
GotIndex:
mov ax,si
pop di
pop si
pop dx
pop cx
pop bx
ret
IsName:
call FindSymbol
jnc HaveIndexAlready
call AddSymbol
mov Attributes[di],#0
mov Value[di],#0
HaveIndexAlready:
call RecordXref
jmps GotIndex