Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

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