Subversion Repositories Kolibri OS

Rev

Rev 242 | 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-2007, Tomasz Grysztar.
340 heavyiron 3
; All rights reserved.
31 halyavin 4
5
 
6
	mov	eax,[memory_end]
157 heavyiron 7
	mov	[labels_list],eax
8
	mov	eax,[additional_memory]
9
	mov	[free_additional_memory],eax
10
	xor	eax,eax
11
	mov	[current_locals_prefix],eax
12
	mov	[anonymous_reverse],eax
13
	mov	[anonymous_forward],eax
14
	mov	[hash_tree],eax
15
	mov	[blocks_stack],eax
16
	mov	[parsed_lines],eax
242 heavyiron 17
	mov	esi,[memory_start]
157 heavyiron 18
	mov	edi,[source_start]
19
      parser_loop:
31 halyavin 20
	mov	[current_line],esi
157 heavyiron 21
	lea	eax,[edi+100h]
22
	cmp	eax,[labels_list]
23
	jae	out_of_memory
24
	cmp	byte [esi+16],0
25
	je	empty_line
26
	mov	al,0Fh
27
	stos	byte [edi]
28
	mov	eax,esi
29
	stos	dword [edi]
30
	inc	[parsed_lines]
242 heavyiron 31
	add	esi,16
157 heavyiron 32
      parse_line:
109 heavyiron 33
	cmp	byte [esi],1Ah
157 heavyiron 34
	jne	empty_instruction
35
	push	edi
36
	add	esi,2
37
	movzx	ecx,byte [esi-1]
38
	cmp	byte [esi+ecx],':'
39
	je	simple_label
40
	cmp	byte [esi+ecx],'='
41
	je	constant_label
42
	call	get_instruction
43
	jnc	main_instruction_identified
44
	cmp	byte [esi+ecx],1Ah
45
	jne	no_data_label
46
	push	esi ecx
47
	lea	esi,[esi+ecx+2]
48
	movzx	ecx,byte [esi-1]
49
	call	get_data_directive
50
	jnc	data_label
51
	pop	ecx esi
52
      no_data_label:
109 heavyiron 53
	call	get_data_directive
157 heavyiron 54
	jnc	main_instruction_identified
55
	pop	edi
56
	sub	esi,2
57
	xor	bx,bx
58
	call	parse_line_contents
59
	jmp	parse_next_line
60
      simple_label:
109 heavyiron 61
	pop	edi
157 heavyiron 62
	call	identify_label
63
	mov	byte [edi],2
64
	inc	edi
65
	stos	dword [edi]
66
	inc	esi
67
	xor	al,al
68
	stos	byte [edi]
69
	jmp	parse_line
70
      constant_label:
109 heavyiron 71
	pop	edi
157 heavyiron 72
	call	get_label_id
73
	mov	byte [edi],3
74
	inc	edi
75
	stos	dword [edi]
76
	xor	al,al
77
	stos	byte [edi]
78
	inc	esi
79
	xor	bx,bx
80
	call	parse_line_contents
81
	jmp	parse_next_line
82
      data_label:
109 heavyiron 83
	pop	ecx edx
157 heavyiron 84
	pop	edi
85
	push	eax ebx esi
86
	mov	esi,edx
87
	movzx	ecx,byte [esi-1]
88
	call	identify_label
89
	mov	byte [edi],2
90
	inc	edi
91
	stos	dword [edi]
92
	pop	esi ebx eax
93
	stos	byte [edi]
94
	push	edi
95
      main_instruction_identified:
109 heavyiron 96
	pop	edi
157 heavyiron 97
	mov	dl,al
98
	mov	al,1
99
	stos	byte [edi]
100
	mov	ax,bx
101
	stos	word [edi]
102
	mov	al,dl
103
	stos	byte [edi]
104
	cmp	bx,if_directive-assembler
105
	je	parse_block
106
	cmp	bx,repeat_directive-assembler
107
	je	parse_block
108
	cmp	bx,while_directive-assembler
109
	je	parse_block
110
	cmp	bx,end_directive-assembler
111
	je	parse_end_directive
112
	cmp	bx,else_directive-assembler
113
	je	parse_else
114
      common_parse:
109 heavyiron 115
	call	parse_line_contents
157 heavyiron 116
	jmp	parse_next_line
117
      empty_instruction:
109 heavyiron 118
	lods	byte [esi]
157 heavyiron 119
	or	al,al
120
	jz	parse_next_line
121
	cmp	al,':'
122
	je	invalid_name
123
	cmp	al,3Bh
124
	je	skip_preprocessed_symbol
125
	dec	esi
126
	call	parse_argument
127
	jmp	parse_next_line
128
      skip_preprocessed_symbol:
109 heavyiron 129
	lods	byte [esi]
157 heavyiron 130
	movzx	eax,al
131
	add	esi,eax
132
      skip_next:
109 heavyiron 133
	lods	byte [esi]
157 heavyiron 134
	or	al,al
135
	jz	parse_next_line
136
	cmp	al,1Ah
137
	je	skip_preprocessed_symbol
138
	cmp	al,3Bh
139
	je	skip_preprocessed_symbol
140
	cmp	al,22h
141
	je	skip_preprocessed_string
142
	jmp	skip_next
143
      skip_preprocessed_string:
109 heavyiron 144
	lods	dword [esi]
157 heavyiron 145
	add	esi,eax
146
	jmp	skip_next
147
      empty_line:
109 heavyiron 148
	add	esi,17
157 heavyiron 149
      parse_next_line:
31 halyavin 150
	cmp	esi,[source_start]
157 heavyiron 151
	jb	parser_loop
152
      source_parsed:
109 heavyiron 153
	cmp	[blocks_stack],0
157 heavyiron 154
	je	blocks_stack_ok
155
	pop	eax
156
	pop	[current_line]
157
	jmp	missing_end_directive
158
      blocks_stack_ok:
109 heavyiron 159
	xor	al,al
157 heavyiron 160
	stos	byte [edi]
161
	mov	eax,[error_line]
162
	mov	[current_line],eax
163
	cmp	[anonymous_forward],0
164
	jne	invalid_value
165
	add	edi,0Fh
166
	and	edi,not 0Fh
167
	mov	[code_start],edi
