Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
31 halyavin 1
 
2
; Copyright (c) 1999-2011, Tomasz Grysztar.
2287 heavyiron 3
; All rights reserved.
31 halyavin 4
5
 
6
	mov	edi,characters
157 heavyiron 7
	xor	al,al
8
      make_characters_table:
31 halyavin 9
	stosb
157 heavyiron 10
	inc	al
11
	jnz	make_characters_table
253 heavyiron 12
	mov	esi,characters+'a'
157 heavyiron 13
	mov	edi,characters+'A'
14
	mov	ecx,26
15
	rep	movsb
16
	mov	edi,characters
17
	mov	esi,symbol_characters+1
18
	movzx	ecx,byte [esi-1]
19
	xor	eax,eax
20
      mark_symbol_characters:
31 halyavin 21
	lodsb
157 heavyiron 22
	mov	byte [edi+eax],0
23
	loop	mark_symbol_characters
24
	mov	edi,locals_counter
25
	mov	ax,1 + '0' shl 8
692 heavyiron 26
	stos	word [edi]
27
	mov	edi,[memory_start]
157 heavyiron 28
	mov	[include_paths],edi
29
	mov	esi,include_variable
30
	call	get_environment_variable
31
	xor	al,al
32
	stos	byte [edi]
1053 heavyiron 33
	mov	[memory_start],edi
157 heavyiron 34
	mov	eax,[additional_memory]
35
	mov	[free_additional_memory],eax
36
	mov	eax,[additional_memory_end]
37
	mov	[labels_list],eax
38
	xor	eax,eax
39
	mov	[source_start],eax
1189 heavyiron 40
	mov	[display_buffer],eax
157 heavyiron 41
	mov	[hash_tree],eax
42
	mov	[macro_status],al
43
	mov	esi,[input_file]
44
	mov	edx,esi
45
	call	open
46
	jc	main_file_not_found
47
	mov	edi,[memory_start]
48
	call	preprocess_file
49
	mov	eax,[error_line]
50
	mov	[current_line],eax
51
	cmp	[macro_status],0
52
	jne	incomplete_macro
53
	mov	[source_start],edi
54
	ret
55
31 halyavin 56
 
57
	push	[memory_end]
157 heavyiron 58
	push	esi
59
	mov	al,2
60
	xor	edx,edx
61
	call	lseek
62
	push	eax
63
	xor	al,al
64
	xor	edx,edx
65
	call	lseek
66
	pop	ecx
67
	mov	edx,[memory_end]
68
	dec	edx
69
	mov	byte [edx],1Ah
70
	sub	edx,ecx
71
	jc	out_of_memory
72
	mov	esi,edx
73
	cmp	edx,edi
74
	jbe	out_of_memory
75
	mov	[memory_end],edx
76
	call	read
77
	call	close
78
	pop	edx
79
	xor	ecx,ecx
80
	mov	ebx,esi
81
      preprocess_source:
31 halyavin 82
	inc	ecx
157 heavyiron 83
	mov	[current_line],edi
84
	mov	eax,edx
85
	stos	dword [edi]
86
	mov	eax,ecx
87
	stos	dword [edi]
88
	mov	eax,esi
89
	sub	eax,ebx
90
	stos	dword [edi]
91
	xor	eax,eax
92
	stos	dword [edi]
93
	push	ebx edx
94
	call	convert_line
95
	call	preprocess_line
96
	pop	edx ebx
97
      next_line:
31 halyavin 98
	cmp	byte [esi-1],0
2287 heavyiron 99
	je	file_end
100
	cmp	byte [esi-1],1Ah
157 heavyiron 101
	jne	preprocess_source
102
      file_end:
31 halyavin 103
	pop	[memory_end]
157 heavyiron 104
	clc
105
	ret
106
31 halyavin 107
 
108
	push	ecx
157 heavyiron 109
	test	[macro_status],0Fh
110
	jz	convert_line_data
111
	mov	ax,3Bh
112
	stos	word [edi]
113
      convert_line_data:
31 halyavin 114
	cmp	edi,[memory_end]
157 heavyiron 115
	jae	out_of_memory
116
	lods	byte [esi]
117
	cmp	al,20h
118
	je	convert_line_data
119
	cmp	al,9
120
	je	convert_line_data
121
	mov	ah,al
122
	mov	ebx,characters
123
	xlat	byte [ebx]
124
	or	al,al
125
	jz	convert_separator
126
	cmp	ah,27h
127
	je	convert_string
128
	cmp	ah,22h
129
	je	convert_string
130
	mov	byte [edi],1Ah
131
	scas	word [edi]
132
	xchg	al,ah
133
	stos	byte [edi]
134
	mov	ebx,characters
135
	xor	ecx,ecx
136
      convert_symbol:
31 halyavin 137
	lods	byte [esi]
157 heavyiron 138
	stos	byte [edi]
139
	xlat	byte [ebx]
140
	or	al,al
141
	loopnzd convert_symbol
142
	neg	ecx
143
	cmp	ecx,255
144
	ja	name_too_long
145
	mov	ebx,edi
146
	sub	ebx,ecx
147
	mov	byte [ebx-2],cl
148
      found_separator:
31 halyavin 149
	dec	edi
157 heavyiron 150
	mov	ah,[esi-1]
151
      convert_separator:
31 halyavin 152
	xchg	al,ah
157 heavyiron 153
	cmp	al,20h
154
	jb	control_character
155
	je	convert_line_data
156
      symbol_character:
31 halyavin 157
	cmp	al,3Bh
157 heavyiron 158
	je	ignore_comment
159
	cmp	al,5Ch
160
	je	backslash_character
161
	stos	byte [edi]
162
	jmp	convert_line_data
163
      control_character:
31 halyavin 164
	cmp	al,1Ah
157 heavyiron 165
	je	line_end
166
	cmp	al,0Dh
167
	je	cr_character
168
	cmp	al,0Ah
169
	je	lf_character
170
	cmp	al,9
171
	je	convert_line_data
172
	or	al,al
173
	jnz	symbol_character
174
	jmp	line_end
175
      lf_character:
31 halyavin 176
	lods	byte [esi]
157 heavyiron 177
	cmp	al,0Dh
178
	je	line_end
179
	dec	esi
180
	jmp	line_end
181
      cr_character:
31 halyavin 182
	lods	byte [esi]
157 heavyiron 183
	cmp	al,0Ah
184
	je	line_end
185
	dec	esi
186
	jmp	line_end
187
      convert_string:
31 halyavin 188
	mov	al,22h
157 heavyiron 189
	stos	byte [edi]
190
	scas	dword [edi]
191
	mov	ebx,edi
192
      copy_string:
31 halyavin 193
	lods	byte [esi]
157 heavyiron 194
	stos	byte [edi]
195
	cmp	al,0Ah
196
	je	missing_end_quote
197
	cmp	al,0Dh
198
	je	missing_end_quote
199
	or	al,al
200
	jz	missing_end_quote
201
	cmp	al,1Ah
202
	je	missing_end_quote
203
	cmp	al,ah
204
	jne	copy_string
205
	lods	byte [esi]
206
	cmp	al,ah
207
	je	copy_string
208
	dec	esi
209
	dec	edi
210
	mov	eax,edi
211
	sub	eax,ebx
212
	mov	[ebx-4],eax
213
	jmp	convert_line_data
214
      backslash_character:
31 halyavin 215
	mov	byte [edi],0
157 heavyiron 216
	lods	byte [esi]
217
	cmp	al,20h
218
	je	concatenate_lines
219
	cmp	al,9
220
	je	concatenate_lines
221
	cmp	al,1Ah
222
	je	unexpected_end_of_file
223
	or	al,al
2287 heavyiron 224
	jz	unexpected_end_of_file
225
	cmp	al,0Ah
157 heavyiron 226
	je	concatenate_lf
227
	cmp	al,0Dh
228
	je	concatenate_cr
229
	cmp	al,3Bh
230
	je	find_concatenated_line
231
	mov	al,1Ah
232
	stos	byte [edi]
233
	mov	ecx,edi
234
	mov	ax,5C01h
235
	stos	word [edi]
236
	dec	esi
237
      group_backslashes:
31 halyavin 238
	lods	byte [esi]
157 heavyiron 239
	cmp	al,5Ch
240
	jne	backslashed_symbol
241
	stos	byte [edi]
242
	inc	byte [ecx]
243
	jmp	group_backslashes
244
      backslashed_symbol:
31 halyavin 245
	cmp	al,1Ah
157 heavyiron 246
	je	unexpected_end_of_file
247
	or	al,al
2287 heavyiron 248
	jz	unexpected_end_of_file
249
	cmp	al,0Ah
157 heavyiron 250
	je	extra_characters_on_line
251
	cmp	al,0Dh
252
	je	extra_characters_on_line
253
	cmp	al,20h
254
	je	extra_characters_on_line
255
	cmp	al,9
256
	je	extra_characters_on_line
257
	cmp	al,22h
258
	je	extra_characters_on_line
259
	cmp	al,27h
260
	je	extra_characters_on_line
261
	cmp	al,3Bh
262
	je	extra_characters_on_line
263
	mov	ah,al
264
	mov	ebx,characters
265
	xlat	byte [ebx]
266
	or	al,al
267
	jz	backslashed_symbol_character
268
	mov	al,ah
269
      convert_backslashed_symbol:
31 halyavin 270
	stos	byte [edi]
157 heavyiron 271
	xlat	byte [ebx]
272
	or	al,al
273
	jz	found_separator
274
	inc	byte [ecx]
275
	jz	name_too_long
276
	lods	byte [esi]
277
	jmp	convert_backslashed_symbol
278
      backslashed_symbol_character:
31 halyavin 279
	mov	al,ah
157 heavyiron 280
	stos	byte [edi]
281
	inc	byte [ecx]
282
	jmp	convert_line_data
283
      concatenate_lines:
31 halyavin 284
	lods	byte [esi]
157 heavyiron 285
	cmp	al,20h
286
	je	concatenate_lines
287
	cmp	al,9
288
	je	concatenate_lines
289
	cmp	al,1Ah
290
	je	unexpected_end_of_file
291
	or	al,al
2287 heavyiron 292
	jz	unexpected_end_of_file
293
	cmp	al,0Ah
157 heavyiron 294
	je	concatenate_lf
295
	cmp	al,0Dh
296
	je	concatenate_cr
297
	cmp	al,3Bh
298
	jne	extra_characters_on_line
299
      find_concatenated_line:
31 halyavin 300
	lods	byte [esi]
157 heavyiron 301
	cmp	al,0Ah
302
	je	concatenate_lf
303
	cmp	al,0Dh
304
	je	concatenate_cr
305
	or	al,al
306
	jz	concatenate_ok
307
	cmp	al,1Ah
308
	jne	find_concatenated_line
309
	jmp	unexpected_end_of_file
310
      concatenate_lf:
31 halyavin 311
	lods	byte [esi]
157 heavyiron 312
	cmp	al,0Dh
313
	je	concatenate_ok
314
	dec	esi
315
	jmp	concatenate_ok
316
      concatenate_cr:
31 halyavin 317
	lods	byte [esi]
157 heavyiron 318
	cmp	al,0Ah
319
	je	concatenate_ok
320
	dec	esi
321
      concatenate_ok:
31 halyavin 322
	inc	dword [esp]
157 heavyiron 323
	jmp	convert_line_data
324
      ignore_comment:
31 halyavin 325
	lods	byte [esi]
157 heavyiron 326
	cmp	al,0Ah
327
	je	lf_character
328
	cmp	al,0Dh
329
	je	cr_character
330
	or	al,al
331
	jz	line_end
332
	cmp	al,1Ah
333
	jne	ignore_comment
334
      line_end:
31 halyavin 335
	xor	al,al
157 heavyiron 336
	stos	byte [edi]
337
	pop	ecx
338
	ret
339
31 halyavin 340
 
109 heavyiron 341
	mov	edi,converted
157 heavyiron 342
	mov	ebx,characters
343
      convert_case:
109 heavyiron 344
	lods	byte [esi]
157 heavyiron 345
	xlat	byte [ebx]
346
	stos	byte [edi]
347
	loop	convert_case
348
      case_ok:
109 heavyiron 349
	ret
