Subversion Repositories Kolibri OS

Rev

Rev 157 | 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
	jecxz	convert_to_quoted_string
242 heavyiron 1201
	cmp	byte [esi],'\'
1202
	jne	convert_to_quoted_string
1203
	inc	esi
1204
	dec	ecx
1205
	dec	ebx
1206
	jmp	convert_to_quoted_string
157 heavyiron 1207
      symbol_character_conversion:
109 heavyiron 1208
	cmp	al,22h
157 heavyiron 1209
	je	after_macro_operators
1210
	cmp	al,'`'
1211
	je	reduce_symbol_conversion
1212
	lea	ebx,[edi+5]
1213
	xor	ecx,ecx
1214
	or	al,al
1215
	jz	convert_to_quoted_string
1216
	cmp	al,'#'
1217
	je	convert_to_quoted_string
1218
	inc	ecx
1219
      convert_to_quoted_string:
109 heavyiron 1220
	sub	ebx,edx
157 heavyiron 1221
	ja	shift_line_data
1222
	mov	al,22h
1223
	mov	dl,al
1224
	stos	byte [edi]
1225
	mov	ebx,edi
1226
	mov	eax,ecx
1227
	stos	dword [edi]
1228
	rep	movs byte [edi],[esi]
1229
	cmp	edi,esi
1230
	je	before_macro_operators
1231
	jmp	after_macro_operators
1232
      shift_line_data:
31 halyavin 1233
	push	ecx
157 heavyiron 1234
	mov	edx,esi
1235
	lea	esi,[ebp-1]
1236
	add	ebp,ebx
1237
	lea	edi,[ebp-1]
1238
	lea	ecx,[esi+1]
1239
	sub	ecx,edx
1240
	std
1241
	rep	movs byte [edi],[esi]
1242
	cld
1243
	pop	eax
1244
	sub	edi,3
1245
	mov	dl,22h
1246
	mov	[edi-1],dl
1247
	mov	ebx,edi
1248
	mov	[edi],eax
1249
	lea	esi,[edi+4+eax]
1250
	jmp	before_macro_operators
1251
      concatenation:
31 halyavin 1252
	cmp	dl,1Ah
157 heavyiron 1253
	je	symbol_concatenation
1254
	cmp	dl,22h
1255
	je	string_concatenation
1256
      no_concatenation:
31 halyavin 1257
	cmp	esi,edi
157 heavyiron 1258
	je	before_macro_operators
1259
	jmp	after_macro_operators
1260
      symbol_concatenation:
31 halyavin 1261
	cmp	byte [esi],1Ah
157 heavyiron 1262
	jne	no_concatenation
1263
	inc	esi
1264
	lods	byte [esi]
1265
	movzx	ecx,al
1266
	jecxz	do_symbol_concatenation
1267
	cmp	byte [esi],'\'
1268
	je	concatenate_escaped_symbol
242 heavyiron 1269
      do_symbol_concatenation:
31 halyavin 1270
	add	[ebx],cl
242 heavyiron 1271
	jc	name_too_long
157 heavyiron 1272
	rep	movs byte [edi],[esi]
1273
	jmp	after_macro_operators
1274
      concatenate_escaped_symbol:
242 heavyiron 1275
	inc	esi
1276
	dec	ecx
1277
	jz	do_symbol_concatenation
1278
	movzx	eax,byte [esi]
1279
	cmp	byte [characters+eax],0
1280
	jne	do_symbol_concatenation
1281
	sub	esi,3
1282
	jmp	no_concatenation
1283
      string_concatenation:
31 halyavin 1284
	cmp	byte [esi],22h
157 heavyiron 1285
	je	do_string_concatenation
1286
	cmp	byte [esi],'`'
1287
	jne	no_concatenation
1288
      concatenate_converted_symbol:
109 heavyiron 1289
	inc	esi
157 heavyiron 1290
	mov	al,[esi]
1291
	cmp	al,'`'
1292
	je	concatenate_converted_symbol
1293
	cmp	al,22h
1294
	je	do_string_concatenation
1295
	cmp	al,1Ah
1296
	jne	concatenate_converted_symbol_character
1297
	inc	esi
1298
	lods	byte [esi]
1299
	movzx	ecx,al
1300
	jecxz	finish_concatenating_converted_symbol
242 heavyiron 1301
	cmp	byte [esi],'\'
1302
	jne	finish_concatenating_converted_symbol
1303
	inc	esi
1304
	dec	ecx
1305
      finish_concatenating_converted_symbol:
1306
	add	[ebx],ecx
157 heavyiron 1307
	rep	movs byte [edi],[esi]
1308
	jmp	after_macro_operators
1309
      concatenate_converted_symbol_character:
109 heavyiron 1310
	or	al,al
157 heavyiron 1311
	jz	after_macro_operators
1312
	cmp	al,'#'
1313
	je	after_macro_operators
1314
	inc	dword [ebx]
1315
	movs	byte [edi],[esi]
1316
	jmp	after_macro_operators
1317
      do_string_concatenation:
31 halyavin 1318
	inc	esi
157 heavyiron 1319
	lods	dword [esi]
1320
	mov	ecx,eax
1321
	add	[ebx],eax
1322
	rep	movs byte [edi],[esi]
1323
      after_macro_operators:
31 halyavin 1324
	lods	byte [esi]
157 heavyiron 1325
	cmp	al,'`'
1326
	je	symbol_conversion
1327
	cmp	al,'#'
1328
	je	concatenation
1329
	stos	byte [edi]
1330
	cmp	al,1Ah
1331
	je	symbol_after_macro_operators
1332
	cmp	al,3Bh
1333
	je	no_more_macro_operators
1334
	cmp	al,22h
1335
	je	string_after_macro_operators
1336
	xor	dl,dl
1337
	or	al,al
1338
	jnz	after_macro_operators
1339
	ret
1340
      symbol_after_macro_operators:
31 halyavin 1341
	mov	dl,1Ah
157 heavyiron 1342
	mov	ebx,edi
1343
	lods	byte [esi]
1344
	stos	byte [edi]
1345
	movzx	ecx,al
1346
	jecxz	symbol_after_macro_operatorss_ok
1347
	cmp	byte [esi],'\'
1348
	je	escaped_symbol
1349
      symbol_after_macro_operatorss_ok:
31 halyavin 1350
	rep	movs byte [edi],[esi]
157 heavyiron 1351
	jmp	after_macro_operators
1352
      string_after_macro_operators:
31 halyavin 1353
	mov	dl,22h
157 heavyiron 1354
	mov	ebx,edi