168
	ret
169
      parse_block:
109 heavyiron 170
	mov	eax,esp
157 heavyiron 171
	sub	eax,100h
172
	jc	stack_overflow
173
	cmp	eax,[stack_limit]
174
	jb	stack_overflow
175
	push	[current_line]
176
	mov	ax,bx
177
	shl	eax,16
178
	push	eax
179
	inc	[blocks_stack]
180
	cmp	bx,if_directive-assembler
181
	je	parse_if
182
	cmp	bx,while_directive-assembler
183
	je	parse_while
184
	call	parse_line_contents
185
	jmp	parse_next_line
186
      parse_end_directive:
109 heavyiron 187
	cmp	byte [esi],1Ah
157 heavyiron 188
	jne	common_parse
189
	push	edi
190
	inc	esi
191
	movzx	ecx,byte [esi]
192
	inc	esi
193
	call	get_instruction
194
	pop	edi
195
	jnc	parse_end_block
196
	sub	esi,2
197
	jmp	common_parse
198
      parse_end_block:
109 heavyiron 199
	mov	dl,al
157 heavyiron 200
	mov	al,1
201
	stos	byte [edi]
202
	mov	ax,bx
203
	stos	word [edi]
204
	mov	al,dl
205
	stos	byte [edi]
206
	lods	byte [esi]
207
	or	al,al
208
	jnz	extra_characters_on_line
209
	cmp	bx,if_directive-assembler
210
	je	close_parsing_block
211
	cmp	bx,repeat_directive-assembler
212
	je	close_parsing_block
213
	cmp	bx,while_directive-assembler
214
	je	close_parsing_block
215
	jmp	parse_next_line
216
      close_parsing_block:
109 heavyiron 217
	cmp	[blocks_stack],0
157 heavyiron 218
	je	unexpected_instruction
219
	cmp	bx,[esp+2]
220
	jne	unexpected_instruction
221
	dec	[blocks_stack]
222
	pop	eax edx
223
	cmp	bx,if_directive-assembler
224
	jne	parse_next_line
225
	test	al,1100b
226
	jz	parse_next_line
227
	test	al,10000b
228
	jnz	parse_next_line
229
	sub	edi,8
230
	jmp	parse_next_line
231
      parse_if:
109 heavyiron 232
	push	edi
157 heavyiron 233
	call	parse_line_contents
234
	xor	al,al
235
	stos	byte [edi]
236
	xchg	esi,[esp]
237
	mov	edi,esi
238
	call	preevaluate_logical_expression
239
	pop	esi
240
	cmp	al,'0'
241
	je	parse_false_condition_block
242
	cmp	al,'1'
243
	je	parse_true_condition_block
244
	or	byte [esp],10000b
245
	jmp	parse_next_line
246
      parse_while:
109 heavyiron 247
	push	edi
157 heavyiron 248
	call	parse_line_contents
249
	xor	al,al
250
	stos	byte [edi]
251
	xchg	esi,[esp]
252
	mov	edi,esi
253
	call	preevaluate_logical_expression
254
	pop	esi
255
	cmp	al,'0'
256
	je	parse_false_condition_block
257
	cmp	al,'1'
258
	jne	parse_next_line
259
	stos	byte [edi]
260
	jmp	parse_next_line
261
      parse_false_condition_block:
109 heavyiron 262
	or	byte [esp],1
157 heavyiron 263
	sub	edi,4
264
	jmp	skip_parsing
265
      parse_true_condition_block:
109 heavyiron 266
	or	byte [esp],100b
157 heavyiron 267
	sub	edi,4
268
	jmp	parse_next_line
269
      parse_else:
109 heavyiron 270
	cmp	[blocks_stack],0
157 heavyiron 271
	je	unexpected_instruction
272
	cmp	word [esp+2],if_directive-assembler
273
	jne	unexpected_instruction
274
	lods	byte [esi]
275
	or	al,al
276
	jz	parse_pure_else
277
	cmp	al,1Ah
278
	jne	extra_characters_on_line
279
	push	edi
280
	movzx	ecx,byte [esi]
281
	inc	esi
282
	call	get_instruction
283
	jc	extra_characters_on_line
284
	pop	edi
285
	cmp	bx,if_directive-assembler
286
	jne	extra_characters_on_line
287
	test	byte [esp],100b
288
	jnz	skip_true_condition_else
289
	mov	dl,al
290
	mov	al,1
291
	stos	byte [edi]
292
	mov	ax,bx
293
	stos	word [edi]
294
	mov	al,dl
295
	stos	byte [edi]
296
	jmp	parse_if
297
      skip_true_condition_else:
109 heavyiron 298
	sub	edi,4
157 heavyiron 299
	or	byte [esp],1
300
	jmp	skip_parsing_contents
301
      parse_pure_else:
109 heavyiron 302
	bts	dword [esp],1
157 heavyiron 303
	jc	unexpected_instruction
304
	test	byte [esp],100b
305
	jz	parse_next_line
306
	sub	edi,4
307
	or	byte [esp],1
308
	jmp	skip_parsing
309
      skip_parsing:
109 heavyiron 310
	cmp	esi,[source_start]
157 heavyiron 311
	jae	source_parsed
312
	mov	[current_line],esi
313
	add	esi,16
314
      skip_parsing_line:
109 heavyiron 315
	cmp	byte [esi],1Ah
157 heavyiron 316
	jne	skip_parsing_contents
317
	inc	esi
318
	movzx	ecx,byte [esi]
319
	inc	esi
320
	cmp	byte [esi+ecx],':'
321
	je	skip_parsing_label
322
	push	edi
323
	call	get_instruction
324
	pop	edi
325
	jnc	skip_parsing_instruction
326
	add	esi,ecx
327
	jmp	skip_parsing_contents
328
      skip_parsing_label:
109 heavyiron 329
	lea	esi,[esi+ecx+1]
157 heavyiron 330
	jmp	skip_parsing_line
331
      skip_parsing_instruction:
109 heavyiron 332
	cmp	bx,if_directive-assembler
157 heavyiron 333
	je	skip_parsing_block
334
	cmp	bx,repeat_directive-assembler
335
	je	skip_parsing_block
336
	cmp	bx,while_directive-assembler
337
	je	skip_parsing_block