157 heavyiron 350
109 heavyiron 351
 
352
	push	edi
157 heavyiron 353
	mov	edx,esi
354
	mov	ebp,ecx
355
	call	lower_case
356
	pop	edi
357
      scan_directives:
109 heavyiron 358
	mov	esi,converted
157 heavyiron 359
	movzx	eax,byte [edi]
360
	or	al,al
361
	jz	no_directive
362
	mov	ecx,ebp
363
	inc	edi
364
	mov	ebx,edi
365
	add	ebx,eax
366
	mov	ah,[esi]
367
	cmp	ah,[edi]
368
	jb	no_directive
369
	ja	next_directive
370
	cmp	cl,al
371
	jne	next_directive
372
	repe	cmps byte [esi],[edi]
373
	jb	no_directive
374
	je	directive_ok
375
      next_directive:
109 heavyiron 376
	mov	edi,ebx
157 heavyiron 377
	add	edi,2
378
	jmp	scan_directives
379
      no_directive:
109 heavyiron 380
	mov	esi,edx
157 heavyiron 381
	mov	ecx,ebp
382
	stc
383
	ret
384
      directive_ok:
109 heavyiron 385
	lea	esi,[edx+ebp]
157 heavyiron 386
	call	directive_handler
1189 heavyiron 387
      directive_handler:
388
	pop	ecx
389
	movzx	eax,word [ebx]
157 heavyiron 390
	add	eax,ecx
1189 heavyiron 391
	clc
157 heavyiron 392
	ret
393
109 heavyiron 394
 
31 halyavin 395
	mov	eax,esp
157 heavyiron 396
	sub	eax,100h
397
	jc	stack_overflow
398
	cmp	eax,[stack_limit]
399
	jb	stack_overflow
400
	push	ecx esi
401
      preprocess_current_line:
31 halyavin 402
	mov	esi,[current_line]
157 heavyiron 403
	add	esi,16
404
	cmp	word [esi],3Bh
405
	jne	line_start_ok
406
	add	esi,2
407
      line_start_ok:
31 halyavin 408
	test	[macro_status],0F0h
157 heavyiron 409
	jnz	macro_preprocessing
410
	cmp	byte [esi],1Ah
411
	jne	not_fix_constant
412
	movzx	edx,byte [esi+1]
413
	lea	edx,[esi+2+edx]
414
	cmp	word [edx],031Ah
415
	jne	not_fix_constant
416
	mov	ebx,characters
417
	movzx	eax,byte [edx+2]
418
	xlat	byte [ebx]
419
	ror	eax,8
420
	mov	al,[edx+3]
421
	xlat	byte [ebx]
422
	ror	eax,8
423
	mov	al,[edx+4]
424
	xlat	byte [ebx]
425
	ror	eax,16
426
	cmp	eax,'fix'
427
	je	define_fix_constant
428
      not_fix_constant:
31 halyavin 429
	call	process_fix_constants
157 heavyiron 430
	jmp	initial_preprocessing_ok
431
      macro_preprocessing:
31 halyavin 432
	call	process_macro_operators
157 heavyiron 433
      initial_preprocessing_ok:
31 halyavin 434
	mov	esi,[current_line]
157 heavyiron 435
	add	esi,16
436
	mov	al,[macro_status]
437
	test	al,2
438
	jnz	skip_macro_block
439
	test	al,1
440
	jnz	find_macro_block
441
      preprocess_instruction:
31 halyavin 442
	mov	[current_offset],esi
157 heavyiron 443
	lods	byte [esi]
444
	movzx	ecx,byte [esi]
445
	inc	esi
446
	cmp	al,1Ah
447
	jne	not_preprocessor_symbol
448
	cmp	cl,3
449
	jb	not_preprocessor_directive
450
	push	edi
451
	mov	edi,preprocessor_directives
452
	call	get_directive
453
	pop	edi
454
	jc	not_preprocessor_directive
455
	mov	byte [edx-2],3Bh
456
	jmp	near eax
457
      not_preprocessor_directive:
31 halyavin 458
	xor	ch,ch
157 heavyiron 459
	call	get_preprocessor_symbol
460
	jc	not_macro
461
	mov	byte [ebx-2],3Bh
462
	mov	[struc_name],0
463
	jmp	use_macro
464
      not_macro:
31 halyavin 465
	mov	[struc_name],esi
157 heavyiron 466
	add	esi,ecx
467
	lods	byte [esi]
468
	cmp	al,':'
469
	je	preprocess_label
470
	cmp	al,1Ah
471
	jne	not_preprocessor_symbol
472
	lods	byte [esi]
473
	cmp	al,3
474
	jne	not_symbolic_constant
475
	mov	ebx,characters
476
	movzx	eax,byte [esi]
477
	xlat	byte [ebx]
478
	ror	eax,8
479
	mov	al,[esi+1]
480
	xlat	byte [ebx]
481
	ror	eax,8
482
	mov	al,[esi+2]
483
	xlat	byte [ebx]
484
	ror	eax,16
485
	cmp	eax,'equ'
486
	je	define_equ_constant
487
	mov	al,3
488
      not_symbolic_constant:
31 halyavin 489
	mov	ch,1
157 heavyiron 490
	mov	cl,al
491
	call	get_preprocessor_symbol
492
	jc	not_preprocessor_symbol
493
	push	edx esi
494
	mov	esi,[struc_name]
495
	mov	[struc_label],esi
496
	sub	[struc_label],2
497
	mov	cl,[esi-1]
498
	mov	ch,10b
499
	call	get_preprocessor_symbol
500
	jc	struc_name_ok
501
	mov	ecx,[edx+12]
502
	add	ecx,3
503
	lea	ebx,[edi+ecx]
504
	mov	ecx,edi
505
	sub	ecx,[struc_label]
506
	lea	esi,[edi-1]
507
	lea	edi,[ebx-1]
508
	std
509
	rep	movs byte [edi],[esi]
510
	cld
511
	mov	edi,[struc_label]
512
	mov	esi,[edx+8]
513
	mov	ecx,[edx+12]
514
	add	[struc_name],ecx
515
	add	[struc_name],3
516
	call	move_data
517
	mov	al,3Ah
518
	stos	byte [edi]
519
	mov	ax,3Bh
520
	stos	word [edi]
521
	mov	edi,ebx
522
	pop	esi
523
	add	esi,[edx+12]
524
	add	esi,3
525
	pop	edx
526
	jmp	use_macro
527
      struc_name_ok:
31 halyavin 528
	mov	edx,[struc_name]
157 heavyiron 529
	movzx	eax,byte [edx-1]
530
	add	edx,eax
531
	push	edi
992 heavyiron 532
	lea	esi,[edi-1]
533
	mov	ecx,edi
534
	sub	ecx,edx
535
	std
536
	rep	movs byte [edi],[esi]
537
	cld
538
	pop	edi
539
	inc	edi
540
	mov	al,3Ah
157 heavyiron 541
	mov	[edx],al
542
	inc	al
543
	mov	[edx+1],al
992 heavyiron 544
	pop	esi edx
157 heavyiron 545
	inc	esi
992 heavyiron 546
	jmp	use_macro
157 heavyiron 547
      preprocess_label:
31 halyavin 548
	dec	esi
157 heavyiron 549
	sub	esi,ecx
550
	lea	ebp,[esi-2]
551
	mov	ch,10b
552
	call	get_preprocessor_symbol
553
	jnc	symbolic_constant_in_label
554
	lea	esi,[esi+ecx+1]
555
	jmp	preprocess_instruction
556
      symbolic_constant_in_label:
31 halyavin 557
	mov	ebx,[edx+8]
157 heavyiron 558
	mov	ecx,[edx+12]
559
	add	ecx,ebx
560
      check_for_broken_label:
31 halyavin 561
	cmp	ebx,ecx
157 heavyiron 562
	je	label_broken
563
	cmp	byte [ebx],1Ah
564
	jne	label_broken
565
	movzx	eax,byte [ebx+1]
566
	lea	ebx,[ebx+2+eax]
567
	cmp	ebx,ecx
568
	je	label_constant_ok
569
	cmp	byte [ebx],':'
570
	jne	label_broken
571
	inc	ebx
572
	jmp	check_for_broken_label
573
      label_broken:
31 halyavin 574
	push	line_preprocessed
157 heavyiron 575
	jmp	replace_symbolic_constant
576
      label_constant_ok:
31 halyavin 577
	mov	ecx,edi
157 heavyiron 578
	sub	ecx,esi
579
	mov	edi,[edx+12]
580
	add	edi,ebp
581
	push	edi
582
	lea	eax,[edi+ecx]
583
	push	eax
584
	cmp	esi,edi
585
	je	replace_label
586
	jb	move_rest_of_line_up
587
	rep	movs byte [edi],[esi]
588
	jmp	replace_label
589
      move_rest_of_line_up:
31 halyavin 590
	lea	esi,[esi+ecx-1]
157 heavyiron 591
	lea	edi,[edi+ecx-1]
592
	std
593
	rep	movs byte [edi],[esi]
594
	cld
595
      replace_label:
31 halyavin 596
	mov	ecx,[edx+12]
157 heavyiron 597
	mov	edi,[esp+4]
598
	sub	edi,ecx
599
	mov	esi,[edx+8]
600
	rep	movs byte [edi],[esi]
601
	pop	edi esi
602
	inc	esi
603
	jmp	preprocess_instruction
604
      not_preprocessor_symbol:
31 halyavin 605
	mov	esi,[current_offset]
157 heavyiron 606
	call	process_equ_constants
607
      line_preprocessed:
31 halyavin 608
	pop	esi ecx
157 heavyiron 609
	ret
610
31 halyavin 611
 
612
	push	ebp edi esi
157 heavyiron 613
	mov	ebp,ecx
614
	shl	ebp,22
615
	movzx	ecx,cl
616
	mov	ebx,hash_tree
617
	mov	edi,10
618
      follow_hashes_roots:
31 halyavin 619
	mov	edx,[ebx]
157 heavyiron 620
	or	edx,edx
621
	jz	preprocessor_symbol_not_found
622
	xor	eax,eax
623
	shl	ebp,1
624
	adc	eax,0
625
	lea	ebx,[edx+eax*4]
626
	dec	edi
627
	jnz	follow_hashes_roots
628
	mov	edi,ebx
629
	call	calculate_hash
630
	mov	ebp,eax
631
	and	ebp,3FFh
632
	shl	ebp,10
633
	xor	ebp,eax
634
	mov	ebx,edi
635
	mov	edi,22
636
      follow_hashes_tree:
31 halyavin 637
	mov	edx,[ebx]
157 heavyiron 638
	or	edx,edx
639
	jz	preprocessor_symbol_not_found
640
	xor	eax,eax
641
	shl	ebp,1
642
	adc	eax,0
643
	lea	ebx,[edx+eax*4]
644
	dec	edi
645
	jnz	follow_hashes_tree
646
	mov	al,cl
647
	mov	edx,[ebx]
648
	or	edx,edx
649
	jz	preprocessor_symbol_not_found
650
      compare_with_preprocessor_symbol:
31 halyavin 651
	mov	edi,[edx+4]
157 heavyiron 652
	cmp	edi,1
653
	jbe	next_equal_hash
654
	repe	cmps byte [esi],[edi]
655
	je	preprocessor_symbol_found
656
	mov	cl,al
657
	mov	esi,[esp]
658
      next_equal_hash:
31 halyavin 659
	mov	edx,[edx]
157 heavyiron 660
	or	edx,edx
661
	jnz	compare_with_preprocessor_symbol
662
      preprocessor_symbol_not_found:
31 halyavin 663
	pop	esi edi ebp
157 heavyiron 664
	stc
665
	ret
666
      preprocessor_symbol_found:
31 halyavin 667
	pop	ebx edi ebp
157 heavyiron 668
	clc
669
	ret
670
      calculate_hash:
31 halyavin 671
	xor	ebx,ebx
157 heavyiron 672
	mov	eax,2166136261
673
	mov	ebp,16777619
674
      fnv1a_hash:
31 halyavin 675
	xor	al,[esi+ebx]
157 heavyiron 676
	mul	ebp
677
	inc	bl
678
	cmp	bl,cl
679
	jb	fnv1a_hash
680
	ret
