Subversion Repositories Kolibri OS

Rev

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