1355
	lods	dword [esi]
1356
	stos	dword [edi]
1357
	mov	ecx,eax
1358
	rep	movs byte [edi],[esi]
1359
	jmp	after_macro_operators
1360
31 halyavin 1361
 
1362
	push	[free_additional_memory]
157 heavyiron 1363
	push	[macro_symbols]
1364
	mov	[macro_symbols],0
1365
	push	[counter_limit]
1366
	push	dword [edx+4]
1367
	mov	dword [edx+4],1
1368
	push	edx
1369
	mov	ebx,esi
1370
	mov	esi,[edx+8]
1371
	mov	eax,[edx+12]
1372
	mov	[macro_line],eax
1373
	mov	[counter_limit],0
1374
      process_macro_arguments:
31 halyavin 1375
	mov	al,[esi]
157 heavyiron 1376
	or	al,al
1377
	jz	arguments_end
1378
	cmp	al,'{'
1379
	je	arguments_end
1380
	inc	esi
1381
	cmp	al,'['
1382
	jne	get_macro_arguments
1383
	mov	ebp,esi
1384
	inc	esi
1385
	inc	[counter_limit]
1386
      get_macro_arguments:
31 halyavin 1387
	call	get_macro_argument
157 heavyiron 1388
	lods	byte [esi]
1389
	cmp	al,','
1390
	je	next_argument
1391
	cmp	al,']'
1392
	je	next_arguments_group
1393
	dec	esi
1394
	jmp	arguments_end
1395
      next_argument:
31 halyavin 1396
	cmp	byte [ebx],','
157 heavyiron 1397
	jne	process_macro_arguments
1398
	inc	ebx
1399
	jmp	process_macro_arguments
1400
      next_arguments_group:
31 halyavin 1401
	cmp	byte [ebx],','
157 heavyiron 1402
	jne	arguments_end
1403
	inc	ebx
1404
	inc	[counter_limit]
1405
	mov	esi,ebp
1406
	jmp	process_macro_arguments
1407
      get_macro_argument:
31 halyavin 1408
	lods	byte [esi]
157 heavyiron 1409
	movzx	ecx,al
1410
	mov	eax,[counter_limit]
1411
	call	add_macro_symbol
1412
	add	esi,ecx
1413
	xchg	esi,ebx
1414
	mov	[edx+12],esi
1415
	cmp	byte [esi],'<'
1416
	jne	simple_argument
1417
	inc	esi
1418
	mov	[edx+12],esi
1419
	mov	ecx,1
1420
      enclosed_argument:
31 halyavin 1421
	lods	byte [esi]
157 heavyiron 1422
	or	al,al
1423
	jz	invalid_macro_arguments
1424
	cmp	al,1Ah
1425
	je	enclosed_symbol
1426
	cmp	al,22h
1427
	je	enclosed_string
1428
	cmp	al,'>'
1429
	je	enclosed_argument_end
1430
	cmp	al,'<'
1431
	jne	enclosed_argument
1432
	inc	ecx
1433
	jmp	enclosed_argument
1434
      enclosed_symbol:
31 halyavin 1435
	movzx	eax,byte [esi]
157 heavyiron 1436
	inc	esi
1437
	add	esi,eax
1438
	jmp	enclosed_argument
1439
      enclosed_string:
31 halyavin 1440
	lods	dword [esi]
157 heavyiron 1441
	add	esi,eax
1442
	jmp	enclosed_argument
1443
      enclosed_argument_end:
31 halyavin 1444
	loop	enclosed_argument
157 heavyiron 1445
	mov	al,[esi]
1446
	or	al,al
1447
	jz	enclosed_argument_ok
1448
	cmp	al,','
1449
	jne	invalid_macro_arguments
1450
      enclosed_argument_ok:
31 halyavin 1451
	mov	eax,esi
157 heavyiron 1452
	sub	eax,[edx+12]
1453
	dec	eax
1454
	or	eax,80000000h
1455
	mov	[edx+8],eax
1456
	jmp	argument_value_ok
1457
      simple_argument:
31 halyavin 1458
	lods	byte [esi]
157 heavyiron 1459
	or	al,al
1460
	jz	argument_value_end
1461
	cmp	al,','
1462
	je	argument_value_end
1463
	cmp	al,22h
1464
	je	argument_string
1465
	cmp	al,1Ah
1466
	jne	simple_argument
1467
	movzx	eax,byte [esi]
1468
	inc	esi
1469
	add	esi,eax
1470
	jmp	simple_argument
1471
      argument_string:
31 halyavin 1472
	lods	dword [esi]
157 heavyiron 1473
	add	esi,eax
1474
	jmp	simple_argument
1475
      argument_value_end:
31 halyavin 1476
	dec	esi
157 heavyiron 1477
	mov	eax,esi
1478
	sub	eax,[edx+12]
1479
	mov	[edx+8],eax
1480
      argument_value_ok:
31 halyavin 1481
	xchg	esi,ebx
157 heavyiron 1482
	cmp	byte [esi],'*'
1483
	jne	macro_argument_ok
1484
	cmp	dword [edx+8],0
1485
	je	invalid_macro_arguments
1486
	inc	esi
1487
      macro_argument_ok:
31 halyavin 1488
	ret
157 heavyiron 1489
      arguments_end:
31 halyavin 1490
	cmp	byte [ebx],0
157 heavyiron 1491
	jne	invalid_macro_arguments
1492
	mov	eax,[esp+4]
1493
	dec	eax
1494
	call	process_macro
1495
	pop	edx
1496
	pop	dword [edx+4]
1497
	pop	[counter_limit]
1498
	pop	[macro_symbols]
1499
	pop	[free_additional_memory]
1500
	jmp	line_preprocessed
1501
use_instant_macro:
31 halyavin 1502
	push	edi [current_line] esi
157 heavyiron 1503
	mov	eax,[error_line]
1504
	mov	[current_line],eax
1505
	mov	[macro_line],eax
1506
	mov	esi,[instant_macro_start]
1507
	cmp	[base_code],10h
1508
	jae	do_match
1509
	cmp	[base_code],0
1510
	jne	do_irp
1511
	call	get_number
1512
	jc	invalid_value
1513
	or	ebp,ebp
1514
	jnz	invalid_value
1515
	cmp	dword [edi+4],0
1516
	jne	value_out_of_range
1517
	mov	eax,[edi]
1518
	or	eax,eax
1519
	jz	instant_macro_done
1520
	cmp	eax,80000000h
1521
	jae	value_out_of_range
1522
	push	[free_additional_memory]
1523
	push	[macro_symbols]