681
add_preprocessor_symbol:
31 halyavin 682
	push	edi esi
157 heavyiron 683
	cmp	ch,11b
992 heavyiron 684
	je	preprocessor_symbol_name_ok
685
	push	ecx
686
	movzx	ecx,cl
687
	mov	edi,preprocessor_directives
872 heavyiron 688
	call	get_directive
689
	jnc	reserved_word_used_as_symbol
690
	pop	ecx
992 heavyiron 691
      preprocessor_symbol_name_ok:
692
	call	calculate_hash
157 heavyiron 693
	mov	ebp,eax
694
	and	ebp,3FFh
695
	shr	eax,10
696
	xor	ebp,eax
697
	shl	ecx,22
698
	or	ebp,ecx
699
	mov	ebx,hash_tree
700
	mov	ecx,32
701
      find_leave_for_symbol:
31 halyavin 702
	mov	edx,[ebx]
157 heavyiron 703
	or	edx,edx
704
	jz	extend_hashes_tree
705
	xor	eax,eax
706
	rol	ebp,1
707
	adc	eax,0
708
	lea	ebx,[edx+eax*4]
709
	dec	ecx
710
	jnz	find_leave_for_symbol
711
	mov	edx,[ebx]
712
	or	edx,edx
713
	jz	add_symbol_entry
714
	shr	ebp,30
715
	cmp	ebp,11b
716
	je	reuse_symbol_entry
717
	cmp	dword [edx+4],0
718
	jne	add_symbol_entry
719
      find_entry_to_reuse:
31 halyavin 720
	mov	edi,[edx]
157 heavyiron 721
	or	edi,edi
722
	jz	reuse_symbol_entry
723
	cmp	dword [edi+4],0
724
	jne	reuse_symbol_entry
725
	mov	edx,edi
726
	jmp	find_entry_to_reuse
727
      add_symbol_entry:
31 halyavin 728
	mov	eax,edx
157 heavyiron 729
	mov	edx,[labels_list]
730
	sub	edx,16
731
	cmp	edx,[free_additional_memory]
732
	jb	out_of_memory
733
	mov	[labels_list],edx
734
	mov	[edx],eax
735
	mov	[ebx],edx
736
      reuse_symbol_entry:
31 halyavin 737
	pop	esi edi
157 heavyiron 738
	mov	[edx+4],esi
739
	ret
740
      extend_hashes_tree:
31 halyavin 741
	mov	edx,[labels_list]
157 heavyiron 742
	sub	edx,8
743
	cmp	edx,[free_additional_memory]
744
	jb	out_of_memory
745
	mov	[labels_list],edx
746
	xor	eax,eax
747
	mov	[edx],eax
748
	mov	[edx+4],eax
749
	shl	ebp,1
750
	adc	eax,0
751
	mov	[ebx],edx
752
	lea	ebx,[edx+eax*4]
753
	dec	ecx
754
	jnz	extend_hashes_tree
755
	mov	edx,[labels_list]
756
	sub	edx,16
757
	cmp	edx,[free_additional_memory]
758
	jb	out_of_memory
759
	mov	[labels_list],edx
760
	mov	dword [edx],0
761
	mov	[ebx],edx
762
	pop	esi edi
763
	mov	[edx+4],esi
764
	ret
765
31 halyavin 766
 
767
	add	edx,5
157 heavyiron 768
	add	esi,2
769
	push	edx
1189 heavyiron 770
	mov	ch,11b
157 heavyiron 771
	jmp	define_preprocessor_constant
772
define_equ_constant:
31 halyavin 773
	add	esi,3
157 heavyiron 774
	push	esi
775
	call	process_equ_constants
776
	mov	esi,[struc_name]
777
	mov	ch,10b
778
      define_preprocessor_constant:
109 heavyiron 779
	mov	byte [esi-2],3Bh
157 heavyiron 780
	mov	cl,[esi-1]
781
	call	add_preprocessor_symbol
782
	pop	ebx
1189 heavyiron 783
	mov	ecx,edi
157 heavyiron 784
	dec	ecx
785
	sub	ecx,ebx
786
	mov	[edx+8],ebx
787
	mov	[edx+12],ecx
788
	jmp	line_preprocessed
789
define_symbolic_constant:
109 heavyiron 790
	lods	byte [esi]
157 heavyiron 791
	cmp	al,1Ah
792
	jne	invalid_name
793
	lods	byte [esi]
794
	mov	cl,al
795
	mov	ch,10b
796
	call	add_preprocessor_symbol
797
	movzx	eax,byte [esi-1]
798
	add	esi,eax
799
	lea	ecx,[edi-1]
1189 heavyiron 800
	sub	ecx,esi
801
	mov	[edx+8],esi
802
	mov	[edx+12],ecx
157 heavyiron 803
	jmp	line_preprocessed
804
109 heavyiron 805
 
31 halyavin 806
	mov	ch,1
157 heavyiron 807
	jmp	make_macro
808
define_macro:
31 halyavin 809
	xor	ch,ch
157 heavyiron 810
      make_macro:
31 halyavin 811
	lods	byte [esi]
157 heavyiron 812
	cmp	al,1Ah
813
	jne	invalid_name
814
	lods	byte [esi]
815
	mov	cl,al
816
	call	add_preprocessor_symbol
817
	mov	eax,[current_line]
818
	mov	[edx+12],eax
819
	movzx	eax,byte [esi-1]
820
	add	esi,eax
821
	mov	[edx+8],esi
822
	mov	al,[macro_status]
823
	and	al,0F0h
824
	or	al,1
825
	mov	[macro_status],al
826
	mov	eax,[current_line]
827
	mov	[error_line],eax
828
	xor	bl,bl
829
	lods	byte [esi]
830
	or	al,al
831
	jz	line_preprocessed
832
	cmp	al,'{'
833
	je	found_macro_block
834
	dec	esi
835
      skip_macro_arguments:
31 halyavin 836
	lods	byte [esi]
157 heavyiron 837
	cmp	al,1Ah
838
	je	skip_macro_argument
839
	cmp	al,'['
840
	jne	invalid_macro_arguments
841
	xor	bl,-1
842
	jz	invalid_macro_arguments
843
	lods	byte [esi]
844
	cmp	al,1Ah
845
	jne	invalid_macro_arguments
846
      skip_macro_argument:
31 halyavin 847
	movzx	eax,byte [esi]
157 heavyiron 848
	inc	esi
849
	add	esi,eax
850
	lods	byte [esi]
851
	cmp	al,'*'
852
	jne	macro_argument_end
853
	lods	byte [esi]
854
      macro_argument_end:
31 halyavin 855
	cmp	al,','
157 heavyiron 856
	je	skip_macro_arguments
857
	cmp	al,']'
858
	jne	end_macro_arguments
859
	lods	byte [esi]
860
	not	bl
861
      end_macro_arguments:
31 halyavin 862
	or	bl,bl
157 heavyiron 863
	jnz	invalid_macro_arguments
864
	or	al,al
865
	jz	line_preprocessed
866
	cmp	al,'{'
867
	je	found_macro_block
868
	jmp	invalid_macro_arguments
869
      find_macro_block:
31 halyavin 870
	add	esi,2
157 heavyiron 871
	lods	byte [esi]
872
	or	al,al
873
	jz	line_preprocessed
874
	cmp	al,'{'
875
	jne	unexpected_characters
876
      found_macro_block:
31 halyavin 877
	or	[macro_status],2
157 heavyiron 878
      skip_macro_block:
31 halyavin 879
	lods	byte [esi]
157 heavyiron 880
	cmp	al,1Ah
881
	je	skip_macro_symbol
882
	cmp	al,3Bh
883
	je	skip_macro_symbol
884
	cmp	al,22h
885
	je	skip_macro_string
886
	or	al,al
887
	jz	line_preprocessed
888
	cmp	al,'}'
889
	jne	skip_macro_block
890
	mov	al,[macro_status]
891
	and	[macro_status],0F0h
892
	test	al,8
893
	jnz	use_instant_macro
894
	cmp	byte [esi],0
895
	je	line_preprocessed
896
	mov	ecx,edi
897
	sub	ecx,esi
898
	mov	edx,esi
899
	lea	esi,[esi+ecx-1]
900
	lea	edi,[edi+1+16]
901
	mov	ebx,edi
902
	dec	edi
903
	std
904
	rep	movs byte [edi],[esi]
905
	cld
906
	mov	edi,edx
907
	xor	al,al
908
	stos	byte [edi]
909
	mov	esi,[current_line]
910
	mov	[current_line],edi
911
	mov	ecx,4
912
	rep	movs dword [edi],[esi]
913
	mov	edi,ebx
914
	jmp	initial_preprocessing_ok
915
      skip_macro_symbol:
31 halyavin 916
	movzx	eax,byte [esi]
157 heavyiron 917
	inc	esi
918
	add	esi,eax
919
	jmp	skip_macro_block
920
      skip_macro_string:
31 halyavin 921
	lods	dword [esi]
157 heavyiron 922
	add	esi,eax
923
	jmp	skip_macro_block
924
rept_directive:
31 halyavin 925
	mov	[base_code],0
157 heavyiron 926
	jmp	define_instant_macro
927
irp_directive:
31 halyavin 928
	mov	[base_code],1
157 heavyiron 929
	jmp	define_instant_macro
930
irps_directive:
31 halyavin 931
	mov	[base_code],2
157 heavyiron 932
	jmp	define_instant_macro
933
match_directive:
31 halyavin 934
	mov	[base_code],10h
157 heavyiron 935
define_instant_macro:
31 halyavin 936
	mov	al,[macro_status]
157 heavyiron 937
	and	al,0F0h
938
	or	al,8+1
939
	mov	[macro_status],al
940
	mov	eax,[current_line]
941
	mov	[error_line],eax
942
	mov	[instant_macro_start],esi
943
	cmp	[base_code],10h
944
	je	prepare_match
945
      skip_parameters:
1189 heavyiron 946
	lods	byte [esi]
947
	or	al,al
948
	jz	parameters_skipped
949
	cmp	al,'{'
950
	je	parameters_skipped
951
	cmp	al,22h
952
	je	skip_quoted_parameter
953
	cmp	al,1Ah
954
	jne	skip_parameters
955
	lods	byte [esi]
956
	movzx	eax,al
957
	add	esi,eax
958
	jmp	skip_parameters
959
      skip_quoted_parameter:
960
	lods	dword [esi]
961
	add	esi,eax
962
	jmp	skip_parameters
963
      parameters_skipped:
964
	dec	esi
157 heavyiron 965
	mov	[parameters_end],esi
966
	lods	byte [esi]
967
	cmp	al,'{'
968
	je	found_macro_block
969
	or	al,al
970
	jnz	invalid_macro_arguments
971
	jmp	line_preprocessed
972
prepare_match:
31 halyavin 973
	call	skip_pattern
157 heavyiron 974
	mov	[value_type],80h+10b
975
	call	process_symbolic_constants
976
	jmp	parameters_skipped
1189 heavyiron 977
      skip_pattern:
31 halyavin 978
	lods	byte [esi]
157 heavyiron 979
	or	al,al
980
	jz	invalid_macro_arguments
981
	cmp	al,','
982
	je	pattern_skipped
983
	cmp	al,22h
984
	je	skip_quoted_string_in_pattern
985
	cmp	al,1Ah
986
	je	skip_symbol_in_pattern
987
	cmp	al,'='
988
	jne	skip_pattern
989
	mov	al,[esi]
990
	cmp	al,1Ah
991
	je	skip_pattern
992
	cmp	al,22h
993
	je	skip_pattern
994
	inc	esi
995
	jmp	skip_pattern
996
      skip_symbol_in_pattern:
31 halyavin 997
	lods	byte [esi]
157 heavyiron 998
	movzx	eax,al
999
	add	esi,eax
1000
	jmp	skip_pattern
1001
      skip_quoted_string_in_pattern:
31 halyavin 1002
	lods	dword [esi]
157 heavyiron 1003
	add	esi,eax
1004
	jmp	skip_pattern
1005
      pattern_skipped:
31 halyavin 1006
	ret
157 heavyiron 1007
31 halyavin 1008
 
1009
	xor	ch,ch
157 heavyiron 1010
	jmp	restore_preprocessor_symbol
