Subversion Repositories Kolibri OS

Rev

Rev 2664 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2665 dunkaist 1
 
2
; Copyright (c) 1999-2012, Tomasz Grysztar.
3
; All rights reserved.
4
5
 
6
	push	ebp
2287 heavyiron 7
	call	get_fp_value
8
	jnc	fp_expression
9
	mov	[current_offset],esp
10
      expression_loop:
11
	push	edi
12
	mov	edi,single_operand_operators
13
	call	get_operator
14
	pop	edi
2665 dunkaist 15
	or	al,al
16
	jz	expression_element
17
	cmp	al,82h
18
	je	expression_loop
19
	push	eax
20
	jmp	expression_loop
21
      expression_element:
22
	mov	al,[esi]
2287 heavyiron 23
	cmp	al,1Ah
24
	je	expression_number
25
	cmp	al,22h
26
	je	expression_number
27
	cmp	al,'('
28
	je	expression_number
29
	mov	al,'!'
30
	stos	byte [edi]
31
	jmp	expression_operator
32
      expression_number:
33
	call	convert_number
34
      expression_operator:
35
	push	edi
36
	mov	edi,operators
37
	call	get_operator
38
	pop	edi
39
	or	al,al
40
	jz	expression_end
41
      operators_loop:
42
	cmp	esp,[current_offset]
43
	je	push_operator
44
	mov	bl,al
45
	and	bl,0F0h
46
	mov	bh,byte [esp]
47
	and	bh,0F0h
48
	cmp	bl,bh
49
	ja	push_operator
50
	pop	ebx
51
	mov	byte [edi],bl
52
	inc	edi
53
	jmp	operators_loop
54
      push_operator:
55
	push	eax
56
	jmp	expression_loop
57
      expression_end:
58
	cmp	esp,[current_offset]
59
	je	expression_converted
60
	pop	eax
61
	stos	byte [edi]
62
	jmp	expression_end
63
      expression_converted:
64
	pop	ebp
65
	ret
66
      fp_expression:
67
	mov	al,'.'
68
	stos	byte [edi]
69
	mov	eax,[fp_value]
70
	stos	dword [edi]
71
	mov	eax,[fp_value+4]
72
	stos	dword [edi]
73
	mov	eax,[fp_value+8]
74
	stos	dword [edi]
75
	pop	ebp
76
	ret
77
78
 
79
	lea	eax,[edi-10h]
80
	mov	edx,[memory_end]
81
	cmp	[source_start],0
82
	je	check_memory_for_number
83
	mov	edx,[labels_list]
84
      check_memory_for_number:
85
	cmp	eax,edx
86
	jae	out_of_memory
87
	mov	eax,esp
88
	sub	eax,100h
89
	jc	stack_overflow
90
	cmp	eax,[stack_limit]
91
	jb	stack_overflow
92
	cmp	byte [esi],'('
93
	je	expression_value
94
	inc	edi
95
	call	get_number
96
	jc	symbol_value
97
	or	ebp,ebp
98
	jz	valid_number
99
	mov	byte [edi-1],0Fh
100
	ret
101
      valid_number:
102
	cmp	dword [edi+4],0
103
	jne	qword_number
104
	cmp	word [edi+2],0
105
	jne	dword_number
106
	cmp	byte [edi+1],0
107
	jne	word_number
108
      byte_number:
109
	mov	byte [edi-1],1
110
	inc	edi
111
	ret
112
      qword_number:
113
	mov	byte [edi-1],8
114
	add	edi,8
115
	ret
116
      dword_number:
117
	mov	byte [edi-1],4
118
	scas	dword [edi]
119
	ret
120
      word_number:
121
	mov	byte [edi-1],2
122
	scas	word [edi]
123
	ret
124
      expression_value:
125
	inc	esi
126
	push	[current_offset]
127
	call	convert_expression
128
	pop	[current_offset]
129
	lods	byte [esi]
130
	cmp	al,')'
131
	jne	invalid_expression
132
	ret
133
      symbol_value:
2665 dunkaist 134
	cmp	[source_start],0
135
	je	preprocessor_value
136
	push	edi esi
137
	lods	word [esi]
138
	cmp	al,1Ah
139
	jne	no_address_register
140
	movzx	ecx,ah
141
	call	get_symbol
142
	jc	no_address_register
143
	cmp	al,10h
144
	jne	no_address_register
145
	mov	al,ah
146
	shr	ah,4
147
	cmp	ah,4
148
	je	register_value
149
	cmp	ah,8
150
	je	register_value
151
	cmp	ah,0Ch
152
	je	register_value
153
	cmp	ah,0Dh
154
	je	register_value
155
	cmp	ah,0Fh
156
	je	register_value
157
	cmp	ah,2
158
	jne	no_address_register
159
	cmp	al,23h
160
	je	register_value
161
	cmp	al,25h
162
	je	register_value
163
	cmp	al,26h
164
	je	register_value
165
	cmp	al,27h
166
	je	register_value
167
      no_address_register:
168
	pop	esi
169
	mov	edi,directive_operators
170
	call	get_operator
171
	pop	edi
172
	or	al,al