1524
	mov	[macro_symbols],0
1525
	push	[counter_limit]
1526
	mov	[struc_name],0
1527
	mov	[counter_limit],eax
1528
	lods	byte [esi]
1529
	or	al,al
1530
	jz	rept_counters_ok
1531
	cmp	al,'{'
1532
	je	rept_counters_ok
1533
	cmp	al,1Ah
1534
	jne	invalid_macro_arguments
1535
      add_rept_counter:
31 halyavin 1536
	lods	byte [esi]
157 heavyiron 1537
	movzx	ecx,al
1538
	xor	eax,eax
1539
	call	add_macro_symbol
1540
	add	esi,ecx
1541
	xor	eax,eax
1542
	mov	dword [edx+12],eax
1543
	inc	eax
1544
	mov	dword [edx+8],eax
1545
	lods	byte [esi]
1546
	cmp	al,':'
1547
	jne	rept_counter_added
1548
	push	edx
1549
	call	get_number
1550
	jc	invalid_value
1551
	or	ebp,ebp
1552
	jnz	invalid_value
1553
	cmp	dword [edi+4],0
1554
	jne	value_out_of_range
1555
	mov	eax,[edi]
1556
	mov	edx,eax
1557
	add	edx,[counter_limit]
1558
	jc	value_out_of_range
1559
	pop	edx
1560
	mov	dword [edx+8],eax
1561
	lods	byte [esi]
1562
      rept_counter_added:
31 halyavin 1563
	cmp	al,','
157 heavyiron 1564
	jne	rept_counters_ok
1565
	lods	byte [esi]
1566
	cmp	al,1Ah
1567
	jne	invalid_macro_arguments
1568
	jmp	add_rept_counter
1569
      rept_counters_ok:
31 halyavin 1570
	dec	esi
157 heavyiron 1571
      instant_macro_parameters_ok:
31 halyavin 1572
	xor	eax,eax
157 heavyiron 1573
	call	process_macro
1574
	pop	[counter_limit]
1575
	pop	[macro_symbols]
1576
	pop	[free_additional_memory]
1577
      instant_macro_done:
31 halyavin 1578
	pop	ebx esi edx
157 heavyiron 1579
	cmp	byte [ebx],0
1580
	je	line_preprocessed
1581
	mov	[current_line],edi
1582
	mov	ecx,4
1583
	rep	movs dword [edi],[esi]
1584
	test	[macro_status],0Fh
1585
	jz	instant_macro_attached_line
1586
	mov	ax,3Bh
1587
	stos	word [edi]
1588
      instant_macro_attached_line:
31 halyavin 1589
	mov	esi,ebx
157 heavyiron 1590
	sub	edx,ebx
1591
	mov	ecx,edx
1592
	call	move_data
1593
	jmp	initial_preprocessing_ok
1594
do_irp:
31 halyavin 1595
	cmp	byte [esi],1Ah
157 heavyiron 1596
	jne	invalid_macro_arguments
1597
	movzx	eax,byte [esi+1]
1598
	lea	esi,[esi+2+eax]
1599
	lods	byte [esi]
1600
	cmp	[base_code],1
1601
	ja	irps_name_ok
1602
	cmp	al,'*'
1603
	jne	irp_name_ok
1604
	lods	byte [esi]
1605
      irp_name_ok:
31 halyavin 1606
	cmp	al,','
157 heavyiron 1607
	jne	invalid_macro_arguments
1608
	jmp	irp_parameters_start
1609
      irps_name_ok:
31 halyavin 1610
	cmp	al,','
157 heavyiron 1611
	jne	invalid_macro_arguments
1612
	mov	al,[esi]
1613
	or	al,al
1614
	jz	instant_macro_done
1615
	cmp	al,'{'
1616
	je	instant_macro_done
1617
      irp_parameters_start:
31 halyavin 1618
	xor	eax,eax
157 heavyiron 1619
	push	[free_additional_memory]
1620
	push	[macro_symbols]
1621
	mov	[macro_symbols],eax
1622
	push	[counter_limit]
1623
	mov	[counter_limit],eax
1624
	mov	[struc_name],eax
1625
	mov	ebx,esi
1626
	cmp	[base_code],1
1627
	ja	get_irps_parameter
1628
	mov	edx,[parameters_end]
1629
	mov	al,[edx]
1630
	push	eax
1631
	mov	byte [edx],0
1632
      get_irp_parameter:
31 halyavin 1633
	inc	[counter_limit]
157 heavyiron 1634
	mov	esi,[instant_macro_start]
1635
	inc	esi
1636
	call	get_macro_argument
1637
	cmp	byte [ebx],','
1638
	jne	irp_parameters_end
1639
	inc	ebx
1640
	jmp	get_irp_parameter
1641
      irp_parameters_end:
31 halyavin 1642
	mov	esi,ebx
157 heavyiron 1643
	pop	eax
1644
	mov	[esi],al
1645
	jmp	instant_macro_parameters_ok
1646
      get_irps_parameter:
31 halyavin 1647
	mov	esi,[instant_macro_start]
157 heavyiron 1648
	inc	esi
1649
	lods	byte [esi]
1650
	movzx	ecx,al
1651
	inc	[counter_limit]
1652
	mov	eax,[counter_limit]
1653
	call	add_macro_symbol
1654
	mov	[edx+12],ebx
1655
	cmp	byte [ebx],1Ah
1656
	je	irps_symbol
1657
	cmp	byte [ebx],22h
1658
	je	irps_quoted_string
1659
	mov	eax,1
1660
	jmp	irps_parameter_ok
1661
      irps_quoted_string:
31 halyavin 1662
	mov	eax,[ebx+1]
157 heavyiron 1663
	add	eax,1+4
1664
	jmp	irps_parameter_ok
1665
      irps_symbol:
31 halyavin 1666
	movzx	eax,byte [ebx+1]
157 heavyiron 1667
	add	eax,1+1
1668
      irps_parameter_ok:
31 halyavin 1669
	mov	[edx+8],eax
157 heavyiron 1670
	add	ebx,eax
1671
	cmp	byte [ebx],0
1672
	je	irps_parameters_end
1673
	cmp	byte [ebx],'{'
1674
	jne	get_irps_parameter
1675
      irps_parameters_end:
31 halyavin 1676
	mov	esi,ebx
157 heavyiron 1677
	jmp	instant_macro_parameters_ok
1678
do_match:
31 halyavin 1679
	mov	ebx,esi
157 heavyiron 1680
	call	skip_pattern
1681
	call	exact_match
1682
	mov	edx,edi