1011
purge_struc:
31 halyavin 1012
	mov	ch,1
157 heavyiron 1013
	jmp	restore_preprocessor_symbol
1014
restore_equ_constant:
31 halyavin 1015
	mov	ch,10b
157 heavyiron 1016
      restore_preprocessor_symbol:
31 halyavin 1017
	push	ecx
157 heavyiron 1018
	lods	byte [esi]
1019
	cmp	al,1Ah
1020
	jne	invalid_name
1021
	lods	byte [esi]
1022
	mov	cl,al
1023
	call	get_preprocessor_symbol
1024
	jc	no_symbol_to_restore
1025
	mov	dword [edx+4],0
1026
	jmp	symbol_restored
1027
      no_symbol_to_restore:
31 halyavin 1028
	add	esi,ecx
157 heavyiron 1029
      symbol_restored:
31 halyavin 1030
	pop	ecx
157 heavyiron 1031
	lods	byte [esi]
1032
	cmp	al,','
1033
	je	restore_preprocessor_symbol
1034
	or	al,al
1035
	jnz	extra_characters_on_line
1036
	jmp	line_preprocessed
1037
31 halyavin 1038
 
1039
	mov	[value_type],11b
157 heavyiron 1040
	jmp	process_symbolic_constants
1041
process_equ_constants:
31 halyavin 1042
	mov	[value_type],10b
157 heavyiron 1043
      process_symbolic_constants:
31 halyavin 1044
	mov	ebp,esi
157 heavyiron 1045
	lods	byte [esi]
1046
	cmp	al,1Ah
1047
	je	check_symbol
1048
	cmp	al,22h
1049
	je	ignore_string
1050
	cmp	al,'{'
1051
	je	check_brace
1052
	or	al,al
1053
	jnz	process_symbolic_constants
1054
	ret
1055
      ignore_string:
31 halyavin 1056
	lods	dword [esi]
157 heavyiron 1057
	add	esi,eax
1058
	jmp	process_symbolic_constants
1059
      check_brace:
31 halyavin 1060
	test	[value_type],80h
157 heavyiron 1061
	jz	process_symbolic_constants
1062
	ret
1063
      no_replacing:
31 halyavin 1064
	movzx	ecx,byte [esi-1]
157 heavyiron 1065
	add	esi,ecx
1066
	jmp	process_symbolic_constants
1067
      check_symbol:
31 halyavin 1068
	mov	cl,[esi]
157 heavyiron 1069
	inc	esi
1070
	mov	ch,[value_type]
1071
	call	get_preprocessor_symbol
1072
	jc	no_replacing
1073
	mov	[current_section],edi
1074
      replace_symbolic_constant:
31 halyavin 1075
	mov	ecx,[edx+12]
157 heavyiron 1076
	mov	edx,[edx+8]
1077
	xchg	esi,edx
1078
	call	move_data
1079
	mov	esi,edx
1080
      process_after_replaced:
31 halyavin 1081
	lods	byte [esi]
157 heavyiron 1082
	cmp	al,1Ah
1083
	je	symbol_after_replaced
1084
	stos	byte [edi]
1085
	cmp	al,22h
1086
	je	string_after_replaced
1087
	cmp	al,'{'
1088
	je	brace_after_replaced
1089
	or	al,al
1090
	jnz	process_after_replaced
1091
	mov	ecx,edi
1092
	sub	ecx,esi
1093
	mov	edi,ebp
1094
	call	move_data
1095
	mov	esi,edi
1096
	ret
1097
      move_data:
31 halyavin 1098
	lea	eax,[edi+ecx]
157 heavyiron 1099
	cmp	eax,[memory_end]
1100
	jae	out_of_memory
1101
	shr	ecx,1
1102
	jnc	movsb_ok
1103
	movs	byte [edi],[esi]
1104
      movsb_ok:
31 halyavin 1105
	shr	ecx,1
157 heavyiron 1106
	jnc	movsw_ok
1107
	movs	word [edi],[esi]
1108
      movsw_ok:
31 halyavin 1109
	rep	movs dword [edi],[esi]
157 heavyiron 1110
	ret
1111
      string_after_replaced:
31 halyavin 1112
	lods	dword [esi]
157 heavyiron 1113
	stos	dword [edi]
1114
	mov	ecx,eax
1115
	call	move_data
1116
	jmp	process_after_replaced
1117
      brace_after_replaced:
31 halyavin 1118
	test	[value_type],80h
157 heavyiron 1119
	jz	process_after_replaced
1120
	mov	edx,edi
1121
	mov	ecx,[current_section]
1122
	sub	edx,ecx
1123
	sub	ecx,esi
1124
	rep	movs byte [edi],[esi]
1125
	mov	ecx,edi
1126
	sub	ecx,esi
1127
	mov	edi,ebp
1128
	call	move_data
1129
	lea	esi,[ebp+edx]
1130
	ret
1131
      symbol_after_replaced:
31 halyavin 1132
	mov	cl,[esi]
157 heavyiron 1133
	inc	esi
1134
	mov	ch,[value_type]
1135
	call	get_preprocessor_symbol
1136
	jnc	replace_symbolic_constant
1137
	movzx	ecx,byte [esi-1]
1138
	mov	al,1Ah
1139
	mov	ah,cl
1140
	stos	word [edi]
1141
	call	move_data
1142
	jmp	process_after_replaced
1143
process_macro_operators:
31 halyavin 1144
	xor	dl,dl
157 heavyiron 1145
	mov	ebp,edi
1146
      before_macro_operators:
31 halyavin 1147
	mov	edi,esi
157 heavyiron 1148
	lods	byte [esi]
1149
	cmp	al,'`'
1150
	je	symbol_conversion
1151
	cmp	al,'#'
1152
	je	concatenation
1153
	cmp	al,1Ah
1154
	je	symbol_before_macro_operators
1155
	cmp	al,3Bh
1156
	je	no_more_macro_operators
1157
	cmp	al,22h
1158
	je	string_before_macro_operators
1159
	xor	dl,dl
1160
	or	al,al
1161
	jnz	before_macro_operators
1162
	mov	edi,esi
1163
	ret
1164
      no_more_macro_operators:
31 halyavin 1165
	mov	edi,ebp
157 heavyiron 1166
	ret
1167
      symbol_before_macro_operators:
31 halyavin 1168
	mov	dl,1Ah
157 heavyiron 1169
	mov	ebx,esi
1170
	lods	byte [esi]
1171
	movzx	ecx,al
1172
	jecxz	symbol_before_macro_operators_ok
1173
	mov	edi,esi
1174
	cmp	byte [esi],'\'
1175
	je	escaped_symbol
1176
      symbol_before_macro_operators_ok:
31 halyavin 1177
	add	esi,ecx
157 heavyiron 1178
	jmp	before_macro_operators
1179
      string_before_macro_operators:
31 halyavin 1180
	mov	dl,22h
157 heavyiron 1181
	mov	ebx,esi
1182
	lods	dword [esi]
1183
	add	esi,eax
1184
	jmp	before_macro_operators
1185
      escaped_symbol:
31 halyavin 1186
	dec	byte [edi-1]
157 heavyiron 1187
	dec	ecx
1188
	inc	esi
1189
	cmp	ecx,1
1190
	rep	movs byte [edi],[esi]
1191
	jne	after_macro_operators
1192
	mov	al,[esi-1]
1193
	mov	ecx,ebx
1194
	mov	ebx,characters
1195
	xlat	byte [ebx]
1196
	mov	ebx,ecx
1197
	or	al,al
1198
	jnz	after_macro_operators
1199
	sub	edi,3
1200
	mov	al,[esi-1]
1201
	stos	byte [edi]
1202
	xor	dl,dl
1203
	jmp	after_macro_operators
1204
      reduce_symbol_conversion:
109 heavyiron 1205
	inc	esi
157 heavyiron 1206
      symbol_conversion:
31 halyavin 1207
	mov	edx,esi
157 heavyiron 1208
	mov	al,[esi]
1209
	cmp	al,1Ah
1210
	jne	symbol_character_conversion
1211
	lods	word [esi]
1212
	movzx	ecx,ah
1213
	lea	ebx,[edi+3]
1214
	jecxz	convert_to_quoted_string
242 heavyiron 1215
	cmp	byte [esi],'\'
1216
	jne	convert_to_quoted_string
1217
	inc	esi
1218
	dec	ecx
1219
	dec	ebx
1220
	jmp	convert_to_quoted_string
157 heavyiron 1221
      symbol_character_conversion:
109 heavyiron 1222
	cmp	al,22h
157 heavyiron 1223
	je	after_macro_operators
1224
	cmp	al,'`'
1225
	je	reduce_symbol_conversion
1226
	lea	ebx,[edi+5]
1227
	xor	ecx,ecx
1228
	or	al,al
1229
	jz	convert_to_quoted_string
1230
	cmp	al,'#'
1231
	je	convert_to_quoted_string
1232
	inc	ecx
1233
      convert_to_quoted_string:
109 heavyiron 1234
	sub	ebx,edx
157 heavyiron 1235
	ja	shift_line_data
1236
	mov	al,22h
1237
	mov	dl,al
1238
	stos	byte [edi]
1239
	mov	ebx,edi
1240
	mov	eax,ecx
1241
	stos	dword [edi]
1242
	rep	movs byte [edi],[esi]
1243
	cmp	edi,esi
1244
	je	before_macro_operators
1245
	jmp	after_macro_operators
1246
      shift_line_data:
31 halyavin 1247
	push	ecx
157 heavyiron 1248
	mov	edx,esi
1249
	lea	esi,[ebp-1]
1250
	add	ebp,ebx
1251
	lea	edi,[ebp-1]
1252
	lea	ecx,[esi+1]
1253
	sub	ecx,edx
1254
	std
1255
	rep	movs byte [edi],[esi]
1256
	cld
1257
	pop	eax
1258
	sub	edi,3
1259
	mov	dl,22h
1260
	mov	[edi-1],dl
1261
	mov	ebx,edi
1262
	mov	[edi],eax
1263
	lea	esi,[edi+4+eax]
1264
	jmp	before_macro_operators
1265
      concatenation:
31 halyavin 1266
	cmp	dl,1Ah
157 heavyiron 1267
	je	symbol_concatenation
1268
	cmp	dl,22h
1269
	je	string_concatenation
1270
      no_concatenation:
31 halyavin 1271
	cmp	esi,edi
157 heavyiron 1272
	je	before_macro_operators
1273
	jmp	after_macro_operators
1274
      symbol_concatenation:
31 halyavin 1275
	cmp	byte [esi],1Ah
157 heavyiron 1276
	jne	no_concatenation
1277
	inc	esi
1278
	lods	byte [esi]
1279
	movzx	ecx,al
1280
	jecxz	do_symbol_concatenation
1281
	cmp	byte [esi],'\'
1282
	je	concatenate_escaped_symbol
242 heavyiron 1283
      do_symbol_concatenation:
31 halyavin 1284
	add	[ebx],cl
242 heavyiron 1285
	jc	name_too_long
157 heavyiron 1286
	rep	movs byte [edi],[esi]
1287
	jmp	after_macro_operators
1288
      concatenate_escaped_symbol:
242 heavyiron 1289
	inc	esi
1290
	dec	ecx
1291
	jz	do_symbol_concatenation
1292
	movzx	eax,byte [esi]
1293
	cmp	byte [characters+eax],0
1294
	jne	do_symbol_concatenation
1295
	sub	esi,3
1296
	jmp	no_concatenation
1297
      string_concatenation:
31 halyavin 1298
	cmp	byte [esi],22h
157 heavyiron 1299
	je	do_string_concatenation
1300
	cmp	byte [esi],'`'
1301
	jne	no_concatenation
1302
      concatenate_converted_symbol:
109 heavyiron 1303
	inc	esi
157 heavyiron 1304
	mov	al,[esi]
1305
	cmp	al,'`'
1306
	je	concatenate_converted_symbol
1307
	cmp	al,22h
1308
	je	do_string_concatenation
1309
	cmp	al,1Ah
1310
	jne	concatenate_converted_symbol_character
1311
	inc	esi
1312
	lods	byte [esi]
1313
	movzx	ecx,al
1314
	jecxz	finish_concatenating_converted_symbol