2287 heavyiron 173
	jnz	broken_value
174
	lods	byte [esi]
175
	cmp	al,1Ah
176
	jne	invalid_value
177
	lods	byte [esi]
178
	movzx	ecx,al
179
	call	get_label_id
180
      store_label_value:
181
	mov	byte [edi-1],11h
182
	stos	dword [edi]
183
	ret
184
      broken_value:
185
	mov	eax,0Fh
2665 dunkaist 186
	jmp	store_label_value
187
      register_value:
188
	pop	edx edi
189
	mov	byte [edi-1],10h
190
	stos	byte [edi]
191
	ret
192
      preprocessor_value:
2287 heavyiron 193
	dec	edi
194
	cmp	[hash_tree],0
195
	je	invalid_value
196
	lods	byte [esi]
197
	cmp	al,1Ah
198
	jne	invalid_value
199
	lods	byte [esi]
200
	mov	cl,al
201
	mov	ch,10b
202
	call	get_preprocessor_symbol
203
	jc	invalid_value
204
	push	esi
205
	mov	esi,[edx+8]
206
	push	[current_offset]
207
	call	convert_expression
208
	pop	[current_offset]
209
	pop	esi
210
	ret
211
212
 
213
	xor	ebp,ebp
214
	lods	byte [esi]
215
	cmp	al,22h
216
	je	get_text_number
217
	cmp	al,1Ah
218
	jne	not_number
219
	lods	byte [esi]
220
	movzx	ecx,al
221
	mov	[number_start],esi
222
	mov	al,[esi]
223
	cmp	al,'$'
224
	je	number_begin
225
	sub	al,30h
226
	cmp	al,9
227
	ja	invalid_number
228
      number_begin:
229
	mov	ebx,esi
230
	add	esi,ecx
231
	push	esi
232
	dec	esi
233
	mov	dword [edi],0
234
	mov	dword [edi+4],0
235
	cmp	byte [ebx],'$'
236
	je	pascal_hex_number
237
	cmp	word [ebx],'0x'
238
	je	get_hex_number
239
	mov	al,[esi]
240
	dec	esi
241
	cmp	al,'h'
242
	je	get_hex_number
243
	cmp	al,'b'
244
	je	get_bin_number
245
	cmp	al,'d'
246
	je	get_dec_number
247
	cmp	al,'o'
248
	je	get_oct_number
249
	cmp	al,'H'
250
	je	get_hex_number
251
	cmp	al,'B'
252
	je	get_bin_number
253
	cmp	al,'D'
254
	je	get_dec_number
255
	cmp	al,'O'
256
	je	get_oct_number
257
	inc	esi
258
      get_dec_number:
259
	mov	ebx,esi
260
	mov	esi,[number_start]
261
      get_dec_digit:
262
	cmp	esi,ebx
263
	ja	number_ok
264
	cmp	byte [esi],27h
265
	je	next_dec_digit
266
	xor	edx,edx
267
	mov	eax,[edi]
268
	shld	edx,eax,2
269
	shl	eax,2
270
	add	eax,[edi]
271
	adc	edx,0
272
	add	eax,eax
273
	adc	edx,edx
274
	mov	[edi],eax
275
	mov	eax,[edi+4]
276
	add	eax,eax
277
	jc	dec_out_of_range
278
	add	eax,eax
279
	jc	dec_out_of_range
280
	add	eax,[edi+4]
281
	jc	dec_out_of_range
282
	add	eax,eax
283
	jc	dec_out_of_range
284
	add	eax,edx
285
	jc	dec_out_of_range
286
	mov	[edi+4],eax
287
	movzx	eax,byte [esi]
288
	sub	al,30h
289
	jc	bad_number
290
	cmp	al,9
291
	ja	bad_number
292
	add	[edi],eax
293
	adc	dword [edi+4],0
294
	jc	dec_out_of_range
295
      next_dec_digit:
296
	inc	esi
297
	jmp	get_dec_digit
298
      dec_out_of_range:
299
	cmp	esi,ebx
300
	ja	dec_out_of_range_finished
301
	lods	byte [esi]
302
	cmp	al,27h
303
	je	bad_number
304
	sub	al,30h
305
	jc	bad_number
306
	cmp	al,9
307
	ja	bad_number
308
	jmp	dec_out_of_range
309
      dec_out_of_range_finished:
310
	or	ebp,-1
311
	jmp	number_ok
312
      bad_number:
313
	pop	eax
314
      invalid_number:
315
	mov	esi,[number_start]
316
	dec	esi
317
      not_number:
318
	dec	esi
319
	stc
320
	ret
321
      get_bin_number:
322
	xor	bl,bl
323
      get_bin_digit:
324
	cmp	esi,[number_start]
325
	jb	number_ok
326
	movzx	eax,byte [esi]
327
	cmp	al,27h
328
	je	bin_digit_skip
329
	sub	al,30h
330
	cmp	al,1
331
	ja	bad_number
332
	xor	edx,edx
333
	mov	cl,bl
334
	dec	esi
335
	cmp	bl,64
336
	je	bin_out_of_range
337
	inc	bl
338
	cmp	cl,32
339
	jae	bin_digit_high
