@@ -197,9 +197,23 @@ namespace Virtual::Asm {
197
197
// { "rdi", TokenType::Rdi},
198
198
};
199
199
200
+ struct DefaultTokenContext {
201
+ size_t char_idx;
202
+ };
203
+
204
+ namespace Contexts {
205
+ struct Number : DefaultTokenContext {
206
+ size_t size;
207
+ Number (size_t size): size(size) {}
208
+ };
209
+ using DataSize = Number;
210
+ using String = Number;
211
+ }
212
+
200
213
struct Token {
201
214
TokenType type;
202
215
const char * value = nullptr ;
216
+ void * context;
203
217
204
218
void print () {
205
219
const char * str = stringify_tokentype (type);
@@ -261,7 +275,8 @@ namespace Virtual::Asm {
261
275
}
262
276
if (*tk.value == ' "' && getLastChar (tk.value ) == ' "' ) {
263
277
tk.type = TokenType::String;
264
- tk.value = scopy (tk.value +1 , strlen (tk.value )-2 );
278
+ tk.context = new Contexts::String (strlen (tk.value )-2 );
279
+ tk.value = str_parse (tk.value +1 , strlen (tk.value )-2 );
265
280
return ;
266
281
}
267
282
/*
@@ -375,6 +390,8 @@ namespace Virtual::Asm {
375
390
std::unordered_map<const char *, size_t > labels;
376
391
size_t entry = 0 ;
377
392
Builder builder;
393
+ const char * entry_name = nullptr ;
394
+ Code* code = nullptr ;
378
395
// mew::stack<Error>
379
396
380
397
Compiler (Lexer& lexer): lexer(lexer) {
@@ -431,6 +448,20 @@ namespace Virtual::Asm {
431
448
}
432
449
}
433
450
451
+ void WriteArgTypedLValue (Token& arg1) {
452
+ switch (arg1.type ) {
453
+ case TokenType::RdiOffset:
454
+ builder << Virtual::Instruction_ST;
455
+ builder << (uint)arg1.value ;
456
+ break ;
457
+ case ALL_REG_CASE:
458
+ builder << Virtual::Instruction_REG;
459
+ writeReg (arg1.type );
460
+ break ;
461
+ default : MewUserAssert (false , " PUSH ? unsupported arg type" );
462
+ }
463
+ }
464
+
434
465
void WriteArgTypedReg (Token& arg1) {
435
466
switch (arg1.type ) {
436
467
case ALL_REG_CASE:
@@ -446,8 +477,7 @@ namespace Virtual::Asm {
446
477
const char * data_name = arg2.value ;
447
478
switch (arg3.type ) {
448
479
case TokenType::String:
449
- const char * data_value = arg3.value ;
450
- builder.AddData (data_name, data_value);
480
+ builder.AddData (data_name, (byte*)arg3.value , ((Contexts::String*)arg3.context )->size );
451
481
break ;
452
482
default : MewUserAssert (false , " DATA DB ? unsupported arg type" );
453
483
}
@@ -458,8 +488,7 @@ namespace Virtual::Asm {
458
488
const char * data_name = arg2.value ;
459
489
switch (arg3.type ) {
460
490
case TokenType::DataSize:
461
- int data_size = (int )arg3.value ;
462
- builder.AddDataAfter (data_name, data_size);
491
+ builder.AddDataAfter (data_name, (int )arg3.value );
463
492
break ;
464
493
default : MewUserAssert (false , " DATA DA ? unsupported arg type" );
465
494
}
@@ -468,7 +497,7 @@ namespace Virtual::Asm {
468
497
void puti (Token& arg1, size_t argc) {
469
498
MewUserAssert (argc == 1 && arg1.type == TokenType::RdiOffset, " not match arg count" );
470
499
int offset = (int )arg1.value ;
471
- builder << Virtual::Instruction_PUTI << offset;
500
+ builder << Virtual::Instruction_PUTI << Virtual::Instruction_ST << offset;
472
501
}
473
502
474
503
void puts (Token& arg1, size_t argc) {
@@ -583,6 +612,12 @@ namespace Virtual::Asm {
583
612
builder.Jump (label_name);
584
613
}
585
614
615
+ void _entry (Token& arg1, size_t argc) {
616
+ MewUserAssert (argc == 1 && arg1.type == TokenType::Text, " not match arg count" );
617
+ const char * label_name = arg1.value ;
618
+ this ->entry_name = label_name;
619
+ }
620
+
586
621
void _je (Token& arg1, size_t argc) {
587
622
MewUserAssert (argc == 1 && arg1.type == TokenType::Text, " not match arg count" );
588
623
const char * label_name = arg1.value ;
@@ -619,19 +654,28 @@ namespace Virtual::Asm {
619
654
builder.JumpIfMore (label_name);
620
655
}
621
656
622
- // todo nexts
623
- void _mov (Token& arg1, size_t argc) {
624
- MewNotImpl ();
657
+ void _mov (Token& arg1, Token& arg2, size_t argc) {
658
+ MewUserAssert (argc == 2 && arg1.type == TokenType::Text, " not match arg count" );
659
+ builder << Virtual::Instruction_MOV;
660
+ WriteArgTypedLValue (arg1);
661
+ WriteArgTypedLValue (arg2);
625
662
}
626
- void _swap (Token& arg1, size_t argc) {
627
- MewNotImpl ();
663
+
664
+ void _swap (Token& arg1, Token& arg2, size_t argc) {
665
+ MewUserAssert (argc == 2 && arg1.type == TokenType::Text, " not match arg count" );
666
+ builder << Virtual::Instruction_SWAP;
667
+ WriteArgTypedLValue (arg1);
668
+ WriteArgTypedLValue (arg2);
628
669
}
670
+
671
+ // todo nexts
629
672
void _mset (Token& arg1, size_t argc) {
630
673
MewNotImpl ();
631
674
}
632
675
633
676
void compile () {
634
- for (int i = 0 ; lexer.token_row .size (); ++i) {
677
+ builder.WaitEntry ();
678
+ for (int i = 0 ; i < lexer.token_row .size (); ++i) {
635
679
auto & line = lexer.token_row [i];
636
680
if (line.size () == 0 ) { continue ; }
637
681
size_t argc = line.size ()-1 ;
@@ -644,6 +688,7 @@ namespace Virtual::Asm {
644
688
this ->db_data (line[2 ], line[3 ], argc);
645
689
}
646
690
} break ;
691
+ case TokenType::Entry: this ->_entry (line[1 ], argc); break ;
647
692
// movements
648
693
case TokenType::Ret: this ->_ret (argc); break ;
649
694
case TokenType::Jmp: this ->_jmp (line[1 ], argc); break ;
@@ -676,12 +721,19 @@ namespace Virtual::Asm {
676
721
case TokenType::And: this ->_and (line[1 ], line[2 ], argc); break ;
677
722
case TokenType::Ls: this ->_ls (line[1 ], line[2 ], argc); break ;
678
723
case TokenType::Rs: this ->_rs (line[1 ], line[2 ], argc); break ;
724
+ case TokenType::Mov: this ->_mov (line[1 ], line[2 ], argc); break ;
725
+ case TokenType::Swap: this ->_swap (line[1 ], line[2 ], argc); break ;
679
726
// todo nexts
680
727
default : MewUserAssert (false , " NOT ASSERTED TOKEN TYPE" );
681
728
}
682
729
}
730
+ builder.CompleteEntry (this ->entry_name );
683
731
// builder.MarkLabel();
684
732
}
733
+
734
+ Virtual::Code* gen_code () {
735
+ return code == nullptr ? code = builder.Build (): code;
736
+ }
685
737
};
686
738
687
739
@@ -700,15 +752,20 @@ namespace Virtual::Asm {
700
752
" L1:\n "
701
753
" test \n "
702
754
" jem LE1\n "
703
- " puti (rdi-4 )\n "
704
- " inc (rdi-4 )\n "
755
+ " puti (rdi-8 )\n "
756
+ " inc (rdi-8 )\n "
705
757
" jmp L1\n "
706
758
" LE1:\n "
707
759
" push 0\n "
708
760
" ret\n " ;
709
761
Lexer lex (str);
710
762
Parser par (lex);
711
- lex.print ();
763
+ Compiler comp (lex);
764
+ // lex.print();
765
+ Code* code = comp.gen_code ();
766
+ Virtual::Execute (*code);
767
+ Virtual::Code_SaveFromFile (*code, " ./temp.nb" );
768
+ Virtual::Execute (" ./temp.nb" );
712
769
}
713
770
};
714
771
}
0 commit comments