242 heavyiron 1315
	cmp	byte [esi],'\'
1316
	jne	finish_concatenating_converted_symbol
1317
	inc	esi
1318
	dec	ecx
1319
      finish_concatenating_converted_symbol:
1320
	add	[ebx],ecx
157 heavyiron 1321
	rep	movs byte [edi],[esi]
1322
	jmp	after_macro_operators
1323
      concatenate_converted_symbol_character:
109 heavyiron 1324
	or	al,al
157 heavyiron 1325
	jz	after_macro_operators
1326
	cmp	al,'#'
1327
	je	after_macro_operators
1328
	inc	dword [ebx]
1329
	movs	byte [edi],[esi]
1330
	jmp	after_macro_operators
1331
      do_string_concatenation:
31 halyavin 1332
	inc	esi
157 heavyiron 1333
	lods	dword [esi]
1334
	mov	ecx,eax
1335
	add	[ebx],eax
1336
	rep	movs byte [edi],[esi]
1337
      after_macro_operators:
31 halyavin 1338
	lods	byte [esi]
157 heavyiron 1339
	cmp	al,'`'
1340
	je	symbol_conversion
1341
	cmp	al,'#'
1342
	je	concatenation
1343
	stos	byte [edi]
1344
	cmp	al,1Ah
1345
	je	symbol_after_macro_operators
1346
	cmp	al,3Bh
1347
	je	no_more_macro_operators
1348
	cmp	al,22h
1349
	je	string_after_macro_operators
1350
	xor	dl,dl
1351
	or	al,al
1352
	jnz	after_macro_operators
1353
	ret
1354
      symbol_after_macro_operators:
31 halyavin 1355
	mov	dl,1Ah
157 heavyiron 1356
	mov	ebx,edi
1357
	lods	byte [esi]
1358
	stos	byte [edi]
1359
	movzx	ecx,al
1360
	jecxz	symbol_after_macro_operatorss_ok
1361
	cmp	byte [esi],'\'
1362
	je	escaped_symbol
1363
      symbol_after_macro_operatorss_ok:
31 halyavin 1364
	rep	movs byte [edi],[esi]
157 heavyiron 1365
	jmp	after_macro_operators
1366
      string_after_macro_operators:
31 halyavin 1367
	mov	dl,22h
157 heavyiron 1368
	mov	ebx,edi
1369
	lods	dword [esi]
1370
	stos	dword [edi]
1371
	mov	ecx,eax
1372
	rep	movs byte [edi],[esi]
1373
	jmp	after_macro_operators
1374
31 halyavin 1375
 
1376
	push	[free_additional_memory]
157 heavyiron 1377
	push	[macro_symbols]
1378
	mov	[macro_symbols],0
1379
	push	[counter_limit]
1380
	push	dword [edx+4]
1381
	mov	dword [edx+4],1
1382
	push	edx
1383
	mov	ebx,esi
1384
	mov	esi,[edx+8]
1385
	mov	eax,[edx+12]
1386
	mov	[macro_line],eax
1387
	mov	[counter_limit],0
1388
      process_macro_arguments:
31 halyavin 1389
	mov	al,[esi]
157 heavyiron 1390
	or	al,al
1391
	jz	arguments_end
1392
	cmp	al,'{'
1393
	je	arguments_end
1394
	inc	esi
1395
	cmp	al,'['
1396
	jne	get_macro_arguments
1397
	mov	ebp,esi
1398
	inc	esi
1399
	inc	[counter_limit]
1400
      get_macro_arguments:
31 halyavin 1401
	call	get_macro_argument
157 heavyiron 1402
	lods	byte [esi]
1403
	cmp	al,','
1404
	je	next_argument
1405
	cmp	al,']'
1406
	je	next_arguments_group
1407
	dec	esi
1408
	jmp	arguments_end
1409
      next_argument:
31 halyavin 1410
	cmp	byte [ebx],','
157 heavyiron 1411
	jne	process_macro_arguments
1412
	inc	ebx
1413
	jmp	process_macro_arguments
1414
      next_arguments_group:
31 halyavin 1415
	cmp	byte [ebx],','
157 heavyiron 1416
	jne	arguments_end
1417
	inc	ebx
1418
	inc	[counter_limit]
1419
	mov	esi,ebp
1420
	jmp	process_macro_arguments
1421
      get_macro_argument:
31 halyavin 1422
	lods	byte [esi]
157 heavyiron 1423
	movzx	ecx,al
1424
	mov	eax,[counter_limit]
1425
	call	add_macro_symbol
1426
	add	esi,ecx
1427
	xchg	esi,ebx
1428
	mov	[edx+12],esi
1429
	cmp	byte [esi],'<'
1430
	jne	simple_argument
1431
	inc	esi
1432
	mov	[edx+12],esi
1433
	mov	ecx,1
1434
      enclosed_argument:
31 halyavin 1435
	lods	byte [esi]
157 heavyiron 1436
	or	al,al
1437
	jz	invalid_macro_arguments
1438
	cmp	al,1Ah
1439
	je	enclosed_symbol
1440
	cmp	al,22h
1441
	je	enclosed_string
1442
	cmp	al,'>'
1443
	je	enclosed_argument_end
1444
	cmp	al,'<'
1445
	jne	enclosed_argument
1446
	inc	ecx
1447
	jmp	enclosed_argument
1448
      enclosed_symbol:
31 halyavin 1449
	movzx	eax,byte [esi]
157 heavyiron 1450
	inc	esi
1451
	add	esi,eax
1452
	jmp	enclosed_argument
1453
      enclosed_string:
31 halyavin 1454
	lods	dword [esi]
157 heavyiron 1455
	add	esi,eax
1456
	jmp	enclosed_argument
1457
      enclosed_argument_end:
31 halyavin 1458
	loop	enclosed_argument
157 heavyiron 1459
	mov	al,[esi]
1460
	or	al,al
1461
	jz	enclosed_argument_ok
1462
	cmp	al,','
1463
	jne	invalid_macro_arguments
1464
      enclosed_argument_ok:
31 halyavin 1465
	mov	eax,esi
157 heavyiron 1466
	sub	eax,[edx+12]
1467
	dec	eax
1468
	or	eax,80000000h
1469
	mov	[edx+8],eax
1470
	jmp	argument_value_ok
1471
      simple_argument:
31 halyavin 1472
	lods	byte [esi]
157 heavyiron 1473
	or	al,al
1474
	jz	argument_value_end
1475
	cmp	al,','
1476
	je	argument_value_end
1477
	cmp	al,22h
1478
	je	argument_string
1479
	cmp	al,1Ah
1480
	jne	simple_argument
1481
	movzx	eax,byte [esi]
1482
	inc	esi
1483
	add	esi,eax
1484
	jmp	simple_argument
1485
      argument_string:
31 halyavin 1486
	lods	dword [esi]
157 heavyiron 1487
	add	esi,eax
1488
	jmp	simple_argument
1489
      argument_value_end:
31 halyavin 1490
	dec	esi
157 heavyiron 1491
	mov	eax,esi
1492
	sub	eax,[edx+12]
1493
	mov	[edx+8],eax
1494
      argument_value_ok:
31 halyavin 1495
	xchg	esi,ebx
157 heavyiron 1496
	cmp	byte [esi],'*'
1497
	jne	macro_argument_ok
1498
	cmp	dword [edx+8],0
1499
	je	invalid_macro_arguments
1500
	inc	esi
1501
      macro_argument_ok:
31 halyavin 1502
	ret
157 heavyiron 1503
      arguments_end:
31 halyavin 1504
	cmp	byte [ebx],0
157 heavyiron 1505
	jne	invalid_macro_arguments
1506
	mov	eax,[esp+4]
1507
	dec	eax
1508
	call	process_macro
1509
	pop	edx
1510
	pop	dword [edx+4]
1511
	pop	[counter_limit]
1512
	pop	[macro_symbols]
1513
	pop	[free_additional_memory]
1514
	jmp	line_preprocessed
1515
use_instant_macro:
31 halyavin 1516
	push	edi [current_line] esi
157 heavyiron 1517
	mov	eax,[error_line]
1518
	mov	[current_line],eax
1519
	mov	[macro_line],eax
1520
	mov	esi,[instant_macro_start]
1521
	cmp	[base_code],10h
1522
	jae	do_match
1523
	cmp	[base_code],0
1524
	jne	do_irp
1525
	call	precalculate_value
1189 heavyiron 1526
	cmp	eax,0
1527
	jl	value_out_of_range
1528
	push	[free_additional_memory]
157 heavyiron 1529
	push	[macro_symbols]
1530
	mov	[macro_symbols],0
1531
	push	[counter_limit]
1532
	mov	[struc_name],0
1533
	mov	[counter_limit],eax
1534
	lods	byte [esi]
1535
	or	al,al
1536
	jz	rept_counters_ok
1537
	cmp	al,'{'
1538
	je	rept_counters_ok
1539
	cmp	al,1Ah
1540
	jne	invalid_macro_arguments
1541
      add_rept_counter:
31 halyavin 1542
	lods	byte [esi]
157 heavyiron 1543
	movzx	ecx,al
1544
	xor	eax,eax
1545
	call	add_macro_symbol
1546
	add	esi,ecx
1547
	xor	eax,eax
1548
	mov	dword [edx+12],eax
1549
	inc	eax
1550
	mov	dword [edx+8],eax
1551
	lods	byte [esi]
1552
	cmp	al,':'
1553
	jne	rept_counter_added
1554
	push	edx
1555
	call	precalculate_value
1189 heavyiron 1556
	mov	edx,eax
157 heavyiron 1557
	add	edx,[counter_limit]
1558
	jo	value_out_of_range
1189 heavyiron 1559
	pop	edx
157 heavyiron 1560
	mov	dword [edx+8],eax
1561
	lods	byte [esi]
1562
      rept_counter_added:
31 halyavin 1563
	cmp	al,','
157 heavyiron 1564
	jne	rept_counters_ok
1565
	lods	byte [esi]
1566
	cmp	al,1Ah
1567
	jne	invalid_macro_arguments
1568
	jmp	add_rept_counter
1569
      rept_counters_ok:
31 halyavin 1570
	dec	esi
157 heavyiron 1571
	cmp	[counter_limit],0
872 heavyiron 1572
	je	instant_macro_finish
1573
      instant_macro_parameters_ok:
31 halyavin 1574
	xor	eax,eax
157 heavyiron 1575
	call	process_macro
1576
      instant_macro_finish:
872 heavyiron 1577
	pop	[counter_limit]
157 heavyiron 1578
	pop	[macro_symbols]
1579
	pop	[free_additional_memory]
1580
      instant_macro_done:
31 halyavin 1581
	pop	ebx esi edx
157 heavyiron 1582
	cmp	byte [ebx],0
1583
	je	line_preprocessed
1584
	mov	[current_line],edi
1585
	mov	ecx,4
1586
	rep	movs dword [edi],[esi]
1587
	test	[macro_status],0Fh
1588
	jz	instant_macro_attached_line
1589
	mov	ax,3Bh
1590
	stos	word [edi]
1591
      instant_macro_attached_line:
31 halyavin 1592
	mov	esi,ebx
157 heavyiron 1593
	sub	edx,ebx
1594
	mov	ecx,edx
1595
	call	move_data
1596
	jmp	initial_preprocessing_ok
1597
      precalculate_value:
1189 heavyiron 1598
	push	edi
1599
	call	convert_expression
1600
	mov	al,')'
1601
	stosb
1602
	push	esi
1603
	mov	esi,[esp+4]
1604
	mov	[value_size],8
2287 heavyiron 1605
	call	calculate_expression
1189 heavyiron 1606
	mov	eax,[edi]
1607
	mov	ecx,[edi+4]
1608
	pop	esi edi
1609
	cdq
1610
	cmp	edx,ecx
1611
	jne	value_out_of_range
1612
	ret
1613
do_irp:
31 halyavin 1614
	cmp	byte [esi],1Ah
157 heavyiron 1615
	jne	invalid_macro_arguments
1616
	movzx	eax,byte [esi+1]
1617
	lea	esi,[esi+2+eax]
1618
	lods	byte [esi]
1619
	cmp	[base_code],1
1620
	ja	irps_name_ok
1621
	cmp	al,'*'
