Subversion Repositories Kolibri OS

Rev

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

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