1683
	mov	al,[ebx]
1684
	cmp	al,1Ah
1685
	je	free_match
1686
	cmp	al,','
1687
	jne	instant_macro_done
1688
	cmp	esi,[parameters_end]
1689
	je	matched_pattern
1690
	jmp	instant_macro_done
1691
      free_match:
31 halyavin 1692
	add	edx,12
157 heavyiron 1693
	cmp	edx,[memory_end]
1694
	ja	out_of_memory
1695
	mov	[edx-12],ebx
1696
	mov	[edx-8],esi
1697
	call	skip_match_element
1698
	jc	try_different_matching
1699
	mov	[edx-4],esi
1700
	movzx	eax,byte [ebx+1]
1701
	lea	ebx,[ebx+2+eax]
1702
	cmp	byte [ebx],1Ah
1703
	je	free_match
1704
      find_exact_match:
31 halyavin 1705
	call	exact_match
157 heavyiron 1706
	cmp	esi,[parameters_end]
1707
	je	end_matching
1708
	cmp	byte [ebx],1Ah
1709
	je	free_match
1710
	mov	ebx,[edx-12]
1711
	movzx	eax,byte [ebx+1]
1712
	lea	ebx,[ebx+2+eax]
1713
	mov	esi,[edx-4]
1714
	jmp	match_more_elements
1715
      try_different_matching:
31 halyavin 1716
	sub	edx,12
157 heavyiron 1717
	cmp	edx,edi
1718
	je	instant_macro_done
1719
	mov	ebx,[edx-12]
1720
	movzx	eax,byte [ebx+1]
1721
	lea	ebx,[ebx+2+eax]
1722
	cmp	byte [ebx],1Ah
1723
	je	try_different_matching
1724
	mov	esi,[edx-4]
1725
      match_more_elements:
31 halyavin 1726
	call	skip_match_element
157 heavyiron 1727
	jc	try_different_matching
1728
	mov	[edx-4],esi
1729
	jmp	find_exact_match
1730
      skip_match_element:
31 halyavin 1731
	cmp	esi,[parameters_end]
157 heavyiron 1732
	je	cannot_match
1733
	mov	al,[esi]
1734
	cmp	al,1Ah
1735
	je	skip_match_symbol
1736
	cmp	al,22h
1737
	je	skip_match_quoted_string
1738
	add	esi,1
1739
	ret
1740
      skip_match_quoted_string:
31 halyavin 1741
	mov	eax,[esi+1]
157 heavyiron 1742
	add	esi,5
1743
	jmp	skip_match_ok
1744
      skip_match_symbol:
31 halyavin 1745
	movzx	eax,byte [esi+1]
157 heavyiron 1746
	add	esi,2
1747
      skip_match_ok:
31 halyavin 1748
	add	esi,eax
157 heavyiron 1749
	ret
1750
      cannot_match:
31 halyavin 1751
	stc
157 heavyiron 1752
	ret
1753
      exact_match:
31 halyavin 1754
	cmp	esi,[parameters_end]
157 heavyiron 1755
	je	exact_match_complete
1756
	mov	ah,[esi]
1757
	mov	al,[ebx]
1758
	cmp	al,','
1759
	je	exact_match_complete
1760
	cmp	al,1Ah
1761
	je	exact_match_complete
1762
	cmp	al,'='
1763
	je	match_verbatim
1764
	call	match_elements
1765
	je	exact_match
1766
      exact_match_complete:
31 halyavin 1767
	ret
157 heavyiron 1768
      match_verbatim:
31 halyavin 1769
	inc	ebx
157 heavyiron 1770
	call	match_elements
1771
	je	exact_match
1772
	dec	ebx
1773
	ret
1774
      match_elements:
31 halyavin 1775
	mov	al,[ebx]
157 heavyiron 1776
	cmp	al,1Ah
1777
	je	match_symbols
1778
	cmp	al,22h
1779
	je	match_quoted_strings
1780
	cmp	al,ah
1781
	je	symbol_characters_matched
1782
	ret
1783
      symbol_characters_matched:
31 halyavin 1784
	lea	ebx,[ebx+1]
157 heavyiron 1785
	lea	esi,[esi+1]
1786
	ret
1787
      match_quoted_strings:
31 halyavin 1788
	mov	ecx,[ebx+1]
157 heavyiron 1789
	add	ecx,5
1790
	jmp	compare_elements
1791
      match_symbols:
31 halyavin 1792
	movzx	ecx,byte [ebx+1]
157 heavyiron 1793
	add	ecx,2
1794
      compare_elements:
31 halyavin 1795
	mov	eax,esi
157 heavyiron 1796
	mov	ebp,edi
1797
	mov	edi,ebx
1798
	repe	cmps byte [esi],[edi]
1799
	jne	elements_mismatch
1800
	mov	ebx,edi
1801
	mov	edi,ebp
1802
	ret
1803
      elements_mismatch:
31 halyavin 1804
	mov	esi,eax
157 heavyiron 1805
	mov	edi,ebp
1806
	ret
1807
      end_matching:
31 halyavin 1808
	cmp	byte [ebx],','
157 heavyiron 1809
	jne	instant_macro_done
1810
      matched_pattern:
31 halyavin 1811
	xor	eax,eax
157 heavyiron 1812
	push	[free_additional_memory]
1813
	push	[macro_symbols]
1814
	mov	[macro_symbols],eax
1815
	push	[counter_limit]
1816
	mov	[counter_limit],eax
1817
	mov	[struc_name],eax
1818
	push	esi edi edx
1819
      add_matched_symbol:
31 halyavin 1820
	cmp	edi,[esp]
157 heavyiron 1821
	je	matched_symbols_ok
1822
	mov	esi,[edi]
1823
	inc	esi
1824
	lods	byte [esi]
1825
	movzx	ecx,al
1826
	xor	eax,eax
1827
	call	add_macro_symbol
1828
	mov	eax,[edi+4]
1829
	mov	dword [edx+12],eax
1830
	mov	ecx,[edi+8]
1831
	sub	ecx,eax
1832
	mov	dword [edx+8],ecx
1833
	add	edi,12
1834
	jmp	add_matched_symbol
1835
      matched_symbols_ok:
31 halyavin 1836
	pop	edx edi esi
157 heavyiron 1837
	jmp	instant_macro_parameters_ok
1838
31 halyavin 1839
 
1840
	push	dword [macro_status]
157 heavyiron 1841
	or	[macro_status],10h
1842
	push	[counter]
1843
	push	[macro_block]
1844
	push	[macro_block_line]