1622
	jne	irp_name_ok
1623
	lods	byte [esi]
1624
      irp_name_ok:
31 halyavin 1625
	cmp	al,','
157 heavyiron 1626
	jne	invalid_macro_arguments
1627
	jmp	irp_parameters_start
1628
      irps_name_ok:
31 halyavin 1629
	cmp	al,','
157 heavyiron 1630
	jne	invalid_macro_arguments
1631
	mov	al,[esi]
1632
	or	al,al
1633
	jz	instant_macro_done
1634
	cmp	al,'{'
1635
	je	instant_macro_done
1636
      irp_parameters_start:
31 halyavin 1637
	xor	eax,eax
157 heavyiron 1638
	push	[free_additional_memory]
1639
	push	[macro_symbols]
1640
	mov	[macro_symbols],eax
1641
	push	[counter_limit]
1642
	mov	[counter_limit],eax
1643
	mov	[struc_name],eax
1644
	mov	ebx,esi
1645
	cmp	[base_code],1
1646
	ja	get_irps_parameter
1647
	mov	edx,[parameters_end]
1648
	mov	al,[edx]
1649
	push	eax
1650
	mov	byte [edx],0
1651
      get_irp_parameter:
31 halyavin 1652
	inc	[counter_limit]
157 heavyiron 1653
	mov	esi,[instant_macro_start]
1654
	inc	esi
1655
	call	get_macro_argument
1656
	cmp	byte [ebx],','
1657
	jne	irp_parameters_end
1658
	inc	ebx
1659
	jmp	get_irp_parameter
1660
      irp_parameters_end:
31 halyavin 1661
	mov	esi,ebx
157 heavyiron 1662
	pop	eax
1663
	mov	[esi],al
1664
	jmp	instant_macro_parameters_ok
1665
      get_irps_parameter:
31 halyavin 1666
	mov	esi,[instant_macro_start]
157 heavyiron 1667
	inc	esi
1668
	lods	byte [esi]
1669
	movzx	ecx,al
1670
	inc	[counter_limit]
1671
	mov	eax,[counter_limit]
1672
	call	add_macro_symbol
1673
	mov	[edx+12],ebx
1674
	cmp	byte [ebx],1Ah
1675
	je	irps_symbol
1676
	cmp	byte [ebx],22h
1677
	je	irps_quoted_string
1678
	mov	eax,1
1679
	jmp	irps_parameter_ok
1680
      irps_quoted_string:
31 halyavin 1681
	mov	eax,[ebx+1]
157 heavyiron 1682
	add	eax,1+4
1683
	jmp	irps_parameter_ok
1684
      irps_symbol:
31 halyavin 1685
	movzx	eax,byte [ebx+1]
157 heavyiron 1686
	add	eax,1+1
1687
      irps_parameter_ok:
31 halyavin 1688
	mov	[edx+8],eax
157 heavyiron 1689
	add	ebx,eax
1690
	cmp	byte [ebx],0
1691
	je	irps_parameters_end
1692
	cmp	byte [ebx],'{'
1693
	jne	get_irps_parameter
1694
      irps_parameters_end:
31 halyavin 1695
	mov	esi,ebx
157 heavyiron 1696
	jmp	instant_macro_parameters_ok
1697
do_match:
31 halyavin 1698
	mov	ebx,esi
157 heavyiron 1699
	call	skip_pattern
1700
	call	exact_match
1701
	mov	edx,edi
1702
	mov	al,[ebx]
1703
	cmp	al,1Ah
1704
	je	free_match
1705
	cmp	al,','
1706
	jne	instant_macro_done
1707
	cmp	esi,[parameters_end]
1708
	je	matched_pattern
1709
	jmp	instant_macro_done
1710
      free_match:
31 halyavin 1711
	add	edx,12
157 heavyiron 1712
	cmp	edx,[memory_end]
1713
	ja	out_of_memory
1714
	mov	[edx-12],ebx
1715
	mov	[edx-8],esi
1716
	call	skip_match_element
1717
	jc	try_different_matching
1718
	mov	[edx-4],esi
1719
	movzx	eax,byte [ebx+1]
1720
	lea	ebx,[ebx+2+eax]
1721
	cmp	byte [ebx],1Ah
1722
	je	free_match
1723
      find_exact_match:
31 halyavin 1724
	call	exact_match
157 heavyiron 1725
	cmp	esi,[parameters_end]
1726
	je	end_matching
1727
	cmp	byte [ebx],1Ah
1728
	je	free_match
1729
	mov	ebx,[edx-12]
1730
	movzx	eax,byte [ebx+1]
1731
	lea	ebx,[ebx+2+eax]
1732
	mov	esi,[edx-4]
1733
	jmp	match_more_elements
1734
      try_different_matching:
31 halyavin 1735
	sub	edx,12
157 heavyiron 1736
	cmp	edx,edi
1737
	je	instant_macro_done
1738
	mov	ebx,[edx-12]
1739
	movzx	eax,byte [ebx+1]
1740
	lea	ebx,[ebx+2+eax]
1741
	cmp	byte [ebx],1Ah
1742
	je	try_different_matching
1743
	mov	esi,[edx-4]
1744
      match_more_elements:
31 halyavin 1745
	call	skip_match_element
157 heavyiron 1746
	jc	try_different_matching
1747
	mov	[edx-4],esi
1748
	jmp	find_exact_match
1749
      skip_match_element:
31 halyavin 1750
	cmp	esi,[parameters_end]
157 heavyiron 1751
	je	cannot_match
1752
	mov	al,[esi]
1753
	cmp	al,1Ah
1754
	je	skip_match_symbol
1755
	cmp	al,22h
1756
	je	skip_match_quoted_string
1757
	add	esi,1
1758
	ret
1759
      skip_match_quoted_string:
31 halyavin 1760
	mov	eax,[esi+1]
157 heavyiron 1761
	add	esi,5
1762
	jmp	skip_match_ok
1763
      skip_match_symbol:
31 halyavin 1764
	movzx	eax,byte [esi+1]
157 heavyiron 1765
	add	esi,2
1766
      skip_match_ok:
31 halyavin 1767
	add	esi,eax
157 heavyiron 1768
	ret
1769
      cannot_match:
31 halyavin 1770
	stc
157 heavyiron 1771
	ret
1772
      exact_match:
31 halyavin 1773
	cmp	esi,[parameters_end]
157 heavyiron 1774
	je	exact_match_complete
1775
	mov	ah,[esi]
1776
	mov	al,[ebx]
1777
	cmp	al,','
1778
	je	exact_match_complete
1779
	cmp	al,1Ah
1780
	je	exact_match_complete
1781
	cmp	al,'='
1782
	je	match_verbatim
1783
	call	match_elements
1784
	je	exact_match
1785
      exact_match_complete:
31 halyavin 1786
	ret
157 heavyiron 1787
      match_verbatim:
31 halyavin 1788
	inc	ebx
157 heavyiron 1789
	call	match_elements
1790
	je	exact_match
1791
	dec	ebx
1792
	ret
1793
      match_elements:
31 halyavin 1794
	mov	al,[ebx]
157 heavyiron 1795
	cmp	al,1Ah
1796
	je	match_symbols
1797
	cmp	al,22h
1798
	je	match_quoted_strings
1799
	cmp	al,ah
1800
	je	symbol_characters_matched
1801
	ret
1802
      symbol_characters_matched:
31 halyavin 1803
	lea	ebx,[ebx+1]
157 heavyiron 1804
	lea	esi,[esi+1]
1805
	ret
1806
      match_quoted_strings:
31 halyavin 1807
	mov	ecx,[ebx+1]
157 heavyiron 1808
	add	ecx,5
1809
	jmp	compare_elements
1810
      match_symbols:
31 halyavin 1811
	movzx	ecx,byte [ebx+1]
157 heavyiron 1812
	add	ecx,2
1813
      compare_elements:
31 halyavin 1814
	mov	eax,esi
157 heavyiron 1815
	mov	ebp,edi
1816
	mov	edi,ebx
1817
	repe	cmps byte [esi],[edi]
1818
	jne	elements_mismatch
1819
	mov	ebx,edi
1820
	mov	edi,ebp
1821
	ret
1822
      elements_mismatch:
31 halyavin 1823
	mov	esi,eax
157 heavyiron 1824
	mov	edi,ebp
1825
	ret
1826
      end_matching:
31 halyavin 1827
	cmp	byte [ebx],','
157 heavyiron 1828
	jne	instant_macro_done
1829
      matched_pattern:
31 halyavin 1830
	xor	eax,eax
157 heavyiron 1831
	push	[free_additional_memory]
1832
	push	[macro_symbols]
1833
	mov	[macro_symbols],eax
1834
	push	[counter_limit]
1835
	mov	[counter_limit],eax
1836
	mov	[struc_name],eax
1837
	push	esi edi edx
1838
      add_matched_symbol:
31 halyavin 1839
	cmp	edi,[esp]
157 heavyiron 1840
	je	matched_symbols_ok
1841
	mov	esi,[edi]
1842
	inc	esi
1843
	lods	byte [esi]
1844
	movzx	ecx,al
1845
	xor	eax,eax
1846
	call	add_macro_symbol
1847
	mov	eax,[edi+4]
1848
	mov	dword [edx+12],eax
1849
	mov	ecx,[edi+8]
1850
	sub	ecx,eax
1851
	mov	dword [edx+8],ecx
1852
	add	edi,12
1853
	jmp	add_matched_symbol
1854
      matched_symbols_ok:
31 halyavin 1855
	pop	edx edi esi
157 heavyiron 1856
	jmp	instant_macro_parameters_ok
1857
31 halyavin 1858
 
1859
	push	dword [macro_status]
157 heavyiron 1860
	or	[macro_status],10h
1861
	push	[counter]
1862
	push	[macro_block]
1863
	push	[macro_block_line]
1864
	push	[macro_block_line_number]
1865
	push	[struc_label]
1866
	push	[struc_name]
1867
	push	eax
1868
	push	[current_line]
1869
	lods	byte [esi]
1870
	cmp	al,'{'
1871
	je	macro_instructions_start
1872
	or	al,al
1873
	jnz	unexpected_characters
1874
      find_macro_instructions:
31 halyavin 1875
	mov	[macro_line],esi
157 heavyiron 1876
	add	esi,16+2
1877
	lods	byte [esi]
1878
	or	al,al
1879
	jz	find_macro_instructions
1880
	cmp	al,'{'
1881
	je	macro_instructions_start
1882
	cmp	al,3Bh
1883
	jne	unexpected_characters
1884
	call	skip_foreign_symbol
1885
	jmp	find_macro_instructions
1886
      macro_instructions_start:
31 halyavin 1887
	mov	ecx,80000000h
157 heavyiron 1888
	mov	[macro_block],esi
1889
	mov	eax,[macro_line]
1890
	mov	[macro_block_line],eax
1891
	mov	[macro_block_line_number],ecx
1892
	xor	eax,eax
1893
	mov	[counter],eax
1894
	cmp	[counter_limit],eax
1895
	je	process_macro_line
1896
	inc	[counter]
1897
      process_macro_line:
31 halyavin 1898
	lods	byte [esi]
2287 heavyiron 1899
	or	al,al
1900
	jz	process_next_line
1901
	cmp	al,'}'
1902
	je	macro_block_processed
1903
	dec	esi
1904
	mov	[current_line],edi
157 heavyiron 1905
	lea	eax,[edi+10h]
1906
	cmp	eax,[memory_end]
1907
	jae	out_of_memory
1908
	mov	eax,[esp+4]
1909
	or	eax,eax
1910
	jz	instant_macro_line_header
1911
	stos	dword [edi]
1912
	mov	eax,ecx
1913
	stos	dword [edi]
1914
	mov	eax,[esp]
1915
	stos	dword [edi]
1916
	mov	eax,[macro_line]
1917
	stos	dword [edi]
1918
	jmp	macro_line_header_ok
1919
      instant_macro_line_header:
31 halyavin 1920
	mov	eax,[macro_line]
992 heavyiron 1921
	add	eax,16+1
1922
	stos	dword [edi]
157 heavyiron 1923
	mov	eax,ecx
992 heavyiron 1924
	stos	dword [edi]
157 heavyiron 1925
	mov	eax,[macro_line]
