Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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