1845
	push	[macro_block_line_number]
1846
	push	[struc_label]
1847
	push	[struc_name]
1848
	push	eax
1849
	push	[current_line]
1850
	lods	byte [esi]
1851
	cmp	al,'{'
1852
	je	macro_instructions_start
1853
	or	al,al
1854
	jnz	unexpected_characters
1855
      find_macro_instructions:
31 halyavin 1856
	mov	[macro_line],esi
157 heavyiron 1857
	add	esi,16+2
1858
	lods	byte [esi]
1859
	or	al,al
1860
	jz	find_macro_instructions
1861
	cmp	al,'{'
1862
	je	macro_instructions_start
1863
	cmp	al,3Bh
1864
	jne	unexpected_characters
1865
	call	skip_foreign_symbol
1866
	jmp	find_macro_instructions
1867
      macro_instructions_start:
31 halyavin 1868
	mov	ecx,80000000h
157 heavyiron 1869
	mov	[macro_block],esi
1870
	mov	eax,[macro_line]
1871
	mov	[macro_block_line],eax
1872
	mov	[macro_block_line_number],ecx
1873
	xor	eax,eax
1874
	mov	[counter],eax
1875
	cmp	[counter_limit],eax
1876
	je	process_macro_line
1877
	inc	[counter]
1878
      process_macro_line:
31 halyavin 1879
	mov	[current_line],edi
157 heavyiron 1880
	lea	eax,[edi+10h]
1881
	cmp	eax,[memory_end]
1882
	jae	out_of_memory
1883
	mov	eax,[esp+4]
1884
	or	eax,eax
1885
	jz	instant_macro_line_header
1886
	stos	dword [edi]
1887
	mov	eax,ecx
1888
	stos	dword [edi]
1889
	mov	eax,[esp]
1890
	stos	dword [edi]
1891
	mov	eax,[macro_line]
1892
	stos	dword [edi]
1893
	jmp	macro_line_header_ok
1894
      instant_macro_line_header:
31 halyavin 1895
	mov	edx,[macro_line]
157 heavyiron 1896
	mov	eax,[edx]
1897
	stos	dword [edi]
1898
	mov	eax,[edx+4]
1899
	stos	dword [edi]
1900
	mov	eax,[edx+8]
1901
	stos	dword [edi]
1902
	mov	eax,[edx+12]
1903
	stos	dword [edi]
1904
      macro_line_header_ok:
31 halyavin 1905
	or	[macro_status],20h
157 heavyiron 1906
	push	ebx ecx
1907
	test	[macro_status],0Fh
1908
	jz	process_macro_line_element
1909
	mov	ax,3Bh
1910
	stos	word [edi]
1911
      process_macro_line_element:
31 halyavin 1912
	lea	eax,[edi+100h]
157 heavyiron 1913
	cmp	eax,[memory_end]
1914
	jae	out_of_memory
1915
	lods	byte [esi]
1916
	cmp	al,'}'
1917
	je	macro_line_processed
1918
	or	al,al
1919
	jz	macro_line_processed
1920
	cmp	al,1Ah
1921
	je	process_macro_symbol
1922
	cmp	al,3Bh
1923
	je	macro_foreign_line
1924
	and	[macro_status],not 20h
1925
	stos	byte [edi]
1926
	cmp	al,22h
1927
	jne	process_macro_line_element
1928
      copy_macro_string:
31 halyavin 1929
	mov	ecx,[esi]
157 heavyiron 1930
	add	ecx,4
1931
	call	move_data
1932
	jmp	process_macro_line_element
1933
      process_macro_symbol:
31 halyavin 1934
	push	esi edi
157 heavyiron 1935
	test	[macro_status],20h
1936
	jz	not_macro_directive
1937
	movzx	ecx,byte [esi]
1938
	inc	esi
1939
	mov	edi,macro_directives
1940
	call	get_directive
1941
	jnc	process_macro_directive
1942
	dec	esi
1943
	jmp	not_macro_directive
1944
      process_macro_directive:
31 halyavin 1945
	mov	edx,eax
157 heavyiron 1946
	pop	edi eax
1947
	mov	byte [edi],0
1948
	inc	edi
1949
	pop	ecx ebx
1950
	jmp	near edx
1951
      not_macro_directive:
31 halyavin 1952
	and	[macro_status],not 20h
157 heavyiron 1953
	movzx	ecx,byte [esi]
1954
	inc	esi
1955
	mov	eax,[counter]
1956
	call	get_macro_symbol
1957
	jnc	group_macro_symbol
1958
	xor	eax,eax
1959
	cmp	[counter],eax
1960
	je	multiple_macro_symbol_values
1961
	call	get_macro_symbol
1962
	jc	not_macro_symbol
1963
      replace_macro_symbol:
31 halyavin 1964
	pop	edi eax
157 heavyiron 1965
	mov	ecx,[edx+8]
1966
	and	ecx,not 80000000h
1967
	mov	edx,[edx+12]
1968
	or	edx,edx
1969
	jz	replace_macro_counter
1970
	xchg	esi,edx
1971
	call	move_data
1972
	mov	esi,edx
1973
	jmp	process_macro_line_element
1974
      group_macro_symbol:
31 halyavin 1975
	xor	eax,eax
157 heavyiron 1976
	cmp	[counter],eax
1977
	je	replace_macro_symbol
1978
	push	esi edx
1979
	sub	esi,ecx
1980
	call	get_macro_symbol
1981
	mov	ebx,edx
1982
	pop	edx esi
1983
	jc	replace_macro_symbol
1984
	cmp	edx,ebx
1985
	ja	replace_macro_symbol
1986
	mov	edx,ebx
1987
	jmp	replace_macro_symbol
1988
      multiple_macro_symbol_values:
31 halyavin 1989
	inc	eax
157 heavyiron 1990
	push	eax
1991
	call	get_macro_symbol
1992
	pop	eax
1993
	jc	not_macro_symbol
1994
	pop	edi
1995
	push	ecx
1996
	mov	ecx,[edx+8]
1997
	mov	edx,[edx+12]
1998
	xchg	esi,edx
1999
	btr	ecx,31
2000
	jc	enclose_macro_symbol_value
2001
	rep	movs byte [edi],[esi]
2002
	jmp	macro_symbol_value_ok
2003
      enclose_macro_symbol_value:
31 halyavin 2004
	mov	byte [edi],'<'
157 heavyiron 2005
	inc	edi
2006
	rep	movs byte [edi],[esi]
2007
	mov	byte [edi],'>'
2008
	inc	edi
2009
      macro_symbol_value_ok:
31 halyavin 2010
	cmp	eax,[counter_limit]
157 heavyiron 2011
	je	multiple_macro_symbol_values_ok
2012
	mov	byte [edi],','
2013
	inc	edi
2014
	mov	esi,edx
2015
	pop	ecx
2016
	push	edi
2017
	sub	esi,ecx
2018
	jmp	multiple_macro_symbol_values
2019
      multiple_macro_symbol_values_ok:
31 halyavin 2020
	pop	ecx eax
157 heavyiron 2021
	mov	esi,edx
2022
	jmp	process_macro_line_element
2023
      replace_macro_counter:
31 halyavin 2024
	mov	eax,[counter]
157 heavyiron 2025
	and	eax,not 80000000h
2026
	jz	group_macro_counter
2027
	add	ecx,eax
2028
	dec	ecx
2029
	call	store_number_symbol
2030
	jmp	process_macro_line_element
2031
      group_macro_counter:
31 halyavin 2032
	mov	edx,ecx
157 heavyiron 2033
	xor	ecx,ecx
2034
      multiple_macro_counter_values:
31 halyavin 2035
	push	ecx edx
157 heavyiron 2036
	add	ecx,edx
2037
	call	store_number_symbol
2038
	pop	edx ecx
2039
	inc	ecx
2040
	cmp	ecx,[counter_limit]
2041
	je	process_macro_line_element
2042
	mov	byte [edi],','
2043
	inc	edi
2044
	jmp	multiple_macro_counter_values
2045
      store_number_symbol:
31 halyavin 2046
	mov	ax,1Ah
157 heavyiron 2047
	stos	word [edi]
2048
	push	edi
2049
	mov	eax,ecx
2050
	mov	ecx,1000000000
2051
	xor	edx,edx
2052
	xor	bl,bl
2053
      store_number_digits:
31 halyavin 2054
	div	ecx
157 heavyiron 2055
	push	edx
2056
	or	bl,bl
2057
	jnz	store_number_digit
2058
	cmp	ecx,1
2059
	je	store_number_digit
2060
	or	al,al
2061
	jz	number_digit_ok
2062
	not	bl
2063
      store_number_digit:
31 halyavin 2064
	add	al,30h
157 heavyiron 2065
	stos	byte [edi]
2066
      number_digit_ok:
31 halyavin 2067
	mov	eax,ecx
157 heavyiron 2068
	xor	edx,edx
2069
	mov	ecx,10
2070
	div	ecx
2071
	mov	ecx,eax
2072
	pop	eax
2073
	or	ecx,ecx
2074
	jnz	store_number_digits
2075
	pop	ebx
2076
	mov	eax,edi
2077
	sub	eax,ebx
2078
	mov	[ebx-1],al
2079
	ret
2080
      not_macro_symbol:
31 halyavin 2081
	pop	edi esi
157 heavyiron 2082
	mov	al,1Ah
2083
	stos	byte [edi]
2084
	mov	al,[esi]
2085
	inc	esi
2086
	stos	byte [edi]
2087
	cmp	byte [esi],'.'
2088
	jne	copy_raw_symbol
2089
	mov	ebx,[esp+8+8]
2090
	or	ebx,ebx
2091
	jz	copy_raw_symbol
2092
	cmp	al,1
2093
	je	copy_struc_name
2094
	xchg	esi,ebx
2095
	movzx	ecx,byte [esi-1]
2096
	add	[edi-1],cl
2097
	jc	name_too_long
2098
	rep	movs byte [edi],[esi]
2099
	xchg	esi,ebx
2100
      copy_raw_symbol:
31 halyavin 2101
	movzx	ecx,al
157 heavyiron 2102
	rep	movs byte [edi],[esi]
2103
	jmp	process_macro_line_element
2104
      copy_struc_name:
31 halyavin 2105
	inc	esi
157 heavyiron 2106
	xchg	esi,ebx
2107
	movzx	ecx,byte [esi-1]
2108
	mov	[edi-1],cl
2109
	rep	movs byte [edi],[esi]
2110
	xchg	esi,ebx
2111
	mov	eax,[esp+8+12]
2112
	cmp	byte [eax],3Bh
2113
	je	process_macro_line_element
2114
	cmp	byte [eax],1Ah
2115
	jne	disable_replaced_struc_name
2116
	mov	byte [eax],3Bh
2117
	jmp	process_macro_line_element
2118
      disable_replaced_struc_name:
31 halyavin 2119
	mov	ebx,[esp+8+8]
157 heavyiron 2120
	push	esi edi
2121
	lea	edi,[ebx-3]
2122
	lea	esi,[edi-2]
2123
	lea	ecx,[esi+1]
2124
	sub	ecx,eax
2125
	std
2126
	rep	movs byte [edi],[esi]
2127
	cld
2128
	mov	word [eax],3Bh
2129
	pop	edi esi
2130
	jmp	process_macro_line_element
2131
      skip_foreign_symbol:
31 halyavin 2132
	lods	byte [esi]
157 heavyiron 2133
	movzx	eax,al
2134
	add	esi,eax
2135
      skip_foreign_line:
31 halyavin 2136
	lods	byte [esi]
157 heavyiron 2137
	cmp	al,1Ah
2138
	je	skip_foreign_symbol
2139
	cmp	al,3Bh
2140
	je	skip_foreign_symbol
2141
	cmp	al,22h
2142
	je	skip_foreign_string
2143
	or	al,al
2144
	jnz	skip_foreign_line
2145
	ret
2146
      skip_foreign_string:
31 halyavin 2147
	lods	dword [esi]
157 heavyiron 2148
	add	esi,eax
2149
	jmp	skip_foreign_line
2150
      macro_foreign_line:
31 halyavin 2151
	call	skip_foreign_symbol
157 heavyiron 2152
      macro_line_processed:
31 halyavin 2153
	mov	byte [edi],0
157 heavyiron 2154
	inc	edi
2155
	push	eax
2156
	call	preprocess_line
2157
	pop	eax
2158
	pop	ecx ebx
2159
	cmp	al,'}'
2160
	je	macro_block_processed
2161
      process_next_line:
31 halyavin 2162
	inc	ecx
157 heavyiron 2163
	mov	[macro_line],esi
2164
	add	esi,16+2
2165
	jmp	process_macro_line
2166
      macro_block_processed:
31 halyavin 2167
	call	close_macro_block
157 heavyiron 2168
	jc	process_macro_line
2169
	pop	[current_line]
2170
	add	esp,12
2171
	pop	[macro_block_line_number]
2172
	pop	[macro_block_line]