340
	shl	eax,cl
341
	or	dword [edi],eax
342
	jmp	get_bin_digit
343
      bin_digit_high:
344
	sub	cl,32
345
	shl	eax,cl
346
	or	dword [edi+4],eax
347
	jmp	get_bin_digit
348
      bin_out_of_range:
349
	or	al,al
350
	jz	get_bin_digit
351
	or	ebp,-1
352
	jmp	get_bin_digit
353
      bin_digit_skip:
354
	dec	esi
355
	jmp	get_bin_digit
356
      pascal_hex_number:
357
	cmp	cl,1
358
	je	bad_number
359
      get_hex_number:
360
	xor	bl,bl
361
      get_hex_digit:
362
	cmp	esi,[number_start]
363
	jb	number_ok
364
	movzx	eax,byte [esi]
365
	cmp	al,27h
366
	je	hex_digit_skip
367
	cmp	al,'x'
368
	je	hex_number_ok
369
	cmp	al,'$'
370
	je	pascal_hex_ok
371
	sub	al,30h
372
	cmp	al,9
373
	jbe	hex_digit_ok
374
	sub	al,7
375
	cmp	al,15
376
	jbe	hex_letter_digit_ok
377
	sub	al,20h
378
	cmp	al,15
379
	ja	bad_number
380
      hex_letter_digit_ok:
381
	cmp	al,10
382
	jb	bad_number
383
      hex_digit_ok:
384
	xor	edx,edx
385
	mov	cl,bl
386
	dec	esi
387
	cmp	bl,64
388
	je	hex_out_of_range
389
	add	bl,4
390
	cmp	cl,32
391
	jae	hex_digit_high
392
	shl	eax,cl
393
	or	dword [edi],eax
394
	jmp	get_hex_digit
395
      hex_digit_high:
396
	sub	cl,32
397
	shl	eax,cl
398
	or	dword [edi+4],eax
399
	jmp	get_hex_digit
400
      hex_out_of_range:
401
	or	al,al
402
	jz	get_hex_digit
403
	or	ebp,-1
404
	jmp	get_hex_digit
405
      hex_digit_skip:
406
	dec	esi
407
	jmp	get_hex_digit
408
      get_oct_number:
409
	xor	bl,bl
410
      get_oct_digit:
411
	cmp	esi,[number_start]
412
	jb	number_ok
413
	movzx	eax,byte [esi]
414
	cmp	al,27h
415
	je	oct_digit_skip
416
	sub	al,30h
417
	cmp	al,7
418
	ja	bad_number
419
      oct_digit_ok:
420
	xor	edx,edx
2665 dunkaist 421
	mov	cl,bl
422
	dec	esi
423
	cmp	bl,63
424
	ja	oct_out_of_range
425
	jne	oct_range_ok
426
	cmp	al,1
427
	ja	oct_out_of_range
428
      oct_range_ok:
429
	add	bl,3
430
	cmp	cl,30
431
	je	oct_digit_wrap
432
	ja	oct_digit_high
2287 heavyiron 433
	shl	eax,cl
434
	or	dword [edi],eax
435
	jmp	get_oct_digit
436
      oct_digit_wrap:
437
	shl	eax,cl
438
	adc	dword [edi+4],0
439
	or	dword [edi],eax
440
	jmp	get_oct_digit
441
      oct_digit_high:
442
	sub	cl,32
443
	shl	eax,cl
444
	or	dword [edi+4],eax
445
	jmp	get_oct_digit
446
      oct_digit_skip:
447
	dec	esi
448
	jmp	get_oct_digit
449
      oct_out_of_range:
450
	or	al,al
451
	jz	get_oct_digit
452
	or	ebp,-1
453
	jmp	get_oct_digit
454
      hex_number_ok:
455
	dec	esi
456
      pascal_hex_ok:
457
	cmp	esi,[number_start]
458
	jne	bad_number
459
      number_ok:
460
	pop	esi
461
      number_done:
462
	clc
463
	ret
464
      get_text_number:
465
	lods	dword [esi]
466
	mov	edx,eax
467
	xor	bl,bl
468
	mov	dword [edi],0
469
	mov	dword [edi+4],0
470
      get_text_character:
471
	sub	edx,1
472
	jc	number_done
473
	movzx	eax,byte [esi]
474
	inc	esi
475
	mov	cl,bl
476
	cmp	bl,64
477
	je	text_out_of_range
478
	add	bl,8
479
	cmp	cl,32
480
	jae	text_character_high
481
	shl	eax,cl
482
	or	dword [edi],eax
483
	jmp	get_text_character
484
      text_character_high:
485
	sub	cl,32
486
	shl	eax,cl
487
	or	dword [edi+4],eax
488
	jmp	get_text_character
489
      text_out_of_range:
490
	or	ebp,-1
491
	jmp	get_text_character
492
493
 
494
	push	edi esi
495
	lods	byte [esi]
496
	cmp	al,1Ah
497
	je	fp_value_start
498
	cmp	al,'-'
499
	je	fp_sign_ok
500
	cmp	al,'+'
501
	jne	not_fp_value
502
      fp_sign_ok:
503
	lods	byte [esi]
