Subversion Repositories Kolibri OS

Rev

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