338
	cmp	bx,end_directive-assembler
339
	je	skip_parsing_end_directive
340
	cmp	bx,else_directive-assembler
341
	je	skip_parsing_else
342
      skip_parsing_contents:
109 heavyiron 343
	lods	byte [esi]
157 heavyiron 344
	or	al,al
345
	jz	skip_parsing
346
	cmp	al,1Ah
347
	je	skip_parsing_symbol
348
	cmp	al,3Bh
349
	je	skip_parsing_symbol
350
	cmp	al,22h
351
	je	skip_parsing_string
352
	jmp	skip_parsing_contents
353
      skip_parsing_symbol:
109 heavyiron 354
	lods	byte [esi]
157 heavyiron 355
	movzx	eax,al
356
	add	esi,eax
357
	jmp	skip_parsing_contents
358
      skip_parsing_string:
109 heavyiron 359
	lods	dword [esi]
157 heavyiron 360
	add	esi,eax
361
	jmp	skip_parsing_contents
362
      skip_parsing_block:
109 heavyiron 363
	mov	eax,esp
157 heavyiron 364
	sub	eax,100h
365
	jc	stack_overflow
366
	cmp	eax,[stack_limit]
367
	jb	stack_overflow
368
	push	[current_line]
369
	mov	ax,bx
370
	shl	eax,16
371
	push	eax
372
	inc	[blocks_stack]
373
	jmp	skip_parsing_contents
374
      skip_parsing_end_directive:
109 heavyiron 375
	cmp	byte [esi],1Ah
157 heavyiron 376
	jne	skip_parsing_contents
377
	push	edi
378
	inc	esi
379
	movzx	ecx,byte [esi]
380
	inc	esi
381
	call	get_instruction
382
	pop	edi
383
	jnc	skip_parsing_end_block
384
	add	esi,ecx
385
	jmp	skip_parsing_contents
386
      skip_parsing_end_block:
109 heavyiron 387
	lods	byte [esi]
157 heavyiron 388
	or	al,al
389
	jnz	extra_characters_on_line
390
	cmp	bx,if_directive-assembler
391
	je	close_skip_parsing_block
392
	cmp	bx,repeat_directive-assembler
393
	je	close_skip_parsing_block
394
	cmp	bx,while_directive-assembler
395
	je	close_skip_parsing_block
396
	jmp	skip_parsing
397
      close_skip_parsing_block:
109 heavyiron 398
	cmp	[blocks_stack],0
157 heavyiron 399
	je	unexpected_instruction
400
	cmp	bx,[esp+2]
401
	jne	unexpected_instruction
402
	dec	[blocks_stack]
403
	pop	eax edx
404
	test	al,1
405
	jz	skip_parsing
406
	cmp	bx,if_directive-assembler
407
	jne	parse_next_line
408
	test	al,10000b
409
	jz	parse_next_line
410
	mov	al,0Fh
411
	stos	byte [edi]
412
	mov	eax,[current_line]
413
	stos	dword [edi]
414
	inc	[parsed_lines]
242 heavyiron 415
	mov	eax,1 + (end_directive-assembler) shl 8
157 heavyiron 416
	stos	dword [edi]
417
	mov	eax,1 + (if_directive-assembler) shl 8
418
	stos	dword [edi]
419
	jmp	parse_next_line
420
      skip_parsing_else:
109 heavyiron 421
	cmp	[blocks_stack],0
157 heavyiron 422
	je	unexpected_instruction
423
	cmp	word [esp+2],if_directive-assembler
424
	jne	unexpected_instruction
425
	lods	byte [esi]
426
	or	al,al
427
	jz	skip_parsing_pure_else
428
	cmp	al,1Ah
429
	jne	extra_characters_on_line
430
	push	edi
431
	movzx	ecx,byte [esi]
432
	inc	esi
433
	call	get_instruction
434
	jc	extra_characters_on_line
435
	pop	edi
436
	cmp	bx,if_directive-assembler
437
	jne	extra_characters_on_line
438
	mov	al,[esp]
439
	test	al,1
440
	jz	skip_parsing_contents
441
	test	al,100b
442
	jnz	skip_parsing_contents
443
	test	al,10000b
444
	jnz	parse_else_if
445
	xor	al,al
446
	mov	[esp],al
447
	mov	al,0Fh
448
	stos	byte [edi]
449
	mov	eax,[current_line]
450
	stos	dword [edi]
451
	inc	[parsed_lines]
242 heavyiron 452
      parse_else_if:
109 heavyiron 453
	mov	eax,1 + (if_directive-assembler) shl 8
157 heavyiron 454
	stos	dword [edi]
455
	jmp	parse_if
456
      skip_parsing_pure_else:
109 heavyiron 457
	bts	dword [esp],1
157 heavyiron 458
	jc	unexpected_instruction
459
	mov	al,[esp]
460
	test	al,1
461
	jz	skip_parsing
462
	test	al,100b
463
	jnz	skip_parsing
464
	and	al,not 1
465
	or	al,1000b
466
	mov	[esp],al
467
	jmp	parse_next_line
468
31 halyavin 469
 
109 heavyiron 470
	mov	[parenthesis_stack],0
157 heavyiron 471
      parse_instruction_arguments:
109 heavyiron 472
	cmp	bx,prefix_instruction-assembler
157 heavyiron 473
	je	allow_embedded_instruction
474
	cmp	bx,times_directive-assembler
475
	je	parse_times_directive
476
	cmp	bx,end_directive-assembler
477
	je	allow_embedded_instruction
478
	cmp	bx,label_directive-assembler
479
	je	parse_label_directive
480
	cmp	bx,segment_directive-assembler
481
	je	parse_label_directive
482
	cmp	bx,load_directive-assembler
483
	je	parse_load_directive
484
	cmp	bx,extrn_directive-assembler
485
	je	parse_extrn_directive
486
	cmp	bx,public_directive-assembler
487
	je	parse_public_directive
488
      parse_argument:
109 heavyiron 489
	lea	eax,[edi+100h]
157 heavyiron 490
	cmp	eax,[labels_list]
491
	jae	out_of_memory
492
	lods	byte [esi]
493
	cmp	al,':'
494
	je	instruction_separator
495
	cmp	al,','
496
	je	separator