504
	cmp	al,1Ah
505
	jne	not_fp_value
506
      fp_value_start:
507
	lods	byte [esi]
508
	movzx	ecx,al
509
	cmp	cl,1
510
	jbe	not_fp_value
511
	lea	edx,[esi+1]
512
	xor	ah,ah
513
      check_fp_value:
514
	lods	byte [esi]
515
	cmp	al,'.'
516
	je	fp_character_dot
517
	cmp	al,'E'
518
	je	fp_character_exp
519
	cmp	al,'e'
520
	je	fp_character_exp
521
	cmp	al,'F'
522
	je	fp_last_character
523
	cmp	al,'f'
524
	je	fp_last_character
525
      digit_expected:
526
	cmp	al,'0'
527
	jb	not_fp_value
528
	cmp	al,'9'
529
	ja	not_fp_value
530
	jmp	fp_character_ok
531
      fp_character_dot:
532
	cmp	esi,edx
533
	je	not_fp_value
534
	or	ah,ah
535
	jnz	not_fp_value
536
	or	ah,1
537
	lods	byte [esi]
538
	loop	digit_expected
539
      not_fp_value:
540
	pop	esi edi
541
	stc
542
	ret
543
      fp_last_character:
544
	cmp	cl,1
545
	jne	not_fp_value
546
	or	ah,4
547
	jmp	fp_character_ok
548
      fp_character_exp:
549
	cmp	esi,edx
550
	je	not_fp_value
551
	cmp	ah,1
552
	ja	not_fp_value
553
	or	ah,2
554
	cmp	ecx,1
555
	jne	fp_character_ok
556
	cmp	byte [esi],'+'
557
	je	fp_exp_sign
558
	cmp	byte [esi],'-'
559
	jne	fp_character_ok
560
      fp_exp_sign:
561
	inc	esi
562
	cmp	byte [esi],1Ah
563
	jne	not_fp_value
564
	inc	esi
565
	lods	byte [esi]
566
	movzx	ecx,al
567
	inc	ecx
568
      fp_character_ok:
569
	dec	ecx
570
	jnz	check_fp_value
571
	or	ah,ah
572
	jz	not_fp_value
573
	pop	esi
574
	lods	byte [esi]
575
	mov	[fp_sign],0
576
	cmp	al,1Ah
577
	je	fp_get
578
	inc	esi
579
	cmp	al,'+'
580
	je	fp_get
581
	mov	[fp_sign],1
582
      fp_get:
583
	lods	byte [esi]
584
	movzx	ecx,al
585
	xor	edx,edx
586
	mov	edi,fp_value
587
	mov	[edi],edx
588
	mov	[edi+4],edx
589
	mov	[edi+12],edx
590
	call	fp_optimize
591
	mov	[fp_format],0
592
	mov	al,[esi]
593
      fp_before_dot:
594
	lods	byte [esi]
595
	cmp	al,'.'
596
	je	fp_dot
597
	cmp	al,'E'
598
	je	fp_exponent
599
	cmp	al,'e'
600
	je	fp_exponent
601
	cmp	al,'F'
602
	je	fp_done
603
	cmp	al,'f'
604
	je	fp_done
605
	sub	al,30h
606
	mov	edi,fp_value+16
607
	xor	edx,edx
608
	mov	dword [edi+12],edx
609
	mov	dword [edi],edx
610
	mov	dword [edi+4],edx
611
	mov	[edi+7],al
612
	mov	dl,7
613
	mov	dword [edi+8],edx
614
	call	fp_optimize
615
	mov	edi,fp_value
616
	push	ecx
617
	mov	ecx,10
618
	call	fp_mul
619
	pop	ecx
620
	mov	ebx,fp_value+16
621
	call	fp_add
622
	loop	fp_before_dot
623
      fp_dot:
624
	mov	edi,fp_value+16
625
	xor	edx,edx
626
	mov	[edi],edx
627
	mov	[edi+4],edx
628
	mov	byte [edi+7],80h
629
	mov	[edi+8],edx
630
	mov	dword [edi+12],edx
631
	dec	ecx
632
	jz	fp_done
633
      fp_after_dot:
634
	lods	byte [esi]
635
	cmp	al,'E'
636
	je	fp_exponent
637
	cmp	al,'e'
638
	je	fp_exponent
639
	cmp	al,'F'
640
	je	fp_done
641
	cmp	al,'f'
642
	je	fp_done
643
	inc	[fp_format]
644
	cmp	[fp_format],80h
645
	jne	fp_counter_ok
646
	mov	[fp_format],7Fh
647
      fp_counter_ok:
648
	dec	esi
649
	mov	edi,fp_value+16
650
	push	ecx
651
	mov	ecx,10
652
	call	fp_div
653
	push	dword [edi]
654
	push	dword [edi+4]
655
	push	dword [edi+8]
656
	push	dword [edi+12]
657
	lods	byte [esi]
658
	sub	al,30h
659
	movzx	ecx,al
660
	call	fp_mul
661
	mov	ebx,edi
662
	mov	edi,fp_value
663
	call	fp_add
664
	mov	edi,fp_value+16
665
	pop	dword [edi+12]
