add 'mem' and extent Token to have Token.jmp which is used in if, else, end, while blocks instead of Token.value
This commit is contained in:
@@ -61,6 +61,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||
|
||||
writeln!(writer, "addr_{}:", ti)?;
|
||||
match token.typ {
|
||||
// stack
|
||||
OpType::Push => {
|
||||
writeln!(writer, " ; -- PUSH {}", token.value)?;
|
||||
writeln!(writer, " mov rax, {}", token.value)?;
|
||||
@@ -73,6 +74,30 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||
writeln!(writer, " pop")?;
|
||||
ti += 1;
|
||||
},
|
||||
OpType::Print => {
|
||||
writeln!(writer, " ; -- PRINT")?;
|
||||
writeln!(writer, " pop rdi")?;
|
||||
writeln!(writer, " call print")?;
|
||||
ti += 1;
|
||||
},
|
||||
|
||||
OpType::Dup => {
|
||||
writeln!(writer, " ; -- DUP")?;
|
||||
writeln!(writer, " pop rax")?;
|
||||
writeln!(writer, " push rax")?;
|
||||
writeln!(writer, " push rax")?;
|
||||
|
||||
ti += 1;
|
||||
},
|
||||
|
||||
//mem
|
||||
OpType::Mem => {
|
||||
writeln!(writer, " ; -- MEM")?;
|
||||
writeln!(writer, " push mem")?;
|
||||
ti += 1;
|
||||
}
|
||||
|
||||
// math
|
||||
OpType::Plus => {
|
||||
writeln!(writer, " ; -- PLUS")?;
|
||||
writeln!(writer, " pop rax")?;
|
||||
@@ -102,7 +127,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||
|
||||
},
|
||||
OpType::Lt => {
|
||||
writeln!(writer, " ; -- EQUALS")?;
|
||||
writeln!(writer, " ; -- LT")?;
|
||||
writeln!(writer, " mov rcx, 0")?;
|
||||
writeln!(writer, " mov rdx, 1")?;
|
||||
writeln!(writer, " pop rbx")?;
|
||||
@@ -114,7 +139,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||
|
||||
},
|
||||
OpType::Gt => {
|
||||
writeln!(writer, " ; -- EQUALS")?;
|
||||
writeln!(writer, " ; -- GT")?;
|
||||
writeln!(writer, " mov rcx, 0")?;
|
||||
writeln!(writer, " mov rdx, 1")?;
|
||||
writeln!(writer, " pop rbx")?;
|
||||
@@ -125,32 +150,18 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||
ti += 1;
|
||||
|
||||
},
|
||||
OpType::Print => {
|
||||
writeln!(writer, " ; -- PRINT")?;
|
||||
writeln!(writer, " pop rdi")?;
|
||||
writeln!(writer, " call print")?;
|
||||
ti += 1;
|
||||
},
|
||||
|
||||
OpType::Dup => {
|
||||
writeln!(writer, " ; -- DUP")?;
|
||||
writeln!(writer, " pop rax")?;
|
||||
writeln!(writer, " push rax")?;
|
||||
writeln!(writer, " push rax")?;
|
||||
|
||||
ti += 1;
|
||||
},
|
||||
|
||||
// block
|
||||
OpType::If => {
|
||||
writeln!(writer, " ; -- IF")?;
|
||||
writeln!(writer, " pop rax")?;
|
||||
writeln!(writer, " test rax, rax")?;
|
||||
writeln!(writer, " jz addr_{}", token.value + 1)?;
|
||||
writeln!(writer, " jz addr_{}", token.jmp)?;
|
||||
ti += 1;
|
||||
},
|
||||
OpType::Else => {
|
||||
writeln!(writer, " ; -- ELSE")?;
|
||||
writeln!(writer, " jmp addr_{}", token.value)?;
|
||||
writeln!(writer, " jmp addr_{}", token.jmp)?;
|
||||
ti += 1;
|
||||
},
|
||||
OpType::While => {
|
||||
@@ -161,12 +172,12 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||
writeln!(writer, " ; -- DO")?;
|
||||
writeln!(writer, " pop rax")?;
|
||||
writeln!(writer, " test rax, rax")?;
|
||||
writeln!(writer, " jz addr_{}", token.value)?;
|
||||
writeln!(writer, " jz addr_{}", token.jmp)?;
|
||||
ti += 1;
|
||||
}
|
||||
OpType::End => {
|
||||
writeln!(writer, " ; -- END")?;
|
||||
writeln!(writer, " jmp addr_{}", token.value)?;
|
||||
writeln!(writer, " jmp addr_{}", token.jmp)?;
|
||||
ti += 1;
|
||||
},
|
||||
}
|
||||
@@ -175,6 +186,10 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
|
||||
writeln!(writer, " mov rax, 60")?;
|
||||
writeln!(writer, " mov rdi, 0")?;
|
||||
writeln!(writer, " syscall")?;
|
||||
|
||||
writeln!(writer, "segment .bss")?;
|
||||
writeln!(writer, " mem: resb {}", crate::compile::MEM_SZ)?;
|
||||
|
||||
writer.flush()?;
|
||||
linux_x86_64_compile_and_link(of_a, of_o, of_c)?;
|
||||
Ok(())
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod linux_x86_64;
|
||||
pub mod commands;
|
||||
|
||||
pub const MEM_SZ: u32 = 640 * 1000; // 4kb
|
||||
|
||||
@@ -14,7 +14,8 @@ pub enum OpType {
|
||||
Gt,
|
||||
Lt,
|
||||
While,
|
||||
Do
|
||||
Do,
|
||||
Mem
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +28,7 @@ pub enum OpType {
|
||||
pub struct Operator {
|
||||
pub typ: OpType,
|
||||
pub value: i32,
|
||||
pub jmp: i32,
|
||||
pub pos: (String, u32, u32)
|
||||
}
|
||||
|
||||
@@ -35,6 +37,7 @@ impl Operator {
|
||||
Self {
|
||||
typ,
|
||||
value,
|
||||
jmp: 0,
|
||||
pos: (file, row, col)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,10 +12,12 @@ fn stack_pop(stack: &mut Vec<i32>) -> Result<i32, &'static str> {
|
||||
pub fn run(tokens: Vec<crate::constants::Operator>) -> Result<(), &'static str>{
|
||||
let mut stack: Vec<i32> = Vec::new();
|
||||
let mut ti = 0;
|
||||
let mut mem: [u8; 16*1024];
|
||||
while ti < tokens.len() {
|
||||
let token = &tokens[ti];
|
||||
|
||||
match token.typ {
|
||||
// stack
|
||||
OpType::Push => {
|
||||
stack.push(token.value);
|
||||
ti += 1;
|
||||
@@ -24,6 +26,27 @@ pub fn run(tokens: Vec<crate::constants::Operator>) -> Result<(), &'static str>{
|
||||
stack.pop();
|
||||
ti += 1;
|
||||
},
|
||||
OpType::Dup => {
|
||||
let a = stack_pop(&mut stack)?;
|
||||
stack.push(a);
|
||||
stack.push(a);
|
||||
ti += 1;
|
||||
},
|
||||
|
||||
OpType::Print => {
|
||||
let a = stack_pop(&mut stack)?;
|
||||
println!("{a}");
|
||||
// let _ = io::stdout().flush();
|
||||
ti += 1;
|
||||
},
|
||||
// mem
|
||||
|
||||
OpType::Mem => {
|
||||
stack.push(0);
|
||||
ti += 1;
|
||||
}
|
||||
|
||||
// math
|
||||
OpType::Plus => {
|
||||
let a = stack_pop(&mut stack)?;
|
||||
let b = stack_pop(&mut stack)?;
|
||||
@@ -55,30 +78,17 @@ pub fn run(tokens: Vec<crate::constants::Operator>) -> Result<(), &'static str>{
|
||||
ti += 1;
|
||||
},
|
||||
|
||||
OpType::Print => {
|
||||
let a = stack_pop(&mut stack)?;
|
||||
println!("{a}");
|
||||
// let _ = io::stdout().flush();
|
||||
ti += 1;
|
||||
},
|
||||
|
||||
OpType::Dup => {
|
||||
let a = stack_pop(&mut stack)?;
|
||||
stack.push(a);
|
||||
stack.push(a);
|
||||
ti += 1;
|
||||
},
|
||||
// blocks
|
||||
OpType::If => {
|
||||
let a = stack_pop(&mut stack)?;
|
||||
if a == 0 {
|
||||
ti = (token.value + 1) as usize;
|
||||
ti = (token.jmp) as usize;
|
||||
} else {
|
||||
ti += 1;
|
||||
}
|
||||
},
|
||||
OpType::Else => {
|
||||
ti = token.value as usize;
|
||||
|
||||
ti = token.jmp as usize;
|
||||
},
|
||||
|
||||
OpType::While => {
|
||||
@@ -87,13 +97,13 @@ pub fn run(tokens: Vec<crate::constants::Operator>) -> Result<(), &'static str>{
|
||||
OpType::Do => {
|
||||
let a = stack.pop().unwrap();
|
||||
if a == 0 {
|
||||
ti = token.value as usize;
|
||||
ti = token.jmp as usize;
|
||||
} else {
|
||||
ti += 1;
|
||||
}
|
||||
}
|
||||
OpType::End => {
|
||||
ti = token.value as usize;
|
||||
ti = token.jmp as usize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,12 @@ fn lex_line(text: String) -> Result<Vec<(u32, String)>> {
|
||||
}
|
||||
|
||||
pub fn lex(code: String, file: &String) -> Result<Vec<Token>> {
|
||||
let lines: Vec<(usize, &str)> = code.split(['\n', '\r']).enumerate().collect();
|
||||
let lines: Vec<(usize, &str)> = code
|
||||
.split("//").collect::<Vec<&str>>()[0]
|
||||
.split(['\n', '\r'])
|
||||
.enumerate()
|
||||
.collect();
|
||||
|
||||
let lines: Vec<(u32, String)> = lines.iter().map(|i| (i.0 as u32, i.1.to_string())).collect();
|
||||
|
||||
let mut tokens: Vec<Token> = Vec::new();
|
||||
|
||||
@@ -14,7 +14,7 @@ use clap::Parser;
|
||||
#[command(author, version, about, long_about = None)]
|
||||
pub struct Args {
|
||||
/// Input source file
|
||||
#[arg(long, short)]
|
||||
#[arg(long, short)]
|
||||
in_file: String,
|
||||
|
||||
/// Output compiled file
|
||||
|
||||
@@ -17,7 +17,7 @@ pub fn cross_ref(mut tokens: Vec<Operator>) -> Vec<Operator> {
|
||||
std::process::exit(1); // idc
|
||||
}
|
||||
|
||||
(*if_og).value = (ip + 1) as i32;
|
||||
(*if_og).jmp = (ip + 1) as i32;
|
||||
stack.push(ip as u32);
|
||||
},
|
||||
OpType::End => {
|
||||
@@ -25,21 +25,21 @@ pub fn cross_ref(mut tokens: Vec<Operator>) -> Vec<Operator> {
|
||||
let mut block_og = &mut tokens[block_ip as usize].clone();
|
||||
if vec![OpType::If, OpType::Else].contains(&(*block_og).typ) {
|
||||
|
||||
(*block_og).value = ip as i32;
|
||||
(*block_og).jmp = ip as i32;
|
||||
tokens[block_ip as usize] = block_og.clone();
|
||||
|
||||
let do_og = &mut tokens[ip as usize].clone();
|
||||
do_og.value = (ip + 1) as i32;
|
||||
do_og.jmp = (ip + 1) as i32;
|
||||
|
||||
tokens[ip as usize] = (*do_og).clone();
|
||||
|
||||
} else if (*block_og).typ == OpType::Do {
|
||||
let do_og = &mut tokens[ip as usize];
|
||||
do_og.value = block_og.value;
|
||||
do_og.jmp = block_og.jmp;
|
||||
|
||||
tokens[ip as usize] = (*do_og).clone();
|
||||
let mut block_og = block_og.clone();
|
||||
block_og.value = (ip + 1) as i32;
|
||||
block_og.jmp = (ip + 1) as i32;
|
||||
tokens[block_ip as usize] = block_og.clone();
|
||||
} else {
|
||||
util::logger::pos_error(op.clone().pos,"'end' can only close 'if' blocks");
|
||||
@@ -52,7 +52,7 @@ pub fn cross_ref(mut tokens: Vec<Operator>) -> Vec<Operator> {
|
||||
}
|
||||
OpType::Do => {
|
||||
let while_ip = stack.pop().unwrap();
|
||||
(&mut tokens[ip as usize]).value = while_ip as i32;
|
||||
(&mut tokens[ip as usize]).jmp = while_ip as i32;
|
||||
stack.push(ip as u32);
|
||||
}
|
||||
_ => ()
|
||||
@@ -91,7 +91,7 @@ impl Parser {
|
||||
|
||||
// stack
|
||||
"dup" => tokens.push(Operator::new(OpType::Dup, 0, token.file.clone(), token.line, token.col)),
|
||||
"pop" => tokens.push(Operator::new(OpType::Pop, 0, token.file.clone(), token.line, token.col)),
|
||||
"drop" => tokens.push(Operator::new(OpType::Pop, 0, token.file.clone(), token.line, token.col)),
|
||||
|
||||
// comp and math
|
||||
"+" => tokens.push(Operator::new(OpType::Plus, 0, token.file.clone(), token.line, token.col)),
|
||||
@@ -106,6 +106,7 @@ impl Parser {
|
||||
"end" => tokens.push(Operator::new(OpType::End, 0, token.file.clone(), token.line, token.col)),
|
||||
"while" => tokens.push(Operator::new(OpType::While, 0, token.file.clone(), token.line, token.col)),
|
||||
"do" => tokens.push(Operator::new(OpType::Do, 0, token.file.clone(), token.line, token.col)),
|
||||
"mem" => tokens.push(Operator::new(OpType::Mem, 0, token.file.clone(), token.line, token.col)),
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user