2173
	pop	[macro_block]
2174
	pop	[counter]
2175
	pop	eax
2176
	and	al,0F0h
2177
	and	[macro_status],0Fh
2178
	or	[macro_status],al
2179
	ret
2180
31 halyavin 2181
 
2182
	lods	byte [esi]
157 heavyiron 2183
	cmp	al,1Ah
2184
	jne	invalid_argument
2185
	mov	byte [edi-1],3Bh
2186
	xor	al,al
2187
	stos	byte [edi]
2188
      make_local_symbol:
31 halyavin 2189
	push	ecx
157 heavyiron 2190
	lods	byte [esi]
2191
	movzx	ecx,al
2192
	mov	eax,[counter]
2193
	call	add_macro_symbol
2194
	mov	[edx+12],edi
2195
	movzx	eax,[locals_counter]
2196
	add	eax,ecx
2197
	inc	eax
2198
	cmp	eax,100h
2199
	jae	name_too_long
2200
	lea	ebp,[edi+2+eax]
2201
	cmp	ebp,[memory_end]
2202
	jae	out_of_memory
2203
	mov	ah,al
2204
	mov	al,1Ah
2205
	stos	word [edi]
2206
	rep	movs byte [edi],[esi]
2207
	mov	al,'?'
2208
	stos	byte [edi]
2209
	push	esi
2210
	mov	esi,locals_counter+1
2211
	movzx	ecx,[locals_counter]
2212
	rep	movs byte [edi],[esi]
2213
	pop	esi
2214
	mov	eax,edi
2215
	sub	eax,[edx+12]
2216
	mov	[edx+8],eax
2217
	xor	al,al
2218
	stos	byte [edi]
2219
	mov	eax,locals_counter
2220
	movzx	ecx,byte [eax]
2221
      counter_loop:
31 halyavin 2222
	inc	byte [eax+ecx]
157 heavyiron 2223
	cmp	byte [eax+ecx],':'
2224
	jb	counter_ok
2225
	jne	letter_digit
2226
	mov	byte [eax+ecx],'A'
2227
	jmp	counter_ok
2228
      letter_digit:
31 halyavin 2229
	cmp	byte [eax+ecx],'F'
157 heavyiron 2230
	jbe	counter_ok
2231
	mov	byte [eax+ecx],'0'
2232
	loop	counter_loop
2233
      counter_ok:
31 halyavin 2234
	pop	ecx
157 heavyiron 2235
	lods	byte [esi]
2236
	cmp	al,'}'
2237
	je	macro_block_processed
2238
	or	al,al
2239
	jz	process_next_line
2240
	cmp	al,','
2241
	jne	extra_characters_on_line
2242
	dec	edi
2243
	lods	byte [esi]
2244
	cmp	al,1Ah
2245
	je	make_local_symbol
2246
	jmp	invalid_argument
2247
common_block:
31 halyavin 2248
	call	close_macro_block
157 heavyiron 2249
	jc	process_macro_line
2250
	mov	[counter],0
2251
	jmp	new_macro_block
2252
forward_block:
31 halyavin 2253
	cmp	[counter_limit],0
157 heavyiron 2254
	je	common_block
2255
	call	close_macro_block
2256
	jc	process_macro_line
2257
	mov	[counter],1
2258
	jmp	new_macro_block
2259
reverse_block:
31 halyavin 2260
	cmp	[counter_limit],0
157 heavyiron 2261
	je	common_block
2262
	call	close_macro_block
2263
	jc	process_macro_line
2264
	mov	eax,[counter_limit]
2265
	or	eax,80000000h
2266
	mov	[counter],eax
2267
      new_macro_block:
31 halyavin 2268
	mov	[macro_block],esi
157 heavyiron 2269
	mov	eax,[macro_line]
2270
	mov	[macro_block_line],eax
2271
	mov	[macro_block_line_number],ecx
2272
	jmp	process_macro_line
2273
close_macro_block:
31 halyavin 2274
	cmp	[counter],0
157 heavyiron 2275
	je	block_closed
2276
	jl	reverse_counter
2277
	mov	eax,[counter]
2278
	cmp	eax,[counter_limit]
2279
	je	block_closed
2280
	inc	[counter]
2281
	jmp	continue_block
2282
      reverse_counter:
31 halyavin 2283
	mov	eax,[counter]
157 heavyiron 2284
	dec	eax
2285
	cmp	eax,80000000h
2286
	je	block_closed
2287
	mov	[counter],eax
2288
      continue_block:
31 halyavin 2289
	mov	esi,[macro_block]
157 heavyiron 2290
	mov	eax,[macro_block_line]
2291
	mov	[macro_line],eax
2292
	mov	ecx,[macro_block_line_number]
2293
	stc
2294
	ret
2295
      block_closed:
31 halyavin 2296
	clc
157 heavyiron 2297
	ret
2298
get_macro_symbol:
31 halyavin 2299
	push	ecx
157 heavyiron 2300
	call	find_macro_symbol_leaf
2301
	jc	macro_symbol_not_found
2302
	mov	edx,[ebx]
2303
	mov	ebx,esi
2304
      try_macro_symbol:
31 halyavin 2305
	or	edx,edx
157 heavyiron 2306
	jz	macro_symbol_not_found
2307
	mov	ecx,[esp]
2308
	mov	edi,[edx+4]
2309
	repe	cmps byte [esi],[edi]
2310
	je	macro_symbol_found
2311
	mov	esi,ebx
2312
	mov	edx,[edx]
2313
	jmp	try_macro_symbol
2314
      macro_symbol_found:
31 halyavin 2315
	pop	ecx
157 heavyiron 2316
	clc
2317
	ret
2318
      macro_symbol_not_found:
31 halyavin 2319
	pop	ecx
157 heavyiron 2320
	stc
2321
	ret
2322
      find_macro_symbol_leaf:
31 halyavin 2323
	shl	eax,8
157 heavyiron 2324
	mov	al,cl
2325
	mov	ebp,eax
2326
	mov	ebx,macro_symbols
2327
      follow_macro_symbols_tree:
31 halyavin 2328
	mov	edx,[ebx]
157 heavyiron 2329
	or	edx,edx
2330
	jz	no_such_macro_symbol
2331
	xor	eax,eax
2332
	shr	ebp,1
2333
	adc	eax,0
2334
	lea	ebx,[edx+eax*4]
2335
	or	ebp,ebp
2336
	jnz	follow_macro_symbols_tree
2337
	add	ebx,8
2338
	clc
2339
	ret
2340
      no_such_macro_symbol:
31 halyavin 2341
	stc
157 heavyiron 2342
	ret
2343
add_macro_symbol:
31 halyavin 2344
	push	ebx ebp
157 heavyiron 2345
	call	find_macro_symbol_leaf
2346
	jc	extend_macro_symbol_tree
2347
	mov	eax,[ebx]
2348
      make_macro_symbol:
31 halyavin 2349
	mov	edx,[free_additional_memory]
157 heavyiron 2350
	add	edx,16
2351
	cmp	edx,[labels_list]
2352
	ja	out_of_memory
2353
	xchg	edx,[free_additional_memory]
2354
	mov	[ebx],edx
2355
	mov	[edx],eax
2356
	mov	[edx+4],esi
2357
	pop	ebp ebx
2358
	ret
2359
      extend_macro_symbol_tree:
31 halyavin 2360
	mov	edx,[free_additional_memory]
157 heavyiron 2361
	add	edx,16
2362
	cmp	edx,[labels_list]
2363
	ja	out_of_memory
2364
	xchg	edx,[free_additional_memory]
2365
	xor	eax,eax
2366
	mov	[edx],eax
2367
	mov	[edx+4],eax
2368
	mov	[edx+8],eax
2369
	mov	[edx+12],eax
2370
	shr	ebp,1
2371
	adc	eax,0
2372
	mov	[ebx],edx
2373
	lea	ebx,[edx+eax*4]
2374
	or	ebp,ebp
2375
	jnz	extend_macro_symbol_tree
2376
	add	ebx,8
2377
	xor	eax,eax
2378
	jmp	make_macro_symbol
2379
31 halyavin 2380
 
2381
	lods	byte [esi]
157 heavyiron 2382
	cmp	al,22h
2383
	jne	invalid_argument
2384
	lods	dword [esi]
2385
	cmp	byte [esi+eax],0
2386
	jne	extra_characters_on_line
2387
	push	esi
2388
	push	edi
2389
	mov	ebx,[current_line]
2390
      find_current_file_path:
31 halyavin 2391
	mov	esi,[ebx]
157 heavyiron 2392
	test	byte [ebx+7],80h
2393
	jz	copy_current_file_path
2394
	mov	ebx,[ebx+8]
2395
	jmp	find_current_file_path
2396
      copy_current_file_path:
31 halyavin 2397
	lods	byte [esi]
157 heavyiron 2398
	stos	byte [edi]
2399
	or	al,al
2400
	jnz	copy_current_file_path
2401
      cut_current_file_name:
31 halyavin 2402
	cmp	edi,[esp]
157 heavyiron 2403
	je	current_file_path_ok
2404
	cmp	byte [edi-1],'\'
2405
	je	current_file_path_ok
2406
	cmp	byte [edi-1],'/'
2407
	je	current_file_path_ok
2408
	dec	edi
2409
	jmp	cut_current_file_name
2410
      current_file_path_ok:
31 halyavin 2411
	mov	esi,[esp+4]
157 heavyiron 2412
	call	preprocess_path
2413
	pop	edx
2414
	mov	esi,edx
2415
	call	open
2416
	jnc	include_path_ok
2417
	mov	ebp,[include_paths]
2418
      try_include_directories:
31 halyavin 2419
	mov	edi,esi
157 heavyiron 2420
	mov	esi,ebp
2421
	cmp	byte [esi],0
2422
	je	try_in_current_directory
2423
	push	ebp
2424
	push	edi
2425
      copy_include_directory:
31 halyavin 2426
	lods	byte [esi]
157 heavyiron 2427
	cmp	al,';'
2428
	je	include_directory_ok
2429
	stos	byte [edi]
2430
	or	al,al
2431
	jnz	copy_include_directory
2432
	dec	esi
2433
	dec	edi
2434
      include_directory_ok:
31 halyavin 2435
	cmp	byte [edi-1],'/'
157 heavyiron 2436
	je	path_separator_ok
2437
	cmp	byte [edi-1],'\'
2438
	je	path_separator_ok
2439
	mov	al,'/'
2440
	stos	byte [edi]
2441
      path_separator_ok:
31 halyavin 2442
	mov	[esp+4],esi
157 heavyiron 2443
	mov	esi,[esp+8]
2444
	call	preprocess_path
2445
	pop	edx
2446
	mov	esi,edx
2447
	call	open
2448
	pop	ebp
2449
	jnc	include_path_ok
2450
	jmp	try_include_directories
2451
	mov	edi,esi
2452
      try_in_current_directory:
31 halyavin 2453
	mov	esi,[esp]
157 heavyiron 2454
	push	edi
2455
	call	preprocess_path
2456
	pop	edx
2457
	mov	esi,edx
2458
	call	open
2459
	jc	file_not_found
2460
      include_path_ok:
31 halyavin 2461
	mov	edi,[esp]
157 heavyiron 2462
      copy_preprocessed_path:
31 halyavin 2463
	lods	byte [esi]
157 heavyiron 2464
	stos	byte [edi]
2465
	or	al,al
2466
	jnz	copy_preprocessed_path
2467
	pop	esi
2468
	lea	ecx,[edi-1]
2469
	sub	ecx,esi
2470
	mov	[esi-4],ecx
2471
	push	dword [macro_status]
2472
	and	[macro_status],0Fh
2473
	call	preprocess_file
2474
	pop	eax
2475
	mov	[macro_status],al
2476
	jmp	line_preprocessed
2477
      preprocess_path:
31 halyavin 2478
	lods	byte [esi]
157 heavyiron 2479
	cmp	al,'%'
2480
	je	environment_variable
2481
	stos	byte [edi]
2482
	or	al,al
2483
	jnz	preprocess_path
2484
	cmp	edi,[memory_end]
2485
	ja	out_of_memory
2486
	ret
2487
      environment_variable:
31 halyavin 2488
	mov	ebx,esi
157 heavyiron 2489
      find_variable_end:
31 halyavin 2490
	lods	byte [esi]
157 heavyiron 2491
	or	al,al
2492
	jz	not_environment_variable
2493
	cmp	al,'%'
2494
	jne	find_variable_end
2495
	mov	byte [esi-1],0
2496
	push	esi
2497
	mov	esi,ebx
2498
	call	get_environment_variable
2499
	pop	esi
2500
	mov	byte [esi-1],'%'
2501
	jmp	preprocess_path
2502
      not_environment_variable:
31 halyavin 2503
	mov	al,'%'
157 heavyiron 2504
	stos	byte [edi]
2505
	mov	esi,ebx
2506
	jmp	preprocess_path
2507
>