666
	pop	dword [edi+8]
667
	pop	dword [edi+4]
668
	pop	dword [edi]
669
	pop	ecx
670
	dec	ecx
671
	jnz	fp_after_dot
672
	jmp	fp_done
673
      fp_exponent:
674
	or	[fp_format],80h
675
	xor	edx,edx
676
	xor	ebp,ebp
677
	dec	ecx
678
	jnz	get_exponent
679
	cmp	byte [esi],'+'
680
	je	fp_exponent_sign
681
	cmp	byte [esi],'-'
682
	jne	fp_done
683
	not	ebp
684
      fp_exponent_sign:
685
	add	esi,2
686
	lods	byte [esi]
687
	movzx	ecx,al
688
      get_exponent:
689
	movzx	eax,byte [esi]
690
	inc	esi
691
	sub	al,30h
692
	cmp	al,10
693
	jae	exponent_ok
694
	imul	edx,10
695
	cmp	edx,8000h
696
	jae	value_out_of_range
697
	add	edx,eax
698
	loop	get_exponent
699
      exponent_ok:
700
	mov	edi,fp_value
701
	or	edx,edx
702
	jz	fp_done
703
	mov	ecx,edx
704
	or	ebp,ebp
705
	jnz	fp_negative_power
706
      fp_power:
707
	push	ecx
708
	mov	ecx,10
709
	call	fp_mul
710
	pop	ecx
711
	loop	fp_power
712
	jmp	fp_done
713
      fp_negative_power:
714
	push	ecx
715
	mov	ecx,10
716
	call	fp_div
717
	pop	ecx
718
	loop	fp_negative_power
719
      fp_done:
720
	mov	edi,fp_value
721
	mov	al,[fp_format]
722
	mov	[edi+10],al
723
	mov	al,[fp_sign]
724
	mov	[edi+11],al
725
	test	byte [edi+15],80h
726
	jz	fp_ok
727
	add	dword [edi],1
728
	adc	dword [edi+4],0
729
	jnc	fp_ok
730
	mov	eax,[edi+4]
731
	shrd	[edi],eax,1
732
	shr	eax,1
733
	or	eax,80000000h
734
	mov	[edi+4],eax
735
	inc	word [edi+8]
736
      fp_ok:
737
	pop	edi
738
	clc
739
	ret
740
      fp_mul:
741
	or	ecx,ecx
742
	jz	fp_zero
743
	mov	eax,[edi+12]
744
	mul	ecx
745
	mov	[edi+12],eax
746
	mov	ebx,edx
747
	mov	eax,[edi]
748
	mul	ecx
749
	add	eax,ebx
750
	adc	edx,0
751
	mov	[edi],eax
752
	mov	ebx,edx
753
	mov	eax,[edi+4]
754
	mul	ecx
755
	add	eax,ebx
756
	adc	edx,0
757
	mov	[edi+4],eax
758
      .loop:
759
	or	edx,edx
760
	jz	.done
761
	mov	eax,[edi]
762
	shrd	[edi+12],eax,1
763
	mov	eax,[edi+4]
764
	shrd	[edi],eax,1
765
	shrd	eax,edx,1
766
	mov	[edi+4],eax
767
	shr	edx,1
768
	inc	dword [edi+8]
769
	cmp	dword [edi+8],8000h
770
	jge	value_out_of_range
771
	jmp	.loop
772
      .done:
773
	ret
774
      fp_div:
775
	mov	eax,[edi+4]
776
	xor	edx,edx
777
	div	ecx
778
	mov	[edi+4],eax
779
	mov	eax,[edi]
780
	div	ecx
781
	mov	[edi],eax
782
	mov	eax,[edi+12]
783
	div	ecx
784
	mov	[edi+12],eax
785
	mov	ebx,eax
786
	or	ebx,[edi]
787
	or	ebx,[edi+4]
788
	jz	fp_zero
789
      .loop:
790
	test	byte [edi+7],80h
791
	jnz	.exp_ok
792
	mov	eax,[edi]
793
	shld	[edi+4],eax,1
794
	mov	eax,[edi+12]
795
	shld	[edi],eax,1
796
	add	eax,eax
797
	mov	[edi+12],eax
798
	dec	dword [edi+8]
799
	add	edx,edx
800
	jmp	.loop
801
      .exp_ok:
802
	mov	eax,edx
803
	xor	edx,edx
804
	div	ecx
805
	add	[edi+12],eax
806
	adc	dword [edi],0
807
	adc	dword [edi+4],0
808
	jnc	.done
809
	mov	eax,[edi+4]
810
	mov	ebx,[edi]
811
	shrd	[edi],eax,1
812
	shrd	[edi+12],ebx,1
813
	shr	eax,1
814
	or	eax,80000000h
815
	mov	[edi+4],eax
816
	inc	dword [edi+8]
817
      .done:
818
	ret
819
      fp_add:
820
	cmp	dword [ebx+8],8000h
821
	je	.done
822
	cmp	dword [edi+8],8000h
823
	je	.copy
824
	mov	eax,[ebx+8]
825
	cmp	eax,[edi+8]
826
	jge	.exp_ok