992 heavyiron 1926
	stos	dword [edi]
157 heavyiron 1927
	stos	dword [edi]
1928
      macro_line_header_ok:
31 halyavin 1929
	or	[macro_status],20h
157 heavyiron 1930
	push	ebx ecx
1931
	test	[macro_status],0Fh
1932
	jz	process_macro_line_element
1933
	mov	ax,3Bh
1934
	stos	word [edi]
1935
      process_macro_line_element:
31 halyavin 1936
	lea	eax,[edi+100h]
157 heavyiron 1937
	cmp	eax,[memory_end]
1938
	jae	out_of_memory
1939
	lods	byte [esi]
1940
	cmp	al,'}'
1941
	je	macro_line_processed
1942
	or	al,al
1943
	jz	macro_line_processed
1944
	cmp	al,1Ah
1945
	je	process_macro_symbol
1946
	cmp	al,3Bh
1947
	je	macro_foreign_line
1948
	and	[macro_status],not 20h
1949
	stos	byte [edi]
1950
	cmp	al,22h
1951
	jne	process_macro_line_element
1952
      copy_macro_string:
31 halyavin 1953
	mov	ecx,[esi]
157 heavyiron 1954
	add	ecx,4
1955
	call	move_data
1956
	jmp	process_macro_line_element
1957
      process_macro_symbol:
31 halyavin 1958
	push	esi edi
157 heavyiron 1959
	test	[macro_status],20h
1960
	jz	not_macro_directive
1961
	movzx	ecx,byte [esi]
1962
	inc	esi
1963
	mov	edi,macro_directives
1964
	call	get_directive
1965
	jnc	process_macro_directive
1966
	dec	esi
1967
	jmp	not_macro_directive
1968
      process_macro_directive:
31 halyavin 1969
	mov	edx,eax
157 heavyiron 1970
	pop	edi eax
1971
	mov	byte [edi],0
1972
	inc	edi
1973
	pop	ecx ebx
1974
	jmp	near edx
1975
      not_macro_directive:
31 halyavin 1976
	and	[macro_status],not 20h
157 heavyiron 1977
	movzx	ecx,byte [esi]
1978
	inc	esi
1979
	mov	eax,[counter]
1980
	call	get_macro_symbol
1981
	jnc	group_macro_symbol
1982
	xor	eax,eax
1983
	cmp	[counter],eax
1984
	je	multiple_macro_symbol_values
1985
	call	get_macro_symbol
1986
	jc	not_macro_symbol
1987
      replace_macro_symbol:
31 halyavin 1988
	pop	edi eax
157 heavyiron 1989
	mov	ecx,[edx+8]
1990
	mov	edx,[edx+12]
1991
	or	edx,edx
1992
	jz	replace_macro_counter
1993
	and	ecx,not 80000000h
1189 heavyiron 1994
	xchg	esi,edx
157 heavyiron 1995
	call	move_data
1996
	mov	esi,edx
1997
	jmp	process_macro_line_element
1998
      group_macro_symbol:
31 halyavin 1999
	xor	eax,eax
157 heavyiron 2000
	cmp	[counter],eax
2001
	je	replace_macro_symbol
2002
	push	esi edx
2003
	sub	esi,ecx
2004
	call	get_macro_symbol
2005
	mov	ebx,edx
2006
	pop	edx esi
2007
	jc	replace_macro_symbol
2008
	cmp	edx,ebx
2009
	ja	replace_macro_symbol
2010
	mov	edx,ebx
2011
	jmp	replace_macro_symbol
2012
      multiple_macro_symbol_values:
31 halyavin 2013
	inc	eax
157 heavyiron 2014
	push	eax
2015
	call	get_macro_symbol
2016
	pop	eax
2017
	jc	not_macro_symbol
2018
	pop	edi
2019
	push	ecx
2020
	mov	ecx,[edx+8]
2021
	mov	edx,[edx+12]
2022
	xchg	esi,edx
2023
	btr	ecx,31
2024
	jc	enclose_macro_symbol_value
2025
	rep	movs byte [edi],[esi]
2026
	jmp	macro_symbol_value_ok
2027
      enclose_macro_symbol_value:
31 halyavin 2028
	mov	byte [edi],'<'
157 heavyiron 2029
	inc	edi
2030
	rep	movs byte [edi],[esi]
2031
	mov	byte [edi],'>'
2032
	inc	edi
2033
      macro_symbol_value_ok:
31 halyavin 2034
	cmp	eax,[counter_limit]
157 heavyiron 2035
	je	multiple_macro_symbol_values_ok
2036
	mov	byte [edi],','
2037
	inc	edi
2038
	mov	esi,edx
2039
	pop	ecx
2040
	push	edi
2041
	sub	esi,ecx
2042
	jmp	multiple_macro_symbol_values
2043
      multiple_macro_symbol_values_ok:
31 halyavin 2044
	pop	ecx eax
157 heavyiron 2045
	mov	esi,edx
2046
	jmp	process_macro_line_element
2047
      replace_macro_counter:
31 halyavin 2048
	mov	eax,[counter]
157 heavyiron 2049
	and	eax,not 80000000h
2050
	jz	group_macro_counter
2051
	add	ecx,eax
2052
	dec	ecx
2053
	call	store_number_symbol
2054
	jmp	process_macro_line_element
2055
      group_macro_counter:
31 halyavin 2056
	mov	edx,ecx
157 heavyiron 2057
	xor	ecx,ecx
2058
      multiple_macro_counter_values:
31 halyavin 2059
	push	ecx edx
157 heavyiron 2060
	add	ecx,edx
2061
	call	store_number_symbol
2062
	pop	edx ecx
2063
	inc	ecx
2064
	cmp	ecx,[counter_limit]
2065
	je	process_macro_line_element
2066
	mov	byte [edi],','
2067
	inc	edi
2068
	jmp	multiple_macro_counter_values
2069
      store_number_symbol:
31 halyavin 2070
	cmp	ecx,0
1189 heavyiron 2071
	jge	numer_symbol_sign_ok
2072
	neg	ecx
2073
	mov	al,'-'
2074
	stos	byte [edi]
2075
      numer_symbol_sign_ok:
2076
	mov	ax,1Ah
157 heavyiron 2077
	stos	word [edi]
2078
	push	edi
2079
	mov	eax,ecx
2080
	mov	ecx,1000000000
2081
	xor	edx,edx
2082
	xor	bl,bl
2083
      store_number_digits:
31 halyavin 2084
	div	ecx
157 heavyiron 2085
	push	edx
2086
	or	bl,bl
2087
	jnz	store_number_digit
2088
	cmp	ecx,1
2089
	je	store_number_digit
2090
	or	al,al
2091
	jz	number_digit_ok
2092
	not	bl
2093
      store_number_digit:
31 halyavin 2094
	add	al,30h
157 heavyiron 2095
	stos	byte [edi]
2096
      number_digit_ok:
31 halyavin 2097
	mov	eax,ecx
157 heavyiron 2098
	xor	edx,edx
2099
	mov	ecx,10
2100
	div	ecx
2101
	mov	ecx,eax
2102
	pop	eax
2103
	or	ecx,ecx
2104
	jnz	store_number_digits
2105
	pop	ebx
2106
	mov	eax,edi
2107
	sub	eax,ebx
2108
	mov	[ebx-1],al
2109
	ret
2110
      not_macro_symbol:
31 halyavin 2111
	pop	edi esi
157 heavyiron 2112
	mov	al,1Ah
2113
	stos	byte [edi]
2114
	mov	al,[esi]
2115
	inc	esi
2116
	stos	byte [edi]
2117
	cmp	byte [esi],'.'
2118
	jne	copy_raw_symbol
2119
	mov	ebx,[esp+8+8]
2120
	or	ebx,ebx
2121
	jz	copy_raw_symbol
2122
	cmp	al,1
2123
	je	copy_struc_name
2124
	xchg	esi,ebx
2125
	movzx	ecx,byte [esi-1]
2126
	add	[edi-1],cl
2127
	jc	name_too_long
2128
	rep	movs byte [edi],[esi]
2129
	xchg	esi,ebx
2130
      copy_raw_symbol:
31 halyavin 2131
	movzx	ecx,al
157 heavyiron 2132
	rep	movs byte [edi],[esi]
2133
	jmp	process_macro_line_element
2134
      copy_struc_name:
31 halyavin 2135
	inc	esi
157 heavyiron 2136
	xchg	esi,ebx
2137
	movzx	ecx,byte [esi-1]
2138
	mov	[edi-1],cl
2139
	rep	movs byte [edi],[esi]
2140
	xchg	esi,ebx
2141
	mov	eax,[esp+8+12]
2142
	cmp	byte [eax],3Bh
2143
	je	process_macro_line_element
2144
	cmp	byte [eax],1Ah
2145
	jne	disable_replaced_struc_name
2146
	mov	byte [eax],3Bh
2147
	jmp	process_macro_line_element
2148
      disable_replaced_struc_name:
31 halyavin 2149
	mov	ebx,[esp+8+8]
157 heavyiron 2150
	push	esi edi
2151
	lea	edi,[ebx-3]
2152
	lea	esi,[edi-2]
2153
	lea	ecx,[esi+1]
2154
	sub	ecx,eax
2155
	std
2156
	rep	movs byte [edi],[esi]
2157
	cld
2158
	mov	word [eax],3Bh
2159
	pop	edi esi
2160
	jmp	process_macro_line_element
2161
      skip_foreign_symbol:
31 halyavin 2162
	lods	byte [esi]
157 heavyiron 2163
	movzx	eax,al
2164
	add	esi,eax
2165
      skip_foreign_line:
31 halyavin 2166
	lods	byte [esi]
157 heavyiron 2167
	cmp	al,1Ah
2168
	je	skip_foreign_symbol
2169
	cmp	al,3Bh
2170
	je	skip_foreign_symbol
2171
	cmp	al,22h
2172
	je	skip_foreign_string
2173
	or	al,al
2174
	jnz	skip_foreign_line
2175
	ret
2176
      skip_foreign_string:
31 halyavin 2177
	lods	dword [esi]
157 heavyiron 2178
	add	esi,eax
2179
	jmp	skip_foreign_line
2180
      macro_foreign_line:
31 halyavin 2181
	call	skip_foreign_symbol
157 heavyiron 2182
      macro_line_processed:
31 halyavin 2183
	mov	byte [edi],0
157 heavyiron 2184
	inc	edi
2185
	push	eax
2186
	call	preprocess_line
2187
	pop	eax
2188
	pop	ecx ebx
2189
	cmp	al,'}'
2190
	je	macro_block_processed
2191
      process_next_line:
31 halyavin 2192
	inc	ecx
157 heavyiron 2193
	mov	[macro_line],esi
2194
	add	esi,16+2
2195
	jmp	process_macro_line
2196
      macro_block_processed:
31 halyavin 2197
	call	close_macro_block
157 heavyiron 2198
	jc	process_macro_line
2199
	pop	[current_line]
2200
	add	esp,12
2201
	pop	[macro_block_line_number]
2202
	pop	[macro_block_line]
2203
	pop	[macro_block]
2204
	pop	[counter]
2205
	pop	eax
2206
	and	al,0F0h
2207
	and	[macro_status],0Fh
2208
	or	[macro_status],al
2209
	ret
2210
31 halyavin 2211
 
2212
	lods	byte [esi]
157 heavyiron 2213
	cmp	al,1Ah
2214
	jne	invalid_argument
2215
	mov	byte [edi-1],3Bh
2216
	xor	al,al
2217
	stos	byte [edi]
2218
      make_local_symbol:
31 halyavin 2219
	push	ecx
157 heavyiron 2220
	lods	byte [esi]
2221
	movzx	ecx,al
2222
	mov	eax,[counter]
2223
	call	add_macro_symbol
2224
	mov	[edx+12],edi
2225
	movzx	eax,[locals_counter]
2226
	add	eax,ecx
2227
	inc	eax
2228
	cmp	eax,100h
2229
	jae	name_too_long
2230
	lea	ebp,[edi+2+eax]
2231
	cmp	ebp,[memory_end]
2232
	jae	out_of_memory
2233
	mov	ah,al
2234
	mov	al,1Ah
2235
	stos	word [edi]
