Subversion Repositories Kolibri OS

Rev

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