827
	mov	eax,[edi+8]
828
      .exp_ok:
829
	call	.change_exp
830
	xchg	ebx,edi
831
	call	.change_exp
832
	xchg	ebx,edi
833
	mov	edx,[ebx+12]
834
	mov	eax,[ebx]
835
	mov	ebx,[ebx+4]
836
	add	[edi+12],edx
837
	adc	[edi],eax
838
	adc	[edi+4],ebx
839
	jnc	.done
840
	mov	eax,[edi]
841
	shrd	[edi+12],eax,1
842
	mov	eax,[edi+4]
843
	shrd	[edi],eax,1
844
	shr	eax,1
845
	or	eax,80000000h
846
	mov	[edi+4],eax
847
	inc	dword [edi+8]
848
      .done:
849
	ret
850
      .copy:
851
	mov	eax,[ebx]
852
	mov	[edi],eax
853
	mov	eax,[ebx+4]
854
	mov	[edi+4],eax
855
	mov	eax,[ebx+8]
856
	mov	[edi+8],eax
857
	mov	eax,[ebx+12]
858
	mov	[edi+12],eax
859
	ret
860
      .change_exp:
861
	push	ecx
862
	mov	ecx,eax
863
	sub	ecx,[ebx+8]
864
	mov	edx,[ebx+4]
865
	jecxz	.exp_done
866
      .exp_loop:
867
	mov	ebp,[ebx]
868
	shrd	[ebx+12],ebp,1
869
	shrd	[ebx],edx,1
870
	shr	edx,1
871
	inc	dword [ebx+8]
872
	loop	.exp_loop
873
      .exp_done:
874
	mov	[ebx+4],edx
875
	pop	ecx
876
	ret
877
      fp_optimize:
878
	mov	eax,[edi]
879
	mov	ebp,[edi+4]
880
	or	ebp,[edi]
881
	or	ebp,[edi+12]
882
	jz	fp_zero
883
      .loop:
884
	test	byte [edi+7],80h
885
	jnz	.done
886
	shld	[edi+4],eax,1
887
	mov	ebp,[edi+12]
888
	shld	eax,ebp,1
889
	mov	[edi],eax
890
	shl	dword [edi+12],1
891
	dec	dword [edi+8]
892
	jmp	.loop
893
      .done:
894
	ret
895
      fp_zero:
896
	mov	dword [edi+8],8000h
897
	ret
898
899
 
900
	xor	al,al
901
  preevaluate_embedded_logical_expression:
902
	mov	[logical_value_wrapping],al
903
	push	edi
904
	call	preevaluate_logical_value
905
      preevaluation_loop:
906
	cmp	al,0FFh
907
	je	invalid_logical_expression
908
	mov	dl,[esi]
909
	inc	esi
910
	cmp	dl,'|'
911
	je	preevaluate_or
912
	cmp	dl,'&'
913
	je	preevaluate_and
914
	cmp	dl,'}'
915
	je	preevaluation_done
916
	or	dl,dl
917
	jnz	invalid_logical_expression
918
      preevaluation_done:
919
	pop	edx
920
	dec	esi
921
	ret
922
      preevaluate_or:
923
	cmp	al,'1'
924
	je	quick_true
925
	cmp	al,'0'
926
	je	leave_only_following
927
	push	edi
928
	mov	al,dl
929
	stos	byte [edi]
930
	call	preevaluate_logical_value
931
	pop	ebx
932
	cmp	al,'0'
933
	je	leave_only_preceding
934
	cmp	al,'1'
935
	jne	preevaluation_loop
936
	stos	byte [edi]
937
	xor	al,al
938
	jmp	preevaluation_loop
939
      preevaluate_and:
940
	cmp	al,'0'
941
	je	quick_false
942
	cmp	al,'1'
943
	je	leave_only_following
944
	push	edi
945
	mov	al,dl
946
	stos	byte [edi]
947
	call	preevaluate_logical_value
948
	pop	ebx
949
	cmp	al,'1'
950
	je	leave_only_preceding
951
	cmp	al,'0'
952
	jne	preevaluation_loop
953
	stos	byte [edi]
954
	xor	al,al
955
	jmp	preevaluation_loop
956
      leave_only_following:
957
	mov	edi,[esp]
958
	call	preevaluate_logical_value
959
	jmp	preevaluation_loop
960
      leave_only_preceding:
961
	mov	edi,ebx
962
	xor	al,al
963
	jmp	preevaluation_loop
964
      quick_true:
965
	call	skip_logical_value
966
	jc	invalid_logical_expression
967
	mov	edi,[esp]
968
	mov	al,'1'
969
	jmp	preevaluation_loop
970
      quick_false:
971
	call	skip_logical_value
972
	jc	invalid_logical_expression
973
	mov	edi,[esp]
974
	mov	al,'0'
975
	jmp	preevaluation_loop
976
      invalid_logical_expression:
977
	pop	edi
978
	mov	esi,edi
979
	mov	al,0FFh
980
	stos	byte [edi]
981
	ret
982
  skip_logical_value:
983
	cmp	byte [esi],'~'
984
	jne	negation_skipped
985
	inc	esi