2236
	rep	movs byte [edi],[esi]
2237
	mov	al,'?'
2238
	stos	byte [edi]
2239
	push	esi
2240
	mov	esi,locals_counter+1
2241
	movzx	ecx,[locals_counter]
2242
	rep	movs byte [edi],[esi]
2243
	pop	esi
2244
	mov	eax,edi
2245
	sub	eax,[edx+12]
2246
	mov	[edx+8],eax
2247
	xor	al,al
2248
	stos	byte [edi]
2249
	mov	eax,locals_counter
2250
	movzx	ecx,byte [eax]
2251
      counter_loop:
31 halyavin 2252
	inc	byte [eax+ecx]
157 heavyiron 2253
	cmp	byte [eax+ecx],'9'+1
692 heavyiron 2254
	jb	counter_ok
157 heavyiron 2255
	jne	letter_digit
2256
	mov	byte [eax+ecx],'A'
2257
	jmp	counter_ok
2258
      letter_digit:
31 halyavin 2259
	cmp	byte [eax+ecx],'Z'+1
692 heavyiron 2260
	jb	counter_ok
2261
	jne	small_letter_digit
2262
	mov	byte [eax+ecx],'a'
2263
	jmp	counter_ok
2264
      small_letter_digit:
2265
	cmp	byte [eax+ecx],'z'+1
2266
	jb	counter_ok
2267
	mov	byte [eax+ecx],'0'
157 heavyiron 2268
	loop	counter_loop
2269
	inc	byte [eax]
692 heavyiron 2270
	movzx	ecx,byte [eax]
2271
	mov	byte [eax+ecx],'0'
2272
      counter_ok:
31 halyavin 2273
	pop	ecx
157 heavyiron 2274
	lods	byte [esi]
2275
	cmp	al,'}'
2276
	je	macro_block_processed
2277
	or	al,al
2278
	jz	process_next_line
2279
	cmp	al,','
2280
	jne	extra_characters_on_line
2281
	dec	edi
2282
	lods	byte [esi]
2283
	cmp	al,1Ah
2284
	je	make_local_symbol
2285
	jmp	invalid_argument
2286
common_block:
31 halyavin 2287
	call	close_macro_block
157 heavyiron 2288
	jc	process_macro_line
2289
	mov	[counter],0
2290
	jmp	new_macro_block
2291
forward_block:
31 halyavin 2292
	cmp	[counter_limit],0
157 heavyiron 2293
	je	common_block
2294
	call	close_macro_block
2295
	jc	process_macro_line
2296
	mov	[counter],1
2297
	jmp	new_macro_block
2298
reverse_block:
31 halyavin 2299
	cmp	[counter_limit],0
157 heavyiron 2300
	je	common_block
2301
	call	close_macro_block
2302
	jc	process_macro_line
2303
	mov	eax,[counter_limit]
2304
	or	eax,80000000h
2305
	mov	[counter],eax
2306
      new_macro_block:
31 halyavin 2307
	mov	[macro_block],esi
157 heavyiron 2308
	mov	eax,[macro_line]
2309
	mov	[macro_block_line],eax
2310
	mov	[macro_block_line_number],ecx
2311
	jmp	process_macro_line
2312
close_macro_block:
31 halyavin 2313
	cmp	[counter],0
157 heavyiron 2314
	je	block_closed
2315
	jl	reverse_counter
2316
	mov	eax,[counter]
2317
	cmp	eax,[counter_limit]
2318
	je	block_closed
2319
	inc	[counter]
2320
	jmp	continue_block
2321
      reverse_counter:
31 halyavin 2322
	mov	eax,[counter]
157 heavyiron 2323
	dec	eax
2324
	cmp	eax,80000000h
2325
	je	block_closed
2326
	mov	[counter],eax
2327
      continue_block:
31 halyavin 2328
	mov	esi,[macro_block]
157 heavyiron 2329
	mov	eax,[macro_block_line]
2330
	mov	[macro_line],eax
2331
	mov	ecx,[macro_block_line_number]
2332
	stc
2333
	ret
2334
      block_closed:
31 halyavin 2335
	clc
157 heavyiron 2336
	ret
2337
get_macro_symbol:
31 halyavin 2338
	push	ecx
157 heavyiron 2339
	call	find_macro_symbol_leaf
2340
	jc	macro_symbol_not_found
2341
	mov	edx,[ebx]
2342
	mov	ebx,esi
2343
      try_macro_symbol:
31 halyavin 2344
	or	edx,edx
157 heavyiron 2345
	jz	macro_symbol_not_found
2346
	mov	ecx,[esp]
2347
	mov	edi,[edx+4]
2348
	repe	cmps byte [esi],[edi]
2349
	je	macro_symbol_found
2350
	mov	esi,ebx
2351
	mov	edx,[edx]
2352
	jmp	try_macro_symbol
2353
      macro_symbol_found:
31 halyavin 2354
	pop	ecx
157 heavyiron 2355
	clc
2356
	ret
2357
      macro_symbol_not_found:
31 halyavin 2358
	pop	ecx
157 heavyiron 2359
	stc
2360
	ret
2361
      find_macro_symbol_leaf:
31 halyavin 2362
	shl	eax,8
157 heavyiron 2363
	mov	al,cl
2364
	mov	ebp,eax
2365
	mov	ebx,macro_symbols
2366
      follow_macro_symbols_tree:
31 halyavin 2367
	mov	edx,[ebx]
157 heavyiron 2368
	or	edx,edx
2369
	jz	no_such_macro_symbol
2370
	xor	eax,eax
2371
	shr	ebp,1
2372
	adc	eax,0
2373
	lea	ebx,[edx+eax*4]
2374
	or	ebp,ebp
2375
	jnz	follow_macro_symbols_tree
2376
	add	ebx,8
2377
	clc
2378
	ret
2379
      no_such_macro_symbol:
31 halyavin 2380
	stc
157 heavyiron 2381
	ret
2382
add_macro_symbol:
31 halyavin 2383
	push	ebx ebp
157 heavyiron 2384
	call	find_macro_symbol_leaf
2385
	jc	extend_macro_symbol_tree
2386
	mov	eax,[ebx]
2387
      make_macro_symbol:
31 halyavin 2388
	mov	edx,[free_additional_memory]
157 heavyiron 2389
	add	edx,16
2390
	cmp	edx,[labels_list]
2391
	ja	out_of_memory
2392
	xchg	edx,[free_additional_memory]
2393
	mov	[ebx],edx
2394
	mov	[edx],eax
2395
	mov	[edx+4],esi
2396
	pop	ebp ebx
2397
	ret
2398
      extend_macro_symbol_tree:
31 halyavin 2399
	mov	edx,[free_additional_memory]
157 heavyiron 2400
	add	edx,16
2401
	cmp	edx,[labels_list]
2402
	ja	out_of_memory
2403
	xchg	edx,[free_additional_memory]
2404
	xor	eax,eax
2405
	mov	[edx],eax
2406
	mov	[edx+4],eax
2407
	mov	[edx+8],eax
2408
	mov	[edx+12],eax
2409
	shr	ebp,1
2410
	adc	eax,0
2411
	mov	[ebx],edx
2412
	lea	ebx,[edx+eax*4]
2413
	or	ebp,ebp
2414
	jnz	extend_macro_symbol_tree
2415
	add	ebx,8
2416
	xor	eax,eax
2417
	jmp	make_macro_symbol
2418
31 halyavin 2419
 
2420
	lods	byte [esi]
157 heavyiron 2421
	cmp	al,22h
2422
	jne	invalid_argument
2423
	lods	dword [esi]
2424
	cmp	byte [esi+eax],0
2425
	jne	extra_characters_on_line
2426
	push	esi
2427
	push	edi
2428
	mov	ebx,[current_line]
2429
      find_current_file_path:
31 halyavin 2430
	mov	esi,[ebx]
157 heavyiron 2431
	test	byte [ebx+7],80h
2432
	jz	copy_current_file_path
2433
	mov	ebx,[ebx+8]
2434
	jmp	find_current_file_path
2435
      copy_current_file_path:
31 halyavin 2436
	lods	byte [esi]
157 heavyiron 2437
	stos	byte [edi]
2438
	or	al,al
2439
	jnz	copy_current_file_path
2440
      cut_current_file_name:
31 halyavin 2441
	cmp	edi,[esp]
157 heavyiron 2442
	je	current_file_path_ok
2443
	cmp	byte [edi-1],'\'
2444
	je	current_file_path_ok
2445
	cmp	byte [edi-1],'/'
2446
	je	current_file_path_ok
2447
	dec	edi
2448
	jmp	cut_current_file_name
2449
      current_file_path_ok:
31 halyavin 2450
	mov	esi,[esp+4]
157 heavyiron 2451
	call	preprocess_path
2452
	pop	edx
2453
	mov	esi,edx
2454
	call	open
2455
	jnc	include_path_ok
2456
	mov	ebp,[include_paths]
2457
      try_include_directories:
31 halyavin 2458
	mov	edi,esi
157 heavyiron 2459
	mov	esi,ebp
2460
	cmp	byte [esi],0
2461
	je	try_in_current_directory
2462
	push	ebp
2463
	push	edi
2464
      copy_include_directory:
31 halyavin 2465
	lods	byte [esi]
157 heavyiron 2466
	cmp	al,';'
2467
	je	include_directory_ok
2468
	stos	byte [edi]
2469
	or	al,al
2470
	jnz	copy_include_directory
2471
	dec	esi
2472
	dec	edi
2473
      include_directory_ok:
31 halyavin 2474
	cmp	byte [edi-1],'/'
157 heavyiron 2475
	je	path_separator_ok
2476
	cmp	byte [edi-1],'\'
2477
	je	path_separator_ok
2478
	mov	al,'/'
2479
	stos	byte [edi]
2480
      path_separator_ok:
31 halyavin 2481
	mov	[esp+4],esi
157 heavyiron 2482
	mov	esi,[esp+8]
2483
	call	preprocess_path
2484
	pop	edx
2485
	mov	esi,edx
2486
	call	open
2487
	pop	ebp
2488
	jnc	include_path_ok
2489
	jmp	try_include_directories
2490
	mov	edi,esi
2491
      try_in_current_directory:
31 halyavin 2492
	mov	esi,[esp]
157 heavyiron 2493
	push	edi
2494
	call	preprocess_path
2495
	pop	edx
2496
	mov	esi,edx
2497
	call	open
2498
	jc	file_not_found
2499
      include_path_ok:
31 halyavin 2500
	mov	edi,[esp]
157 heavyiron 2501
      copy_preprocessed_path:
31 halyavin 2502
	lods	byte [esi]
157 heavyiron 2503
	stos	byte [edi]
2504
	or	al,al
2505
	jnz	copy_preprocessed_path
2506
	pop	esi
2507
	lea	ecx,[edi-1]
2508
	sub	ecx,esi
2509
	mov	[esi-4],ecx
2510
	push	dword [macro_status]
2511
	and	[macro_status],0Fh
2512
	call	preprocess_file
2513
	pop	eax
2514
	mov	[macro_status],al
2515
	jmp	line_preprocessed
2516
      preprocess_path:
31 halyavin 2517
	lods	byte [esi]
157 heavyiron 2518
	cmp	al,'%'
2519
	je	environment_variable
2520
	stos	byte [edi]
2521
	or	al,al
2522
	jnz	preprocess_path
2523
	cmp	edi,[memory_end]
2524
	ja	out_of_memory
2525
	ret
2526
      environment_variable:
31 halyavin 2527
	mov	ebx,esi
157 heavyiron 2528
      find_variable_end:
31 halyavin 2529
	lods	byte [esi]
157 heavyiron 2530
	or	al,al
2531
	jz	not_environment_variable
2532
	cmp	al,'%'
2533
	jne	find_variable_end
2534
	mov	byte [esi-1],0
2535
	push	esi
2536
	mov	esi,ebx
2537
	call	get_environment_variable
2538
	pop	esi
2539
	mov	byte [esi-1],'%'
2540
	jmp	preprocess_path
2541
      not_environment_variable:
31 halyavin 2542
	mov	al,'%'
157 heavyiron 2543
	stos	byte [edi]
2544
	mov	esi,ebx
2545
	jmp	preprocess_path
2546
>