497
	cmp	al,'='
498
	je	separator
499
	cmp	al,'|'
500
	je	separator
501
	cmp	al,'&'
502
	je	separator
503
	cmp	al,'~'
504
	je	separator
505
	cmp	al,'>'
506
	je	greater
507
	cmp	al,'<'
508
	je	less
509
	cmp	al,')'
510
	je	close_parenthesis
511
	or	al,al
512
	jz	contents_parsed
513
	cmp	al,'['
514
	je	address_argument
515
	cmp	al,']'
516
	je	separator
517
	cmp	al,'{'
518
	je	unallowed_character
519
	cmp	al,'}'
520
	je	unallowed_character
521
	cmp	al,'#'
522
	je	unallowed_character
523
	cmp	al,'`'
524
	je	unallowed_character
525
	dec	esi
526
	cmp	al,1Ah
527
	jne	expression_argument
528
	push	edi
529
	mov	edi,directive_operators
530
	call	get_operator
531
	or	al,al
532
	jnz	operator_argument
533
	inc	esi
534
	movzx	ecx,byte [esi]
535
	inc	esi
536
	call	get_symbol
537
	jnc	symbol_argument
538
	cmp	ecx,1
539
	jne	check_argument
540
	cmp	byte [esi],'?'
541
	jne	check_argument
542
	pop	edi
543
	movs	byte [edi],[esi]
544
	jmp	argument_parsed
545
      symbol_argument:
109 heavyiron 546
	pop	edi
157 heavyiron 547
	stos	word [edi]
548
	jmp	argument_parsed
549
      operator_argument:
109 heavyiron 550
	pop	edi
157 heavyiron 551
	cmp	al,85h
552
	je	ptr_argument
553
	stos	byte [edi]
554
	cmp	al,80h
555
	je	forced_expression
556
	cmp	al,81h
557
	je	forced_parenthesis
558
	cmp	al,82h
559
	je	parse_from_operator
560
	cmp	al,89h
561
	je	parse_label_operator
562
	jmp	argument_parsed
563
      allow_embedded_instruction:
109 heavyiron 564
	cmp	byte [esi],1Ah
157 heavyiron 565
	jne	parse_argument
566
	push	edi
567
	inc	esi
568
	movzx	ecx,byte [esi]
569
	inc	esi
570
	call	get_instruction
571
	jnc	embedded_instruction
572
	call	get_data_directive
573
	jnc	embedded_instruction
574
	pop	edi
575
	sub	esi,2
576
	jmp	parse_argument
577
      embedded_instruction:
109 heavyiron 578
	pop	edi
157 heavyiron 579
	mov	dl,al
580
	mov	al,1
581
	stos	byte [edi]
582
	mov	ax,bx
583
	stos	word [edi]
584
	mov	al,dl
585
	stos	byte [edi]
586
	jmp	parse_instruction_arguments
587
      parse_times_directive:
109 heavyiron 588
	mov	al,'('
157 heavyiron 589
	stos	byte [edi]
590
	call	convert_expression
591
	mov	al,')'
592
	stos	byte [edi]
593
	cmp	byte [esi],':'
594
	jne	allow_embedded_instruction
595
	movs	byte [edi],[esi]
596
	jmp	allow_embedded_instruction
597
      parse_label_directive:
31 halyavin 598
	cmp	byte [esi],1Ah
157 heavyiron 599
	jne	argument_parsed
600
	push	esi
601
	inc	esi
602
	movzx	ecx,byte [esi]
603
	inc	esi
604
	call	identify_label
605
	pop	ebx
606
	cmp	eax,0Fh
607
	je	non_label_identified
608
	mov	byte [edi],2
609
	inc	edi
610
	stos	dword [edi]
611
	xor	al,al
612
	stos	byte [edi]
613
	jmp	argument_parsed
614
      non_label_identified:
109 heavyiron 615
	mov	esi,ebx
157 heavyiron 616
	jmp	argument_parsed
617
      parse_load_directive:
31 halyavin 618
	cmp	byte [esi],1Ah
157 heavyiron 619
	jne	argument_parsed
620
	push	esi
621
	inc	esi
622
	movzx	ecx,byte [esi]
623
	inc	esi
624
	call	get_label_id
625
	pop	ebx
626
	cmp	eax,0Fh
627
	je	non_label_identified
628
	mov	byte [edi],2
629
	inc	edi
630
	stos	dword [edi]
631
	xor	al,al
632
	stos	byte [edi]
633
	jmp	argument_parsed
634
      parse_public_directive:
31 halyavin 635
	cmp	byte [esi],1Ah
157 heavyiron 636
	jne	parse_argument
637
	inc	esi
638
	push	esi
639
	movzx	ecx,byte [esi]
640
	inc	esi
641
	mov	al,2
642
	stos	byte [edi]
643
	call	get_label_id
644
	stos	dword [edi]
645
	mov	ax,8600h
646
	stos	word [edi]
647
	pop	ebx
648
	push	ebx esi edi
649
	mov	edi,directive_operators
650
	call	get_operator
651
	pop	edi edx ebx
652
	cmp	al,86h
653
	je	argument_parsed
654
	mov	esi,edx
655
	xchg	esi,ebx
656
	movzx	ecx,byte [esi]
657
	inc	esi
658
	mov	ax,'('
659
	stos	word [edi]
660
	mov	eax,ecx
661
	stos	dword [edi]
662
	rep	movs byte [edi],[esi]
663
	xor	al,al
664
	stos	byte [edi]
665
	xchg	esi,ebx
666
	jmp	argument_parsed
667
      parse_extrn_directive:
31 halyavin 668
	cmp	byte [esi],22h
157 heavyiron 669
	je	parse_quoted_extrn
670
	cmp	byte [esi],1Ah
671
	jne	parse_argument
672
	push	esi
673
	movzx	ecx,byte [esi+1]
674
	add	esi,2
675
	mov	ax,'('
676
	stos	word [edi]
677
	mov	eax,ecx
678
	stos	dword [edi]
679
	rep	movs byte [edi],[esi]
680
	mov	ax,8600h
681
	stos	word [edi]
682
	pop	esi
683
      parse_label_operator:
31 halyavin 684
	cmp	byte [esi],1Ah
