Skip to content

Commit 7cf98d7

Browse files
committed
552/3192025 FX
1 parent 61716ed commit 7cf98d7

File tree

5 files changed

+284
-202
lines changed

5 files changed

+284
-202
lines changed

include/asm.hpp

Lines changed: 72 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,23 @@ namespace Virtual::Asm {
197197
// { "rdi", TokenType::Rdi},
198198
};
199199

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+
200213
struct Token {
201214
TokenType type;
202215
const char* value = nullptr;
216+
void* context;
203217

204218
void print() {
205219
const char* str = stringify_tokentype(type);
@@ -261,7 +275,8 @@ namespace Virtual::Asm {
261275
}
262276
if (*tk.value == '"' && getLastChar(tk.value) == '"') {
263277
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);
265280
return;
266281
}
267282
/*
@@ -375,6 +390,8 @@ namespace Virtual::Asm {
375390
std::unordered_map<const char*, size_t> labels;
376391
size_t entry = 0;
377392
Builder builder;
393+
const char* entry_name = nullptr;
394+
Code* code = nullptr;
378395
// mew::stack<Error>
379396

380397
Compiler(Lexer& lexer): lexer(lexer) {
@@ -431,6 +448,20 @@ namespace Virtual::Asm {
431448
}
432449
}
433450

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+
434465
void WriteArgTypedReg(Token& arg1) {
435466
switch(arg1.type) {
436467
case ALL_REG_CASE:
@@ -446,8 +477,7 @@ namespace Virtual::Asm {
446477
const char* data_name = arg2.value;
447478
switch (arg3.type) {
448479
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);
451481
break;
452482
default: MewUserAssert(false, "DATA DB ? unsupported arg type");
453483
}
@@ -458,8 +488,7 @@ namespace Virtual::Asm {
458488
const char* data_name = arg2.value;
459489
switch (arg3.type) {
460490
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);
463492
break;
464493
default: MewUserAssert(false, "DATA DA ? unsupported arg type");
465494
}
@@ -468,7 +497,7 @@ namespace Virtual::Asm {
468497
void puti(Token& arg1, size_t argc) {
469498
MewUserAssert(argc == 1 && arg1.type == TokenType::RdiOffset, "not match arg count");
470499
int offset = (int)arg1.value;
471-
builder << Virtual::Instruction_PUTI << offset;
500+
builder << Virtual::Instruction_PUTI << Virtual::Instruction_ST << offset;
472501
}
473502

474503
void puts(Token& arg1, size_t argc) {
@@ -583,6 +612,12 @@ namespace Virtual::Asm {
583612
builder.Jump(label_name);
584613
}
585614

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+
586621
void _je(Token& arg1, size_t argc) {
587622
MewUserAssert(argc == 1 && arg1.type == TokenType::Text, "not match arg count");
588623
const char* label_name = arg1.value;
@@ -619,19 +654,28 @@ namespace Virtual::Asm {
619654
builder.JumpIfMore(label_name);
620655
}
621656

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);
625662
}
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);
628669
}
670+
671+
// todo nexts
629672
void _mset(Token& arg1, size_t argc) {
630673
MewNotImpl();
631674
}
632675

633676
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) {
635679
auto& line = lexer.token_row[i];
636680
if (line.size() == 0) { continue; }
637681
size_t argc = line.size()-1;
@@ -644,6 +688,7 @@ namespace Virtual::Asm {
644688
this->db_data(line[2], line[3], argc);
645689
}
646690
} break;
691+
case TokenType::Entry: this->_entry(line[1], argc); break;
647692
// movements
648693
case TokenType::Ret: this->_ret(argc); break;
649694
case TokenType::Jmp: this->_jmp(line[1], argc); break;
@@ -676,12 +721,19 @@ namespace Virtual::Asm {
676721
case TokenType::And: this->_and(line[1], line[2], argc); break;
677722
case TokenType::Ls: this->_ls(line[1], line[2], argc); break;
678723
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;
679726
// todo nexts
680727
default: MewUserAssert(false, "NOT ASSERTED TOKEN TYPE");
681728
}
682729
}
730+
builder.CompleteEntry(this->entry_name);
683731
// builder.MarkLabel();
684732
}
733+
734+
Virtual::Code* gen_code() {
735+
return code == nullptr ? code = builder.Build(): code;
736+
}
685737
};
686738

687739

@@ -700,15 +752,20 @@ namespace Virtual::Asm {
700752
"L1:\n"
701753
" test \n"
702754
" jem LE1\n"
703-
" puti (rdi-4)\n"
704-
" inc (rdi-4)\n"
755+
" puti (rdi-8)\n"
756+
" inc (rdi-8)\n"
705757
" jmp L1\n"
706758
"LE1:\n"
707759
" push 0\n"
708760
" ret\n";
709761
Lexer lex(str);
710762
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");
712769
}
713770
};
714771
}

include/docs/virtual.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,44 @@ OPEN
4040
PUTC [char:2b]
4141
PUTI -offset:4b-
4242
PUTS <offset:4b>
43+
```
44+
45+
``` asm
46+
arg: rdi_offset | number | register
47+
label: string
48+
data: string
49+
50+
;; stack
51+
push <arg>
52+
pop
53+
;; matg
54+
add <arg> <arg>
55+
sub <arg> <arg>
56+
mul <arg> <arg>
57+
div <arg> <arg>
58+
inc <arg>
59+
dec <arg>
60+
xor <arg> <arg>
61+
or <arg> <arg>
62+
not <arg>
63+
and <arg> <arg>
64+
ls <arg> <arg>
65+
rs <arg> <arg>
66+
;; movement
67+
jmp <label>
68+
test -no-args-
69+
je <label>
70+
jel <label>
71+
jem <label>
72+
jne <label>
73+
jl <label>
74+
jm <label>
75+
mov <arg> <arg> ;; copy arg2 value to arg1
76+
swap <arg> <arg> ;; swap arg1 & arg2
77+
;; mset
78+
ret
79+
80+
putc <arg>
81+
puti <arg>
82+
puts <data>
4383
```

0 commit comments

Comments
 (0)