Subversion Repositories Kolibri OS

Rev

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