157 heavyiron 685
	jne	argument_parsed
686
	inc	esi
687
	movzx	ecx,byte [esi]
688
	inc	esi
689
	mov	al,2
690
	stos	byte [edi]
691
	call	get_label_id
692
	stos	dword [edi]
693
	xor	al,al
694
	stos	byte [edi]
695
	jmp	argument_parsed
696
      parse_from_operator:
31 halyavin 697
	cmp	byte [esi],22h
157 heavyiron 698
	jne	forced_expression
699
	jmp	argument_parsed
700
      parse_quoted_extrn:
31 halyavin 701
	inc	esi
157 heavyiron 702
	mov	ax,'('
703
	stos	word [edi]
704
	lods	dword [esi]
705
	mov	ecx,eax
706
	stos	dword [edi]
707
	rep	movs byte [edi],[esi]
708
	xor	al,al
709
	stos	byte [edi]
710
	push	esi edi
711
	mov	edi,directive_operators
712
	call	get_operator
713
	mov	edx,esi
714
	pop	edi esi
715
	cmp	al,86h
716
	jne	argument_parsed
717
	stos	byte [edi]
718
	mov	esi,edx
719
	jmp	parse_label_operator
720
      ptr_argument:
31 halyavin 721
	call	parse_address
157 heavyiron 722
	jmp	address_parsed
723
      check_argument:
31 halyavin 724
	push	esi ecx
157 heavyiron 725
	sub	esi,2
726
	mov	edi,single_operand_operators
727
	call	get_operator
728
	pop	ecx esi
729
	or	al,al
730
	jnz	not_instruction
731
	call	get_instruction
732
	jnc	embedded_instruction
733
	call	get_data_directive
734
	jnc	embedded_instruction
735
      not_instruction:
31 halyavin 736
	pop	edi
157 heavyiron 737
	sub	esi,2
738
      expression_argument:
31 halyavin 739
	cmp	byte [esi],22h
157 heavyiron 740
	jne	not_string
741
	mov	eax,[esi+1]
742
	lea	ebx,[esi+5+eax]
743
	push	ebx ecx esi edi
744
	mov	al,'('
745
	stos	byte [edi]
746
	call	convert_expression
747
	mov	al,')'
748
	stos	byte [edi]
749
	pop	eax edx ecx ebx
750
	cmp	esi,ebx
751
	jne	expression_parsed
752
	mov	edi,eax
753
	mov	esi,edx
754
      string_argument:
31 halyavin 755
	inc	esi
157 heavyiron 756
	mov	ax,'('
757
	stos	word [edi]
758
	lods	dword [esi]
759
	mov	ecx,eax
760
	stos	dword [edi]
761
	shr	ecx,1
762
	jnc	string_movsb_ok
763
	movs	byte [edi],[esi]
764
      string_movsb_ok:
31 halyavin 765
	shr	ecx,1
157 heavyiron 766
	jnc	string_movsw_ok
767
	movs	word [edi],[esi]
768
      string_movsw_ok:
31 halyavin 769
	rep	movs dword [edi],[esi]
157 heavyiron 770
	xor	al,al
771
	stos	byte [edi]
772
	jmp	expression_parsed
773
      not_string:
31 halyavin 774
	cmp	byte [esi],'('
157 heavyiron 775
	jne	expression
776
	mov	eax,esp
777
	sub	eax,100h
778
	jc	stack_overflow
779
	cmp	eax,[stack_limit]
780
	jb	stack_overflow
781
	push	esi edi
782
	inc	esi
783
	mov	al,'{'
784
	stos	byte [edi]
785
	inc	[parenthesis_stack]
786
	jmp	parse_argument
787
      expression:
31 halyavin 788
	mov	al,'('
157 heavyiron 789
	stos	byte [edi]
790
	call	convert_expression
791
	mov	al,')'
792
	stos	byte [edi]
793
	jmp	expression_parsed
794
      forced_expression:
31 halyavin 795
	mov	al,'('
157 heavyiron 796
	stos	byte [edi]
797
	call	convert_expression
798
	mov	al,')'
799
	stos	byte [edi]
800
	jmp	argument_parsed
801
      address_argument:
31 halyavin 802
	call	parse_address
157 heavyiron 803
	lods	byte [esi]
804
	cmp	al,']'
805
	je	address_parsed
806
	dec	esi
807
	mov	al,')'
808
	stos	byte [edi]
809
	jmp	argument_parsed
810
      address_parsed:
31 halyavin 811
	mov	al,']'
157 heavyiron 812
	stos	byte [edi]
813
	jmp	argument_parsed
814
      parse_address:
31 halyavin 815
	mov	al,'['
157 heavyiron 816
	stos	byte [edi]
817
	cmp	word [esi],021Ah
818
	jne	convert_address
819
	push	esi
820
	add	esi,4
821
	lea	ebx,[esi+1]
822
	cmp	byte [esi],':'
823
	pop	esi
824
	jne	convert_address
825
	add	esi,2
826
	mov	ecx,2
827
	push	ebx edi
828
	call	get_symbol
829
	pop	edi esi
830
	jc	unknown_segment_prefix
831
	cmp	al,10h
832
	jne	unknown_segment_prefix
833
	mov	al,ah
834
	and	ah,11110000b
835
	cmp	ah,60h
836
	jne	unknown_segment_prefix
837
	stos	byte [edi]
838
	jmp	convert_address
839
      unknown_segment_prefix:
109 heavyiron 840
	sub	esi,5
157 heavyiron 841
      convert_address:
31 halyavin 842
	push	edi
157 heavyiron 843
	mov	edi,address_sizes
844
	call	get_operator
845
	pop	edi
846
	or	al,al
847
	jz	convert_expression
848
	add	al,70h
849
	stos	byte [edi]
850
	jmp	convert_expression
851
      forced_parenthesis:
31 halyavin 852
	cmp	byte [esi],'('
157 heavyiron 853
	jne	argument_parsed
854
	inc	esi
855
	mov	al,'{'
856
	jmp	separator
857
      unallowed_character:
31 halyavin 858
	mov	al,0FFh
157 heavyiron 859
	jmp	separator
860
      close_parenthesis:
31 halyavin 861
	mov	al,'}'
157 heavyiron 862
      separator:
31 halyavin 863
	stos	byte [edi]
157 heavyiron 864
	jmp	argument_parsed
865
      instruction_separator:
31 halyavin 866
	stos	byte [edi]
157 heavyiron 867
	jmp	allow_embedded_instruction
868
      greater:
31 halyavin 869
	cmp	byte [esi],'='
157 heavyiron 870
	jne	separator
871
	inc	esi
872
	mov	al,0F2h
873
	jmp	separator
874
      less:
31 halyavin 875
	cmp	byte [edi-1],0F6h
157 heavyiron 876
	je	separator
877
	cmp	byte [esi],'>'
878
	je	not_equal
879
	cmp	byte [esi],'='
880
	jne	separator
881
	inc	esi
882
	mov	al,0F3h
883
	jmp	separator
884
      not_equal:
31 halyavin 885
	inc	esi
157 heavyiron 886
	mov	al,0F1h
887
	jmp	separator
888
      argument_parsed:
31 halyavin 889
	cmp	[parenthesis_stack],0
157 heavyiron 890
	je	parse_argument
891
	dec	[parenthesis_stack]
892
	add	esp,8
893
	jmp	argument_parsed
894
      expression_parsed:
31 halyavin 895
	cmp	[parenthesis_stack],0
157 heavyiron 896
	je	parse_argument
897
	cmp	byte [esi],')'
898
	jne	argument_parsed
899
	dec	[parenthesis_stack]
900
	pop	edi esi
901
	jmp	expression
902
      contents_parsed:
109 heavyiron 903
	cmp	[parenthesis_stack],0
157 heavyiron 904
;        jne     invalid_expression
242 heavyiron 905
	je	contents_ok
906
	dec	[parenthesis_stack]
907
	add	esp,8
908
	jmp	contents_parsed
909
      contents_ok:
910
	ret
157 heavyiron 911
31 halyavin 912
 
109 heavyiron 913
	cmp	byte [esi],'.'
157 heavyiron 914
	je	local_label_name
915
	call	get_label_id
916
	cmp	eax,10h
917
	jb	label_identified
918
	or	ebx,ebx
919
	jz	anonymous_label_name
920
	dec	ebx
921
	mov	[current_locals_prefix],ebx
922
      label_identified:
109 heavyiron 923
	ret
157 heavyiron 924
      anonymous_label_name:
109 heavyiron 925
	cmp	byte [esi-1],'@'
157 heavyiron 926
	je	anonymous_label_name_ok
927
	mov	eax,0Fh
928
      anonymous_label_name_ok:
109 heavyiron 929
	ret
157 heavyiron 930
      local_label_name:
109 heavyiron 931
	call	get_label_id
157 heavyiron 932
	ret
933
109 heavyiron 934
 
31 halyavin 935
	cmp	byte [esi],1Ah
157 heavyiron 936
	jne	get_simple_operator
937
	mov	edx,esi
938
	push	ebp
939
	inc	esi
940
	lods	byte [esi]
941
	movzx	ebp,al
942
	push	edi
943
	mov	ecx,ebp
944
	call	lower_case
945
	pop	edi
946
      check_operator:
31 halyavin 947
	mov	esi,converted
157 heavyiron 948
	movzx	ecx,byte [edi]
949
	jecxz	no_operator
950
	inc	edi
951
	mov	ebx,edi
952
	add	ebx,ecx
953
	cmp	ecx,ebp
954
	jne	next_operator
955
	repe	cmps byte [esi],[edi]
956
	je	operator_found
957
      next_operator:
31 halyavin 958
	mov	edi,ebx
157 heavyiron 959
	inc	edi
960
	jmp	check_operator
961
      no_operator:
31 halyavin 962
	mov	esi,edx
157 heavyiron 963
	mov	ecx,ebp
964
	pop	ebp
965
      no_simple_operator:
31 halyavin 966
	xor	al,al
157 heavyiron 967
	ret
968
      operator_found:
31 halyavin 969
	lea	esi,[edx+2+ebp]
157 heavyiron 970
	mov	ecx,ebp
971
	pop	ebp
972
	mov	al,[edi]
973
	ret
974
      get_simple_operator:
31 halyavin 975
	mov	al,[esi]
157 heavyiron 976
	cmp	al,22h
977
	je	no_simple_operator
978
      simple_operator:
31 halyavin 979
	cmp	byte [edi],1
157 heavyiron 980
	jb	no_simple_operator
981
	ja	simple_next_operator
982
	cmp	al,[edi+1]
983
	je	simple_operator_found
984
      simple_next_operator:
31 halyavin 985
	movzx	ecx,byte [edi]
157 heavyiron 986
	lea	edi,[edi+1+ecx+1]
987
	jmp	simple_operator
988
      simple_operator_found:
31 halyavin 989
	inc	esi
157 heavyiron 990
	mov	al,[edi+2]
991
	ret
992
31 halyavin 993
 
994
	push	esi
157 heavyiron 995
	mov	ebp,ecx
996
	call	lower_case
997
	mov	ecx,ebp
998
	cmp	cl,11
999
	ja	no_symbol
1000
	sub	cl,2
1001
	jc	no_symbol
1002
	movzx	ebx,word [symbols+ecx*4]
1003
	add	ebx,symbols
1004
	movzx	edx,word [symbols+ecx*4+2]
1005
      scan_symbols:
31 halyavin 1006
	or	edx,edx
157 heavyiron 1007
	jz	no_symbol
1008
	mov	eax,edx
1009
	shr	eax,1
1010
	lea	edi,[ebp+2]
1011
	imul	eax,edi
1012
	lea	edi,[ebx+eax]
1013
	mov	esi,converted
1014
	mov	ecx,ebp
1015
	repe	cmps byte [esi],[edi]
1016
	ja	symbols_up
1017
	jb	symbols_down
1018
	pop	esi
1019
	add	esi,ebp
1020
	mov	ax,[edi]
1021
	clc
1022
	ret
1023
      no_symbol:
31 halyavin 1024
	pop	esi
157 heavyiron 1025
	mov	ecx,ebp
1026
	stc
1027
	ret
1028
      symbols_down:
109 heavyiron 1029
	shr	edx,1
157 heavyiron 1030
	jmp	scan_symbols
1031
      symbols_up:
109 heavyiron 1032
	lea	ebx,[edi+ecx+2]
157 heavyiron 1033
	shr	edx,1
1034
	adc	edx,-1
1035
	jmp	scan_symbols
1036
31 halyavin 1037
 
109 heavyiron 1038
	push	esi
157 heavyiron 1039
	mov	ebp,ecx
1040
	call	lower_case
1041
	mov	ecx,ebp
1042
	cmp	cl,4
1043
	ja	no_instruction
1044
	sub	cl,2
1045
	jc	no_instruction
1046
	movzx	ebx,word [data_directives+ecx*4]
1047
	add	ebx,data_directives
1048
	movzx	edx,word [data_directives+ecx*4+2]
1049
	jmp	scan_instructions
1050
109 heavyiron 1051
 
31 halyavin 1052
	push	esi
157 heavyiron 1053
	mov	ebp,ecx
1054
	call	lower_case
1055
	mov	ecx,ebp
1056
	cmp	cl,11
1057
	ja	no_instruction
1058
	sub	cl,2
1059
	jc	no_instruction
1060
	movzx	ebx,word [instructions+ecx*4]
1061
	add	ebx,instructions
1062
	movzx	edx,word [instructions+ecx*4+2]
1063
      scan_instructions:
31 halyavin 1064
	or	edx,edx
157 heavyiron 1065
	jz	no_instruction
1066
	mov	eax,edx
1067
	shr	eax,1
1068
	lea	edi,[ebp+3]
1069
	imul	eax,edi
1070
	lea	edi,[ebx+eax]
1071
	mov	esi,converted
1072
	mov	ecx,ebp
1073
	repe	cmps byte [esi],[edi]
1074
	ja	instructions_up
1075
	jb	instructions_down
1076
	pop	esi
1077
	add	esi,ebp
1078
	mov	al,[edi]
1079
	mov	bx,[edi+1]
1080
	clc
1081
	ret
1082
      no_instruction:
31 halyavin 1083
	pop	esi
157 heavyiron 1084
	mov	ecx,ebp
1085
	stc
1086
	ret
1087
      instructions_down:
109 heavyiron 1088
	shr	edx,1
157 heavyiron 1089
	jmp	scan_instructions
1090
      instructions_up:
109 heavyiron 1091
	lea	ebx,[edi+ecx+3]
157 heavyiron 1092
	shr	edx,1
1093
	adc	edx,-1
1094
	jmp	scan_instructions
1095
31 halyavin 1096
 
1097
	cmp	ecx,100h
157 heavyiron 1098
	jae	name_too_long
1099
	cmp	byte [esi],'@'
1100
	je	anonymous_label
1101
	cmp	byte [esi],'.'
1102
	jne	standard_label
1103
	cmp	byte [esi+1],'.'
1104
	je	standard_label
1105
	cmp	[current_locals_prefix],0
1106
	je	standard_label
1107
	push	edi
1108
	mov	edi,[additional_memory_end]
1109
	sub	edi,2
1110
	sub	edi,ecx
1111
	push	ecx esi
1112
	mov	esi,[current_locals_prefix]
1113
	lods	byte [esi]
1114
	movzx	ecx,al
1115
	sub	edi,ecx
1116
	cmp	edi,[free_additional_memory]
1117
	jb	out_of_memory
1118
	mov	word [edi],0
1119
	add	edi,2
1120
	mov	ebx,edi
1121
	rep	movs byte [edi],[esi]
1122
	pop	esi ecx
1123
	add	al,cl
1124
	jc	name_too_long
1125
	rep	movs byte [edi],[esi]
1126
	pop	edi
1127
	push	ebx esi
1128
	movzx	ecx,al
1129
	mov	byte [ebx-1],al
1130
	mov	esi,ebx
1131
	call	get_label_id
1132
	pop	esi ebx
1133
	cmp	ebx,[eax+24]
1134
	jne	composed_label_id_ok
1135
	lea	edx,[ebx-2]
1136
	mov	[additional_memory_end],edx
1137
      composed_label_id_ok:
109 heavyiron 1138
	ret
157 heavyiron 1139
      anonymous_label:
31 halyavin 1140
	cmp	ecx,2
157 heavyiron 1141
	jne	standard_label
1142
	mov	al,[esi+1]
1143
	mov	ebx,characters
1144
	xlat	byte [ebx]
1145
	cmp	al,'@'
1146
	je	new_anonymous
1147
	cmp	al,'b'
1148
	je	anonymous_back
1149
	cmp	al,'r'
1150
	je	anonymous_back
1151
	cmp	al,'f'
1152
	jne	standard_label
1153
	add	esi,2
1154
	mov	eax,[anonymous_forward]
1155
	or	eax,eax
1156
	jnz	anonymous_ok
1157
	mov	eax,[current_line]
1158
	mov	[error_line],eax
1159
	call	allocate_label
1160
	mov	[anonymous_forward],eax
1161
      anonymous_ok:
31 halyavin 1162
	xor	ebx,ebx
157 heavyiron 1163
	ret
1164
      anonymous_back:
31 halyavin 1165
	add	esi,2
157 heavyiron 1166
	mov	eax,[anonymous_reverse]
1167
	or	eax,eax
1168
	jz	invalid_value
1169
	jmp	anonymous_ok
1170
      new_anonymous:
31 halyavin 1171
	add	esi,2
157 heavyiron 1172
	mov	eax,[anonymous_forward]
1173
	or	eax,eax
1174
	jnz	new_anonymous_ok
1175
	call	allocate_label
1176
      new_anonymous_ok:
31 halyavin 1177
	mov	[anonymous_reverse],eax
157 heavyiron 1178
	mov	[anonymous_forward],0
1179
	jmp	anonymous_ok
1180
      standard_label:
31 halyavin 1181
	cmp	byte [esi],'%'
157 heavyiron 1182
	je	get_predefined_id
1183
	cmp	byte [esi],'$'
1184
	jne	find_label
1185
	cmp	ecx,2
1186
	ja	find_label
1187
	inc	esi
1188
	jb	get_current_offset_id
1189
	inc	esi
1190
	cmp	byte [esi-1],'$'
1191
	je	get_org_origin_id
1192
	sub	esi,ecx
1193
	jmp	find_label