986
	jmp	skip_logical_value
987
      negation_skipped:
988
	mov	al,[esi]
989
	cmp	al,'{'
990
	jne	skip_simple_logical_value
991
	inc	esi
992
	xchg	al,[logical_value_wrapping]
993
	push	eax
994
      skip_logical_expression:
995
	call	skip_logical_value
996
	lods	byte [esi]
997
	or	al,al
998
	jz	wrongly_structured_logical_expression
999
	cmp	al,0Fh
1000
	je	wrongly_structured_logical_expression
1001
	cmp	al,'|'
1002
	je	skip_logical_expression
1003
	cmp	al,'&'
1004
	je	skip_logical_expression
1005
	cmp	al,'}'
1006
	jne	wrongly_structured_logical_expression
1007
	pop	eax
1008
	mov	[logical_value_wrapping],al
1009
      logical_value_skipped:
1010
	clc
1011
	ret
1012
      wrongly_structured_logical_expression:
1013
	pop	eax
1014
	stc
1015
	ret
1016
      skip_simple_logical_value:
1017
	mov	[logical_value_parentheses],0
1018
      find_simple_logical_value_end:
1019
	mov	al,[esi]
1020
	or	al,al
1021
	jz	logical_value_skipped
1022
	cmp	al,0Fh
1023
	je	logical_value_skipped
1024
	cmp	al,'|'
1025
	je	logical_value_skipped
1026
	cmp	al,'&'
1027
	je	logical_value_skipped
1028
	cmp	al,'{'
1029
	je	skip_logical_value_internal_parenthesis
1030
	cmp	al,'}'
1031
	jne	skip_logical_value_symbol
1032
	sub	[logical_value_parentheses],1
1033
	jnc	skip_logical_value_symbol
1034
	cmp	[logical_value_wrapping],'{'
1035
	jne	skip_logical_value_symbol
1036
	jmp	logical_value_skipped
1037
      skip_logical_value_internal_parenthesis:
1038
	inc	[logical_value_parentheses]
1039
      skip_logical_value_symbol:
1040
	call	skip_symbol
1041
	jmp	find_simple_logical_value_end
1042
  preevaluate_logical_value:
1043
	mov	ebp,edi
1044
      preevaluate_negation:
1045
	cmp	byte [esi],'~'
1046
	jne	preevaluate_negation_ok
1047
	movs	byte [edi],[esi]
1048
	jmp	preevaluate_negation
1049
      preevaluate_negation_ok:
1050
	mov	ebx,esi
1051
	cmp	byte [esi],'{'
1052
	jne	preevaluate_simple_logical_value
1053
	lods	byte [esi]
1054
	stos	byte [edi]
1055
	push	ebp
1056
	mov	dl,[logical_value_wrapping]
1057
	push	edx
1058
	call	preevaluate_embedded_logical_expression
1059
	pop	edx
1060
	mov	[logical_value_wrapping],dl
1061
	pop	ebp
1062
	cmp	al,0FFh
1063
	je	invalid_logical_value
1064
	cmp	byte [esi],'}'
1065
	jne	invalid_logical_value
1066
	or	al,al
1067
	jnz	preevaluated_expression_value
1068
	movs	byte [edi],[esi]
1069
	ret
1070
      preevaluated_expression_value:
1071
	inc	esi
1072
	lea	edx,[edi-1]
1073
	sub	edx,ebp
1074
	test	edx,1
1075
	jz	expression_negation_ok
1076
	xor	al,1
1077
      expression_negation_ok:
1078
	mov	edi,ebp
1079
	ret
1080
      invalid_logical_value:
1081
	mov	edi,ebp
1082
	mov	al,0FFh
1083
	ret
1084
      preevaluate_simple_logical_value:
1085
	xor	edx,edx
1086
	mov	[logical_value_parentheses],edx
1087
      find_logical_value_boundaries:
1088
	mov	al,[esi]
1089
	or	al,al
1090
	jz	logical_value_boundaries_found
1091
	cmp	al,'{'
1092
	je	logical_value_internal_parentheses
1093
	cmp	al,'}'
1094
	je	logical_value_boundaries_parenthesis_close
1095
	cmp	al,'|'
1096
	je	logical_value_boundaries_found
1097
	cmp	al,'&'
1098
	je	logical_value_boundaries_found
1099
	or	edx,edx
1100
	jnz	next_symbol_in_logical_value
1101
	cmp	al,0F0h
1102
	je	preevaluable_logical_operator
1103
	cmp	al,0F7h
1104
	je	preevaluable_logical_operator
1105
	cmp	al,0F6h
1106
	jne	next_symbol_in_logical_value
1107
      preevaluable_logical_operator:
1108
	mov	edx,esi
1109
      next_symbol_in_logical_value:
1110
	call	skip_symbol
1111
	jmp	find_logical_value_boundaries
1112
      logical_value_internal_parentheses:
1113
	inc	[logical_value_parentheses]
1114
	jmp	next_symbol_in_logical_value
1115
      logical_value_boundaries_parenthesis_close:
1116
	sub	[logical_value_parentheses],1
1117
	jnc	next_symbol_in_logical_value
