Subversion Repositories Kolibri OS

Rev

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