1194
      get_current_offset_id:
31 halyavin 1195
	xor	eax,eax
157 heavyiron 1196
	ret
1197
      get_counter_id:
31 halyavin 1198
	mov	eax,1
157 heavyiron 1199
	ret
1200
      get_timestamp_id:
31 halyavin 1201
	mov	eax,2
157 heavyiron 1202
	ret
1203
      get_org_origin_id:
31 halyavin 1204
	mov	eax,3
157 heavyiron 1205
	ret
1206
      get_predefined_id:
31 halyavin 1207
	cmp	ecx,2
157 heavyiron 1208
	ja	find_label
1209
	inc	esi
1210
	cmp	cl,1
1211
	je	get_counter_id
1212
	lods	byte [esi]
1213
	mov	ebx,characters
1214
	xlat	[ebx]
1215
	cmp	al,'t'
1216
	je	get_timestamp_id
1217
	sub	esi,2
1218
      find_label:
31 halyavin 1219
	xor	ebx,ebx
157 heavyiron 1220
	mov	eax,2166136261
1221
	mov	ebp,16777619
1222
      hash_label:
31 halyavin 1223
	xor	al,[esi+ebx]
157 heavyiron 1224
	mul	ebp
1225
	inc	bl
1226
	cmp	bl,cl
1227
	jb	hash_label
1228
	mov	ebp,eax
1229
	shl	eax,8
1230
	and	ebp,0FFh shl 24
1231
	xor	ebp,eax
1232
	or	ebp,ebx
1233
	mov	[label_hash],ebp
1234
	push	edi esi
1235
	push	ecx
1236
	mov	ecx,32
1237
	mov	ebx,hash_tree
1238
      follow_tree:
31 halyavin 1239
	mov	edx,[ebx]
157 heavyiron 1240
	or	edx,edx
1241
	jz	extend_tree
1242
	xor	eax,eax
1243
	shl	ebp,1
1244
	adc	eax,0
1245
	lea	ebx,[edx+eax*4]
1246
	dec	ecx
1247
	jnz	follow_tree
1248
	mov	[label_leaf],ebx
1249
	pop	edx
1250
	mov	eax,[ebx]
1251
	or	eax,eax
1252
	jz	add_label
1253
	mov	ebx,esi
1254
	mov	ebp,[label_hash]
1255
      compare_labels:
31 halyavin 1256
	mov	esi,ebx
157 heavyiron 1257
	mov	ecx,edx
1258
	mov	edi,[eax+4]
1259
	mov	edi,[edi+24]
1260
	repe	cmps byte [esi],[edi]
1261
	je	label_found
1262
	mov	eax,[eax]
1263
	or	eax,eax
1264
	jnz	compare_labels
1265
	jmp	add_label
1266
      label_found:
31 halyavin 1267
	add	esp,4
157 heavyiron 1268
	pop	edi
1269
	mov	eax,[eax+4]
1270
	ret
1271
      extend_tree:
31 halyavin 1272
	mov	edx,[free_additional_memory]
157 heavyiron 1273
	lea	eax,[edx+8]
1274
	cmp	eax,[additional_memory_end]
1275
	ja	out_of_memory
1276
	mov	[free_additional_memory],eax
1277
	xor	eax,eax
1278
	mov	[edx],eax
1279
	mov	[edx+4],eax
1280
	shl	ebp,1
1281
	adc	eax,0
1282
	mov	[ebx],edx
1283
	lea	ebx,[edx+eax*4]
1284
	dec	ecx
1285
	jnz	extend_tree
1286
	mov	[label_leaf],ebx
1287
	pop	edx
1288
      add_label:
31 halyavin 1289
	mov	ecx,edx
157 heavyiron 1290
	pop	esi
1291
	cmp	byte [esi-2],0
1292
	je	label_name_ok
1293
	mov	al,[esi]
1294
	cmp	al,30h
1295
	jb	name_first_char_ok
1296
	cmp	al,39h
1297
	jbe	invalid_name
1298
      name_first_char_ok:
31 halyavin 1299
	cmp	al,'$'
340 heavyiron 1300
	jne	check_for_reserved_word
1301
	cmp	ecx,1
157 heavyiron 1302
	jne	invalid_name
340 heavyiron 1303
      reserved_word:
1304
	mov	eax,0Fh
1305
	pop	edi
1306
	ret
1307
      check_for_reserved_word:
31 halyavin 1308
	call	get_instruction
157 heavyiron 1309
	jnc	reserved_word
1310
	call	get_data_directive
1311
	jnc	reserved_word
1312
	call	get_symbol
1313
	jnc	reserved_word
1314
	sub	esi,2
1315
	mov	edi,operators
1316
	call	get_operator
1317
	or	al,al
1318
	jnz	reserved_word
1319
	mov	edi,single_operand_operators
1320
	call	get_operator
1321
	or	al,al
1322
	jnz	reserved_word
1323
	mov	edi,directive_operators
1324
	call	get_operator
1325
	or	al,al
1326
	jnz	reserved_word
1327
	inc	esi
1328
	movzx	ecx,byte [esi]
1329
	inc	esi
1330
      label_name_ok:
31 halyavin 1331
	mov	edx,[free_additional_memory]
157 heavyiron 1332
	lea	eax,[edx+8]
1333
	cmp	eax,[additional_memory_end]
1334
	ja	out_of_memory
1335
	mov	[free_additional_memory],eax
1336
	mov	ebx,esi
1337
	add	esi,ecx
1338
	mov	eax,[label_leaf]
1339
	mov	edi,[eax]
1340
	mov	[edx],edi
1341
	mov	[eax],edx
1342
	call	allocate_label
1343
	mov	[edx+4],eax
1344
	mov	[eax+24],ebx
1345
	pop	edi
1346
	ret
1347
      allocate_label:
109 heavyiron 1348
	mov	eax,[labels_list]
157 heavyiron 1349
	mov	ecx,LABEL_STRUCTURE_SIZE shr 2
1350
      initialize_label:
109 heavyiron 1351
	sub	eax,4
157 heavyiron 1352
	mov	dword [eax],0
1353
	loop	initialize_label
1354
	mov	[labels_list],eax
1355
	ret
1356
31 halyavin 1357
 
109 heavyiron 1358
>