implemented string literals
This commit is contained in:
parent
fed3be5614
commit
e63e9ef891
|
@ -19,6 +19,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||||
let mut writer = BufWriter::new(&file);
|
let mut writer = BufWriter::new(&file);
|
||||||
|
|
||||||
// println!("{}", tokens.len());
|
// println!("{}", tokens.len());
|
||||||
|
let mut strings: Vec<String> = Vec::new();
|
||||||
|
|
||||||
writeln!(writer, "BITS 64")?;
|
writeln!(writer, "BITS 64")?;
|
||||||
writeln!(writer, "segment .text")?;
|
writeln!(writer, "segment .text")?;
|
||||||
|
@ -67,27 +68,34 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||||
writeln!(writer, "addr_{}:", ti)?;
|
writeln!(writer, "addr_{}:", ti)?;
|
||||||
match token.typ {
|
match token.typ {
|
||||||
// stack
|
// stack
|
||||||
OpType::Push => {
|
OpType::PushInt => {
|
||||||
writeln!(writer, " ;; -- push {} --", token.value)?;
|
writeln!(writer, " ;; -- push int {}", token.value)?;
|
||||||
writeln!(writer, " mov rax, {}", token.value)?;
|
writeln!(writer, " mov rax, {}", token.value)?;
|
||||||
writeln!(writer, " push rax")?;
|
writeln!(writer, " push rax")?;
|
||||||
ti += 1;
|
ti += 1;
|
||||||
|
|
||||||
},
|
},
|
||||||
|
OpType::PushStr => {
|
||||||
|
writeln!(writer, " ;; -- push str \"{}\"", token.text)?;
|
||||||
|
writeln!(writer, " mov rax, {}", token.text.len())?;
|
||||||
|
writeln!(writer, " push rax")?;
|
||||||
|
writeln!(writer, " push str_{}", strings.len())?;
|
||||||
|
strings.push(token.text.clone());
|
||||||
|
ti += 1;
|
||||||
|
}
|
||||||
OpType::Drop => {
|
OpType::Drop => {
|
||||||
writeln!(writer, " ;; -- drop --")?;
|
writeln!(writer, " ;; -- drop")?;
|
||||||
writeln!(writer, " pop rax")?;
|
writeln!(writer, " pop rax")?;
|
||||||
ti += 1;
|
ti += 1;
|
||||||
},
|
},
|
||||||
OpType::Print => {
|
OpType::Print => {
|
||||||
writeln!(writer, " ;; -- print --")?;
|
writeln!(writer, " ;; -- print")?;
|
||||||
writeln!(writer, " pop rdi")?;
|
writeln!(writer, " pop rdi")?;
|
||||||
writeln!(writer, " call print")?;
|
writeln!(writer, " call print")?;
|
||||||
ti += 1;
|
ti += 1;
|
||||||
},
|
},
|
||||||
|
|
||||||
OpType::Dup => {
|
OpType::Dup => {
|
||||||
writeln!(writer, " ;; -- dup --")?;
|
writeln!(writer, " ;; -- dup")?;
|
||||||
writeln!(writer, " pop rax")?;
|
writeln!(writer, " pop rax")?;
|
||||||
writeln!(writer, " push rax")?;
|
writeln!(writer, " push rax")?;
|
||||||
writeln!(writer, " push rax")?;
|
writeln!(writer, " push rax")?;
|
||||||
|
@ -95,7 +103,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||||
ti += 1;
|
ti += 1;
|
||||||
},
|
},
|
||||||
OpType::Dup2 => {
|
OpType::Dup2 => {
|
||||||
writeln!(writer, " ;; -- 2dup --")?;
|
writeln!(writer, " ;; -- 2dup")?;
|
||||||
writeln!(writer, " pop rbx")?;
|
writeln!(writer, " pop rbx")?;
|
||||||
writeln!(writer, " pop rax")?;
|
writeln!(writer, " pop rax")?;
|
||||||
writeln!(writer, " push rax")?;
|
writeln!(writer, " push rax")?;
|
||||||
|
@ -107,7 +115,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||||
},
|
},
|
||||||
|
|
||||||
OpType::Rot => {
|
OpType::Rot => {
|
||||||
writeln!(writer, " ;; -- rot --")?;
|
writeln!(writer, " ;; -- rot")?;
|
||||||
writeln!(writer, " pop rax")?;
|
writeln!(writer, " pop rax")?;
|
||||||
writeln!(writer, " pop rbx")?;
|
writeln!(writer, " pop rbx")?;
|
||||||
writeln!(writer, " pop rcx")?;
|
writeln!(writer, " pop rcx")?;
|
||||||
|
@ -118,7 +126,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||||
ti += 1;
|
ti += 1;
|
||||||
},
|
},
|
||||||
OpType::Swap => {
|
OpType::Swap => {
|
||||||
writeln!(writer, " ;; -- swap --")?;
|
writeln!(writer, " ;; -- swap")?;
|
||||||
writeln!(writer, " pop rax")?;
|
writeln!(writer, " pop rax")?;
|
||||||
writeln!(writer, " pop rbx")?;
|
writeln!(writer, " pop rbx")?;
|
||||||
writeln!(writer, " push rax")?;
|
writeln!(writer, " push rax")?;
|
||||||
|
@ -127,7 +135,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||||
ti += 1;
|
ti += 1;
|
||||||
},
|
},
|
||||||
OpType::Over => {
|
OpType::Over => {
|
||||||
writeln!(writer, " ;; -- over --")?;
|
writeln!(writer, " ;; -- over")?;
|
||||||
writeln!(writer, " pop rax")?;
|
writeln!(writer, " pop rax")?;
|
||||||
writeln!(writer, " pop rbx")?;
|
writeln!(writer, " pop rbx")?;
|
||||||
writeln!(writer, " push rbx")?;
|
writeln!(writer, " push rbx")?;
|
||||||
|
@ -139,12 +147,12 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||||
|
|
||||||
//mem
|
//mem
|
||||||
OpType::Mem => {
|
OpType::Mem => {
|
||||||
writeln!(writer, " ;; -- mem --")?;
|
writeln!(writer, " ;; -- mem")?;
|
||||||
writeln!(writer, " push mem")?;
|
writeln!(writer, " push mem")?;
|
||||||
ti += 1;
|
ti += 1;
|
||||||
}
|
}
|
||||||
OpType::Load8 => {
|
OpType::Load8 => {
|
||||||
writeln!(writer, " ;; -- load --")?;
|
writeln!(writer, " ;; -- load")?;
|
||||||
writeln!(writer, " pop rax")?;
|
writeln!(writer, " pop rax")?;
|
||||||
writeln!(writer, " xor rbx, rbx")?;
|
writeln!(writer, " xor rbx, rbx")?;
|
||||||
writeln!(writer, " mov bl, [rax]")?;
|
writeln!(writer, " mov bl, [rax]")?;
|
||||||
|
@ -153,7 +161,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||||
}
|
}
|
||||||
|
|
||||||
OpType::Store8 => {
|
OpType::Store8 => {
|
||||||
writeln!(writer, " ;; -- store --")?;
|
writeln!(writer, " ;; -- store")?;
|
||||||
writeln!(writer, " pop rbx")?;
|
writeln!(writer, " pop rbx")?;
|
||||||
writeln!(writer, " pop rax")?;
|
writeln!(writer, " pop rax")?;
|
||||||
writeln!(writer, " mov [rax], bl")?;
|
writeln!(writer, " mov [rax], bl")?;
|
||||||
|
@ -162,7 +170,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||||
|
|
||||||
// math
|
// math
|
||||||
OpType::Plus => {
|
OpType::Plus => {
|
||||||
writeln!(writer, " ;; -- plus --")?;
|
writeln!(writer, " ;; -- plus")?;
|
||||||
writeln!(writer, " pop rax")?;
|
writeln!(writer, " pop rax")?;
|
||||||
writeln!(writer, " pop rbx")?;
|
writeln!(writer, " pop rbx")?;
|
||||||
writeln!(writer, " add rax, rbx")?;
|
writeln!(writer, " add rax, rbx")?;
|
||||||
|
@ -170,7 +178,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||||
ti += 1;
|
ti += 1;
|
||||||
},
|
},
|
||||||
OpType::Minus => {
|
OpType::Minus => {
|
||||||
writeln!(writer, " ;; -- minus --")?;
|
writeln!(writer, " ;; -- minus")?;
|
||||||
writeln!(writer, " pop rax")?;
|
writeln!(writer, " pop rax")?;
|
||||||
writeln!(writer, " pop rbx")?;
|
writeln!(writer, " pop rbx")?;
|
||||||
writeln!(writer, " sub rbx, rax")?;
|
writeln!(writer, " sub rbx, rax")?;
|
||||||
|
@ -178,7 +186,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||||
ti += 1;
|
ti += 1;
|
||||||
},
|
},
|
||||||
OpType::Equals => {
|
OpType::Equals => {
|
||||||
writeln!(writer, " ;; -- equals --")?;
|
writeln!(writer, " ;; -- equals")?;
|
||||||
writeln!(writer, " mov rcx, 0")?;
|
writeln!(writer, " mov rcx, 0")?;
|
||||||
writeln!(writer, " mov rdx, 1")?;
|
writeln!(writer, " mov rdx, 1")?;
|
||||||
writeln!(writer, " pop rax")?;
|
writeln!(writer, " pop rax")?;
|
||||||
|
@ -190,7 +198,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||||
|
|
||||||
},
|
},
|
||||||
OpType::Lt => {
|
OpType::Lt => {
|
||||||
writeln!(writer, " ;; -- lt --")?;
|
writeln!(writer, " ;; -- lt")?;
|
||||||
writeln!(writer, " mov rcx, 0")?;
|
writeln!(writer, " mov rcx, 0")?;
|
||||||
writeln!(writer, " mov rdx, 1")?;
|
writeln!(writer, " mov rdx, 1")?;
|
||||||
writeln!(writer, " pop rbx")?;
|
writeln!(writer, " pop rbx")?;
|
||||||
|
@ -202,7 +210,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||||
|
|
||||||
},
|
},
|
||||||
OpType::Gt => {
|
OpType::Gt => {
|
||||||
writeln!(writer, " ;; -- gt --")?;
|
writeln!(writer, " ;; -- gt")?;
|
||||||
writeln!(writer, " mov rcx, 0")?;
|
writeln!(writer, " mov rcx, 0")?;
|
||||||
writeln!(writer, " mov rdx, 1")?;
|
writeln!(writer, " mov rdx, 1")?;
|
||||||
writeln!(writer, " pop rbx")?;
|
writeln!(writer, " pop rbx")?;
|
||||||
|
@ -214,7 +222,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||||
|
|
||||||
},
|
},
|
||||||
OpType::Band => {
|
OpType::Band => {
|
||||||
writeln!(writer, " ;; -- band --")?;
|
writeln!(writer, " ;; -- band")?;
|
||||||
writeln!(writer, " pop rax")?;
|
writeln!(writer, " pop rax")?;
|
||||||
writeln!(writer, " pop rbx")?;
|
writeln!(writer, " pop rbx")?;
|
||||||
writeln!(writer, " and rbx, rax")?;
|
writeln!(writer, " and rbx, rax")?;
|
||||||
|
@ -222,7 +230,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||||
ti += 1;
|
ti += 1;
|
||||||
},
|
},
|
||||||
OpType::Bor => {
|
OpType::Bor => {
|
||||||
writeln!(writer, " ;; -- bor --")?;
|
writeln!(writer, " ;; -- bor")?;
|
||||||
writeln!(writer, " pop rax")?;
|
writeln!(writer, " pop rax")?;
|
||||||
writeln!(writer, " pop rbx")?;
|
writeln!(writer, " pop rbx")?;
|
||||||
writeln!(writer, " or rbx, rax")?;
|
writeln!(writer, " or rbx, rax")?;
|
||||||
|
@ -230,7 +238,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||||
ti += 1;
|
ti += 1;
|
||||||
},
|
},
|
||||||
OpType::Shr => {
|
OpType::Shr => {
|
||||||
writeln!(writer, " ;; -- shr --")?;
|
writeln!(writer, " ;; -- shr")?;
|
||||||
writeln!(writer, " pop rcx")?;
|
writeln!(writer, " pop rcx")?;
|
||||||
writeln!(writer, " pop rbx")?;
|
writeln!(writer, " pop rbx")?;
|
||||||
writeln!(writer, " shr rbx, cl")?;
|
writeln!(writer, " shr rbx, cl")?;
|
||||||
|
@ -238,7 +246,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||||
ti += 1;
|
ti += 1;
|
||||||
},
|
},
|
||||||
OpType::Shl => {
|
OpType::Shl => {
|
||||||
writeln!(writer, " ;; -- shl --")?;
|
writeln!(writer, " ;; -- shl")?;
|
||||||
writeln!(writer, " pop rcx")?;
|
writeln!(writer, " pop rcx")?;
|
||||||
writeln!(writer, " pop rbx")?;
|
writeln!(writer, " pop rbx")?;
|
||||||
writeln!(writer, " shl rbx, cl")?;
|
writeln!(writer, " shl rbx, cl")?;
|
||||||
|
@ -246,7 +254,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||||
ti += 1;
|
ti += 1;
|
||||||
},
|
},
|
||||||
OpType::Div => {
|
OpType::Div => {
|
||||||
writeln!(writer, " ;; -- div --")?;
|
writeln!(writer, " ;; -- div")?;
|
||||||
writeln!(writer, " xor rdx, rdx")?;
|
writeln!(writer, " xor rdx, rdx")?;
|
||||||
writeln!(writer, " pop rbx")?;
|
writeln!(writer, " pop rbx")?;
|
||||||
writeln!(writer, " pop rax")?;
|
writeln!(writer, " pop rax")?;
|
||||||
|
@ -256,7 +264,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||||
ti += 1;
|
ti += 1;
|
||||||
},
|
},
|
||||||
OpType::Mul => {
|
OpType::Mul => {
|
||||||
writeln!(writer, " ;; -- mul --")?;
|
writeln!(writer, " ;; -- mul")?;
|
||||||
writeln!(writer, " pop rax")?;
|
writeln!(writer, " pop rax")?;
|
||||||
writeln!(writer, " pop rbx")?;
|
writeln!(writer, " pop rbx")?;
|
||||||
writeln!(writer, " mul rbx")?;
|
writeln!(writer, " mul rbx")?;
|
||||||
|
@ -268,44 +276,44 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||||
|
|
||||||
// block
|
// block
|
||||||
OpType::If => {
|
OpType::If => {
|
||||||
writeln!(writer, " ;; -- if --")?;
|
writeln!(writer, " ;; -- if")?;
|
||||||
writeln!(writer, " pop rax")?;
|
writeln!(writer, " pop rax")?;
|
||||||
writeln!(writer, " test rax, rax")?;
|
writeln!(writer, " test rax, rax")?;
|
||||||
writeln!(writer, " jz addr_{}", token.jmp)?;
|
writeln!(writer, " jz addr_{}", token.jmp)?;
|
||||||
ti += 1;
|
ti += 1;
|
||||||
},
|
},
|
||||||
OpType::Else => {
|
OpType::Else => {
|
||||||
writeln!(writer, " ;; -- else --")?;
|
writeln!(writer, " ;; -- else")?;
|
||||||
writeln!(writer, " jmp addr_{}", token.jmp)?;
|
writeln!(writer, " jmp addr_{}", token.jmp)?;
|
||||||
ti += 1;
|
ti += 1;
|
||||||
},
|
},
|
||||||
OpType::While => {
|
OpType::While => {
|
||||||
writeln!(writer, " ;; -- while --")?;
|
writeln!(writer, " ;; -- while")?;
|
||||||
ti += 1;
|
ti += 1;
|
||||||
}
|
}
|
||||||
OpType::Do => {
|
OpType::Do => {
|
||||||
writeln!(writer, " ;; -- do --")?;
|
writeln!(writer, " ;; -- do")?;
|
||||||
writeln!(writer, " pop rax")?;
|
writeln!(writer, " pop rax")?;
|
||||||
writeln!(writer, " test rax, rax")?;
|
writeln!(writer, " test rax, rax")?;
|
||||||
writeln!(writer, " jz addr_{}", token.jmp)?;
|
writeln!(writer, " jz addr_{}", token.jmp)?;
|
||||||
ti += 1;
|
ti += 1;
|
||||||
}
|
}
|
||||||
OpType::End => {
|
OpType::End => {
|
||||||
writeln!(writer, " ;; -- end --")?;
|
writeln!(writer, " ;; -- end")?;
|
||||||
if ti + 1 != token.jmp as usize {
|
if ti + 1 != token.jmp as usize {
|
||||||
writeln!(writer, " jmp addr_{}", token.jmp)?;
|
writeln!(writer, " jmp addr_{}", token.jmp)?;
|
||||||
}
|
}
|
||||||
ti += 1;
|
ti += 1;
|
||||||
},
|
},
|
||||||
OpType::Syscall0 => {
|
OpType::Syscall0 => {
|
||||||
writeln!(writer, " ;; -- syscall0 --")?;
|
writeln!(writer, " ;; -- syscall0")?;
|
||||||
writeln!(writer, " pop rax")?;
|
writeln!(writer, " pop rax")?;
|
||||||
writeln!(writer, " syscall")?;
|
writeln!(writer, " syscall")?;
|
||||||
writeln!(writer, " push rax")?;
|
writeln!(writer, " push rax")?;
|
||||||
ti += 1;
|
ti += 1;
|
||||||
},
|
},
|
||||||
OpType::Syscall1 => {
|
OpType::Syscall1 => {
|
||||||
writeln!(writer, " ;; -- syscall1 --")?;
|
writeln!(writer, " ;; -- syscall1")?;
|
||||||
writeln!(writer, " pop rax")?;
|
writeln!(writer, " pop rax")?;
|
||||||
writeln!(writer, " pop rdi")?;
|
writeln!(writer, " pop rdi")?;
|
||||||
writeln!(writer, " syscall")?;
|
writeln!(writer, " syscall")?;
|
||||||
|
@ -313,7 +321,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||||
ti += 1;
|
ti += 1;
|
||||||
},
|
},
|
||||||
OpType::Syscall2 => {
|
OpType::Syscall2 => {
|
||||||
writeln!(writer, " ;; -- syscall2 --")?;
|
writeln!(writer, " ;; -- syscall2")?;
|
||||||
writeln!(writer, " pop rax")?;
|
writeln!(writer, " pop rax")?;
|
||||||
writeln!(writer, " pop rdi")?;
|
writeln!(writer, " pop rdi")?;
|
||||||
writeln!(writer, " pop rsi")?;
|
writeln!(writer, " pop rsi")?;
|
||||||
|
@ -322,7 +330,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||||
ti += 1;
|
ti += 1;
|
||||||
},
|
},
|
||||||
OpType::Syscall3 => {
|
OpType::Syscall3 => {
|
||||||
writeln!(writer, " ;; -- syscall3 --")?;
|
writeln!(writer, " ;; -- syscall3")?;
|
||||||
writeln!(writer, " pop rax")?;
|
writeln!(writer, " pop rax")?;
|
||||||
writeln!(writer, " pop rdi")?;
|
writeln!(writer, " pop rdi")?;
|
||||||
writeln!(writer, " pop rsi")?;
|
writeln!(writer, " pop rsi")?;
|
||||||
|
@ -333,7 +341,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||||
ti += 1;
|
ti += 1;
|
||||||
},
|
},
|
||||||
OpType::Syscall4 => {
|
OpType::Syscall4 => {
|
||||||
writeln!(writer, " ;; -- syscall4 --")?;
|
writeln!(writer, " ;; -- syscall4")?;
|
||||||
writeln!(writer, " pop rax")?;
|
writeln!(writer, " pop rax")?;
|
||||||
writeln!(writer, " pop rdi")?;
|
writeln!(writer, " pop rdi")?;
|
||||||
writeln!(writer, " pop rsi")?;
|
writeln!(writer, " pop rsi")?;
|
||||||
|
@ -344,7 +352,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||||
ti += 1;
|
ti += 1;
|
||||||
},
|
},
|
||||||
OpType::Syscall5 => {
|
OpType::Syscall5 => {
|
||||||
writeln!(writer, " ;; -- syscall5 --")?;
|
writeln!(writer, " ;; -- syscall5")?;
|
||||||
writeln!(writer, " pop rax")?;
|
writeln!(writer, " pop rax")?;
|
||||||
writeln!(writer, " pop rdi")?;
|
writeln!(writer, " pop rdi")?;
|
||||||
writeln!(writer, " pop rsi")?;
|
writeln!(writer, " pop rsi")?;
|
||||||
|
@ -356,7 +364,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||||
ti += 1;
|
ti += 1;
|
||||||
},
|
},
|
||||||
OpType::Syscall6 => {
|
OpType::Syscall6 => {
|
||||||
writeln!(writer, " ;; -- syscall6 --")?;
|
writeln!(writer, " ;; -- syscall6")?;
|
||||||
writeln!(writer, " pop rax")?;
|
writeln!(writer, " pop rax")?;
|
||||||
writeln!(writer, " pop rdi")?;
|
writeln!(writer, " pop rdi")?;
|
||||||
writeln!(writer, " pop rsi")?;
|
writeln!(writer, " pop rsi")?;
|
||||||
|
@ -374,6 +382,12 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||||
writeln!(writer, " mov rax, 60")?;
|
writeln!(writer, " mov rax, 60")?;
|
||||||
writeln!(writer, " mov rdi, 0")?;
|
writeln!(writer, " mov rdi, 0")?;
|
||||||
writeln!(writer, " syscall")?;
|
writeln!(writer, " syscall")?;
|
||||||
|
writeln!(writer, "segment .data")?;
|
||||||
|
for s in 0..strings.len() {
|
||||||
|
let s_chars = strings[s].chars().map(|c| (c as u32).to_string()).collect::<Vec<String>>();
|
||||||
|
let s_list = s_chars.join(",");
|
||||||
|
writeln!(writer, " str_{}: db {} ; {}", s, s_list, strings[s].escape_default())?;
|
||||||
|
}
|
||||||
|
|
||||||
writeln!(writer, "segment .bss")?;
|
writeln!(writer, "segment .bss")?;
|
||||||
writeln!(writer, "mem: resb {}", crate::compile::MEM_SZ)?;
|
writeln!(writer, "mem: resb {}", crate::compile::MEM_SZ)?;
|
||||||
|
|
|
@ -2,3 +2,4 @@ pub mod linux_x86_64;
|
||||||
pub mod commands;
|
pub mod commands;
|
||||||
|
|
||||||
pub const MEM_SZ: u32 = 640 * 1000; // 4kb
|
pub const MEM_SZ: u32 = 640 * 1000; // 4kb
|
||||||
|
pub const STRING_SZ: u32 = 640 * 1000; // 4kb
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
pub enum OpType {
|
pub enum OpType {
|
||||||
|
|
||||||
// stack
|
// stack
|
||||||
Push,
|
PushInt,
|
||||||
|
PushStr,
|
||||||
Drop,
|
Drop,
|
||||||
Print,
|
Print,
|
||||||
Dup,
|
Dup,
|
||||||
|
@ -54,16 +55,20 @@ pub enum OpType {
|
||||||
pub struct Operator {
|
pub struct Operator {
|
||||||
pub typ: OpType,
|
pub typ: OpType,
|
||||||
pub value: i64,
|
pub value: i64,
|
||||||
|
pub text: String, //? only used for OpType::PushStr
|
||||||
|
pub addr: i64, //? only used for OpType::PushStr
|
||||||
pub jmp: i32,
|
pub jmp: i32,
|
||||||
pub pos: (String, u32, u32)
|
pub pos: (String, u32, u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Operator {
|
impl Operator {
|
||||||
pub fn new(typ: OpType, value: i64, file: String, row: u32, col: u32) -> Self {
|
pub fn new(typ: OpType, value: i64, text: String, file: String, row: u32, col: u32) -> Self {
|
||||||
Self {
|
Self {
|
||||||
typ,
|
typ,
|
||||||
value,
|
value,
|
||||||
jmp: 0,
|
jmp: 0,
|
||||||
|
addr: -1,
|
||||||
|
text,
|
||||||
pos: (file, row, col)
|
pos: (file, row, col)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,10 +84,10 @@ pub struct Token {
|
||||||
pub typ: TokenType
|
pub typ: TokenType
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum TokenType {
|
pub enum TokenType {
|
||||||
Word,
|
Word,
|
||||||
Int,
|
Int,
|
||||||
// String,
|
String,
|
||||||
//TODO: Add char
|
//TODO: Add char
|
||||||
}
|
}
|
|
@ -17,7 +17,8 @@ fn stack_pop(stack: &mut Vec<u64>, pos: &(String, u32, u32)) -> Result<u64> {
|
||||||
pub fn run(tokens: Vec<crate::constants::Operator>) -> Result<()>{
|
pub fn run(tokens: Vec<crate::constants::Operator>) -> Result<()>{
|
||||||
let mut stack: Vec<u64> = Vec::new();
|
let mut stack: Vec<u64> = Vec::new();
|
||||||
let mut ti = 0;
|
let mut ti = 0;
|
||||||
let mut mem: Vec<u8> = vec![0; crate::compile::MEM_SZ as usize];
|
let mut mem: Vec<u8> = vec![0; crate::compile::MEM_SZ as usize + crate::compile::STRING_SZ as usize];
|
||||||
|
let mut string_idx = 0;
|
||||||
// for token in &tokens {
|
// for token in &tokens {
|
||||||
// println!("{{typ: \"{:?}\", val: {}, jmp: {}}}", token.typ, token.value, token.jmp);
|
// println!("{{typ: \"{:?}\", val: {}, jmp: {}}}", token.typ, token.value, token.jmp);
|
||||||
|
|
||||||
|
@ -29,10 +30,27 @@ pub fn run(tokens: Vec<crate::constants::Operator>) -> Result<()>{
|
||||||
match token.typ {
|
match token.typ {
|
||||||
|
|
||||||
// stack
|
// stack
|
||||||
OpType::Push => {
|
OpType::PushInt => {
|
||||||
stack.push(token.value as u64);
|
stack.push(token.value as u64);
|
||||||
ti += 1;
|
ti += 1;
|
||||||
},
|
},
|
||||||
|
OpType::PushStr => {
|
||||||
|
if token.addr < 0 {
|
||||||
|
stack.push(token.text.len() as u64); // string len
|
||||||
|
stack.push(string_idx + crate::compile::MEM_SZ as u64);
|
||||||
|
|
||||||
|
for c in token.text.bytes() {
|
||||||
|
mem[crate::compile::MEM_SZ as usize + string_idx as usize] = c;
|
||||||
|
string_idx += 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
stack.push(token.text.len() as u64);
|
||||||
|
stack.push(token.addr as u64);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ti += 1;
|
||||||
|
},
|
||||||
OpType::Drop => {
|
OpType::Drop => {
|
||||||
stack.pop();
|
stack.pop();
|
||||||
ti += 1;
|
ti += 1;
|
||||||
|
@ -249,5 +267,7 @@ pub fn run(tokens: Vec<crate::constants::Operator>) -> Result<()>{
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
66
src/lexer.rs
66
src/lexer.rs
|
@ -2,19 +2,25 @@
|
||||||
use crate::constants::{Token, TokenType};
|
use crate::constants::{Token, TokenType};
|
||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
|
|
||||||
fn lex_word(s: String) -> (TokenType, String) {
|
fn lex_word(s: String, tok_type: TokenType) -> (TokenType, String) {
|
||||||
match s {
|
match s {
|
||||||
s if s.parse::<u64>().is_ok() => { // negative numbers not yet implemented
|
s if s.parse::<u64>().is_ok() && tok_type == TokenType::Word => { // negative numbers not yet implemented
|
||||||
return (TokenType::Int, s);
|
return (TokenType::Int, s);
|
||||||
},
|
},
|
||||||
s => {
|
s if tok_type == TokenType::Word => {
|
||||||
return(TokenType::Word, s);
|
return (TokenType::Word, s);
|
||||||
|
},
|
||||||
|
s if tok_type == TokenType::String => {
|
||||||
|
return (tok_type, s);
|
||||||
}
|
}
|
||||||
|
_ => panic!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_col<F>(text: String, mut col: u32, predicate: F) -> Result<u32> where F: Fn(char) -> bool {
|
pub fn find_col<F>(text: String, mut col: u32, predicate: F) -> Result<u32> where F: Fn(char, char) -> bool {
|
||||||
while (col as usize) < text.len() && !predicate(text.chars().nth(col as usize).unwrap()) {
|
let mut last = '\0';
|
||||||
|
while (col as usize) < text.len() && !predicate(text.chars().nth(col as usize).unwrap(), last) {
|
||||||
|
last = text.chars().nth(col as usize).unwrap();
|
||||||
col += 1;
|
col += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,14 +28,28 @@ pub fn find_col<F>(text: String, mut col: u32, predicate: F) -> Result<u32> wher
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: Implement multiline strings
|
||||||
|
fn lex_line(text: String) -> Result<Vec<(u32, String, TokenType)>> {
|
||||||
|
let mut tokens: Vec<(u32, String, TokenType)> = Vec::new();
|
||||||
|
|
||||||
fn lex_line(text: String) -> Result<Vec<(u32, String)>> {
|
let mut col = find_col(text.clone(), 0, |x, _| !x.is_whitespace())?;
|
||||||
let mut tokens: Vec<(u32, String)> = Vec::new();
|
|
||||||
|
|
||||||
let mut col = find_col(text.clone(), 0, |x| !x.is_whitespace())?;
|
|
||||||
let mut col_end: u32 = 0;
|
let mut col_end: u32 = 0;
|
||||||
while col_end < text.clone().len() as u32 {
|
while col_end < text.clone().len() as u32 {
|
||||||
col_end = find_col(text.clone(), col, |x| x.is_whitespace())?;
|
if &text[(col as usize)..(col + 1) as usize] == "\"" {
|
||||||
|
col_end = find_col(text.clone(), col + 1, |x, x2| x == '"' && x2 != '\\')?;
|
||||||
|
let t = &text[((col + 1) as usize)..(col_end as usize)];
|
||||||
|
let t = t.replace("\\n", "\n")
|
||||||
|
.replace("\\t", "\t")
|
||||||
|
.replace("\\r", "\r")
|
||||||
|
.replace("\\0", "\0");
|
||||||
|
if !t.is_empty() {
|
||||||
|
tokens.push((col, t.to_string(), TokenType::String));
|
||||||
|
}
|
||||||
|
col = find_col(text.clone(), col_end + 1, |x, _| !x.is_whitespace())?;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
col_end = find_col(text.clone(), col, |x, _| x.is_whitespace())?;
|
||||||
let t = &text[(col as usize)..((col_end as usize))];
|
let t = &text[(col as usize)..((col_end as usize))];
|
||||||
|
|
||||||
if t == "//" {
|
if t == "//" {
|
||||||
|
@ -37,14 +57,30 @@ fn lex_line(text: String) -> Result<Vec<(u32, String)>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !t.is_empty() {
|
if !t.is_empty() {
|
||||||
tokens.push((col, t.to_string()));
|
tokens.push((col, t.to_string(), TokenType::Word));
|
||||||
|
}
|
||||||
|
col = find_col(text.clone(), col_end, |x, _| !x.is_whitespace())?;
|
||||||
}
|
}
|
||||||
col = find_col(text.clone(), col_end, |x| !x.is_whitespace())?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(tokens)
|
Ok(tokens)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// fn lex_text(text: String) -> Result<Vec<Token>>{
|
||||||
|
// let tokens: Vec<Token> = Vec::new();
|
||||||
|
|
||||||
|
// let mut row = 0;
|
||||||
|
// let mut col = 0;
|
||||||
|
// let mut index = find_col(text.clone(), 0, |x| x.is_whitespace())?;
|
||||||
|
|
||||||
|
// while index < text.len() as u32 {
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Ok(tokens)
|
||||||
|
// }
|
||||||
|
|
||||||
pub fn lex(code: String, file: &String) -> Result<Vec<Token>> {
|
pub fn lex(code: String, file: &String) -> Result<Vec<Token>> {
|
||||||
let lines: Vec<(usize, &str)> = code
|
let lines: Vec<(usize, &str)> = code
|
||||||
.split(['\n', '\r'])
|
.split(['\n', '\r'])
|
||||||
|
@ -57,8 +93,8 @@ pub fn lex(code: String, file: &String) -> Result<Vec<Token>> {
|
||||||
|
|
||||||
for (row, line) in lines {
|
for (row, line) in lines {
|
||||||
let lt = lex_line(line)?;
|
let lt = lex_line(line)?;
|
||||||
for (col, tok) in lt {
|
for (col, tok, tok_type) in lt {
|
||||||
let (tok_type, tok) = lex_word(tok);
|
let (tok_type, tok) = lex_word(tok, tok_type);
|
||||||
let t = Token{
|
let t = Token{
|
||||||
file: file.clone(),
|
file: file.clone(),
|
||||||
line: row + 1,
|
line: row + 1,
|
||||||
|
|
|
@ -16,7 +16,7 @@ pub fn cross_ref(mut program: Vec<Operator>) -> Result<Vec<Operator>> {
|
||||||
let if_ip = stack.pop().unwrap();
|
let if_ip = stack.pop().unwrap();
|
||||||
if program[if_ip as usize].typ != OpType::If {
|
if program[if_ip as usize].typ != OpType::If {
|
||||||
util::logger::pos_error(&op.clone().pos,"'end' can only close 'if' blocks");
|
util::logger::pos_error(&op.clone().pos,"'end' can only close 'if' blocks");
|
||||||
std::process::exit(1); // idc
|
return Err(eyre!("Bad block"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// let mut if_og = &mut tokens[if_ip as usize];
|
// let mut if_og = &mut tokens[if_ip as usize];
|
||||||
|
@ -84,11 +84,14 @@ impl Parser {
|
||||||
match token.typ {
|
match token.typ {
|
||||||
TokenType::Word => {
|
TokenType::Word => {
|
||||||
let word_type = lookup_word(token.text.clone(), &pos)?;
|
let word_type = lookup_word(token.text.clone(), &pos)?;
|
||||||
tokens.push(Operator { typ: word_type , value: 0, jmp: 0, pos: pos });
|
tokens.push(Operator::new(word_type, 0, token.text.clone(), token.file.clone(), token.line, token.col));
|
||||||
},
|
},
|
||||||
TokenType::Int => {// negative numbers not yet implemented
|
TokenType::Int => {// negative numbers not yet implemented
|
||||||
tokens.push(Operator::new(OpType::Push, token.text.parse::<i64>()?, token.file.clone(), token.line, token.col));
|
tokens.push(Operator::new(OpType::PushInt, token.text.parse::<i64>()?, String::new(), token.file.clone(), token.line, token.col));
|
||||||
},
|
},
|
||||||
|
TokenType::String => {
|
||||||
|
tokens.push(Operator::new(OpType::PushStr, 0, token.text.clone(), token.file.clone(), token.line, token.col));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
2
test.mcl
2
test.mcl
|
@ -1 +1 @@
|
||||||
1 2 3 2dup print print print print print
|
"Hello world!\n\n\n\n\n\n" 1 1 syscall3 drop
|
1
tests/fail_unknown_word.mcl
Normal file
1
tests/fail_unknown_word.mcl
Normal file
|
@ -0,0 +1 @@
|
||||||
|
gftdesd5ryutfgyhibugtf6r4
|
Loading…
Reference in New Issue
Block a user