1118
	cmp	[logical_value_wrapping],'{'
1119
	jne	next_symbol_in_logical_value
1120
      logical_value_boundaries_found:
1121
	or	edx,edx
1122
	jz	non_preevaluable_logical_value
1123
	mov	al,[edx]
1124
	cmp	al,0F0h
1125
	je	compare_symbols
1126
	cmp	al,0F7h
1127
	je	compare_symbol_types
1128
	cmp	al,0F6h
1129
	je	scan_symbols_list
1130
      non_preevaluable_logical_value:
1131
	mov	ecx,esi
1132
	mov	esi,ebx
1133
	sub	ecx,esi
1134
	jz	invalid_logical_value
1135
	cmp	esi,edi
1136
	je	leave_logical_value_intact
1137
	rep	movs byte [edi],[esi]
1138
	xor	al,al
1139
	ret
1140
      leave_logical_value_intact:
1141
	add	edi,ecx
1142
	add	esi,ecx
1143
	xor	al,al
1144
	ret
1145
      compare_symbols:
1146
	lea	ecx,[esi-1]
1147
	sub	ecx,edx
1148
	mov	eax,edx
1149
	sub	eax,ebx
1150
	cmp	ecx,eax
1151
	jne	preevaluated_false
1152
	push	esi edi
1153
	mov	esi,ebx
1154
	lea	edi,[edx+1]
1155
	repe	cmps byte [esi],[edi]
1156
	pop	edi esi
1157
	je	preevaluated_true
1158
      preevaluated_false:
1159
	mov	eax,edi
1160
	sub	eax,ebp
1161
	test	eax,1
1162
	jnz	store_true
1163
      store_false:
1164
	mov	edi,ebp
1165
	mov	al,'0'
1166
	ret
1167
      preevaluated_true:
1168
	mov	eax,edi
1169
	sub	eax,ebp
1170
	test	eax,1
1171
	jnz	store_false
1172
      store_true:
1173
	mov	edi,ebp
1174
	mov	al,'1'
1175
	ret
1176
      compare_symbol_types:
1177
	push	esi
1178
	lea	esi,[edx+1]
1179
      type_comparison:
1180
	cmp	esi,[esp]
1181
	je	types_compared
1182
	mov	al,[esi]
1183
	cmp	al,[ebx]
1184
	jne	different_type
1185
	cmp	al,'('
1186
	jne	equal_type
1187
	mov	al,[esi+1]
1188
	mov	ah,[ebx+1]
1189
	cmp	al,ah
1190
	je	equal_type
1191
	or	al,al
1192
	jz	different_type
1193
	or	ah,ah
1194
	jz	different_type
1195
	cmp	al,'.'
1196
	je	different_type
1197
	cmp	ah,'.'
1198
	je	different_type
1199
      equal_type:
1200
	call	skip_symbol
1201
	xchg	esi,ebx
1202
	call	skip_symbol
1203
	xchg	esi,ebx
1204
	jmp	type_comparison
1205
      types_compared:
1206
	pop	esi
1207
	cmp	byte [ebx],0F7h
1208
	jne	preevaluated_false
1209
	jmp	preevaluated_true
1210
      different_type:
1211
	pop	esi
1212
	jmp	preevaluated_false
1213
      scan_symbols_list:
1214
	push	edi esi
1215
	lea	esi,[edx+1]
1216
	sub	edx,ebx
1217
	lods	byte [esi]
1218
	cmp	al,'<'
1219
	jne	invalid_symbols_list
1220
      get_next_from_list:
1221
	mov	edi,esi
1222
      get_from_list:
1223
	cmp	byte [esi],','
1224
	je	compare_in_list
1225
	cmp	byte [esi],'>'
1226
	je	compare_in_list
1227
	cmp	esi,[esp]
1228
	jae	invalid_symbols_list
1229
	call	skip_symbol
1230
	jmp	get_from_list
1231
      compare_in_list:
1232
	mov	ecx,esi
1233
	sub	ecx,edi
1234
	cmp	ecx,edx
1235
	jne	not_equal_length_in_list
1236
	mov	esi,ebx
1237
	repe	cmps byte [esi],[edi]
1238
	mov	esi,edi
1239
	jne	not_equal_in_list
1240
      skip_rest_of_list:
1241
	cmp	byte [esi],'>'
1242
	je	check_list_end
1243
	cmp	esi,[esp]
1244
	jae	invalid_symbols_list
1245
	call	skip_symbol
1246
	jmp	skip_rest_of_list
1247
      check_list_end:
1248
	inc	esi
1249
	cmp	esi,[esp]
1250
	jne	invalid_symbols_list
1251
	pop	esi edi
1252
	jmp	preevaluated_true
1253
      not_equal_in_list:
1254
	add	esi,ecx
1255
      not_equal_length_in_list:
1256
	lods	byte [esi]
1257
	cmp	al,','
1258
	je	get_next_from_list
1259
	cmp	esi,[esp]
1260
	jne	invalid_symbols_list
1261
	pop	esi edi
1262
	jmp	preevaluated_false
1263
      invalid_symbols_list:
1264
	pop	esi edi
1265
	jmp	invalid_logical_value
1266
>