added like a shit load of math and stack instructions

This commit is contained in:
MCorange 2023-03-14 23:37:43 +02:00
parent 2c82aebd60
commit 8a53271a91
6 changed files with 264 additions and 27 deletions

View File

@ -3,7 +3,7 @@ use std::process::{Command, Stdio};
use color_eyre::Result; use color_eyre::Result;
use crate::util::logger; use crate::util::logger;
pub fn linux_x86_64_compile_and_link(of_a: PathBuf, of_o: PathBuf, of_c: PathBuf) -> Result<()> { pub fn linux_x86_64_compile_and_link(of_a: &PathBuf, of_o: &PathBuf, of_c: &PathBuf, quiet: bool) -> Result<()> {
let nasm_args = [ let nasm_args = [
"-felf64", "-felf64",
@ -20,7 +20,7 @@ pub fn linux_x86_64_compile_and_link(of_a: PathBuf, of_o: PathBuf, of_c: PathBuf
let mut proc = if cfg!(target_os = "windows") { let mut proc = if cfg!(target_os = "windows") {
todo!("Windows compiling"); return Ok(());
} else { } else {
Command::new("nasm") Command::new("nasm")
.args(&nasm_args) .args(&nasm_args)
@ -28,14 +28,18 @@ pub fn linux_x86_64_compile_and_link(of_a: PathBuf, of_o: PathBuf, of_c: PathBuf
.stderr(Stdio::inherit()) .stderr(Stdio::inherit())
.spawn()? .spawn()?
}; };
if !quiet{
logger::info(format!("running 'nasm {}'", nasm_args.join(" ")).as_str()); logger::info(format!("running 'nasm {}'", nasm_args.join(" ")).as_str());
}
let exit = proc.wait()?; let exit = proc.wait()?;
logger::info(format!("nasm process exited with code {}", exit).as_str());
if (!quiet) {
logger::info(format!("nasm process exited with code {}", exit).as_str());
}
let mut proc2 = if cfg!(target_os = "windows") { let mut proc2 = if cfg!(target_os = "windows") {
todo!("Windows compiling"); return Ok(());
} else { } else {
Command::new("ld") Command::new("ld")
.args(&ld_args) .args(&ld_args)
@ -43,12 +47,37 @@ pub fn linux_x86_64_compile_and_link(of_a: PathBuf, of_o: PathBuf, of_c: PathBuf
.stderr(Stdio::inherit()) .stderr(Stdio::inherit())
.spawn()? .spawn()?
}; };
if (!quiet) {
logger::info(format!("running 'ld {}'", ld_args.join(" ")).as_str()); logger::info(format!("running 'ld {}'", ld_args.join(" ")).as_str());
}
let exit2 = proc2.wait()?; let exit2 = proc2.wait()?;
logger::info(format!("ld process exited with code {}", exit2).as_str()); if (!quiet) {
logger::info(format!("ld process exited with code {}", exit2).as_str());
}
Ok(())
}
pub fn linux_x86_64_run(bin: &PathBuf, args: Vec<String>, quiet: bool) -> Result<()> {
let mut proc = if cfg!(target_os = "windows") {
return Ok(());
} else {
Command::new(bin)
//.args(&nasm_args)
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.spawn()?
};
if (!quiet) {
logger::info(format!("running '{} {}'", bin.to_string_lossy() ,args.join(" ")).as_str());
}
let exit = proc.wait()?;
if (!quiet) {
logger::info(format!("{} process exited with code {}", bin.to_string_lossy(), exit).as_str());
}
Ok(()) Ok(())
} }

View File

@ -3,6 +3,8 @@ use crate::{constants::{Operator, OpType}, Args};
use color_eyre::Result; use color_eyre::Result;
use crate::compile::commands::linux_x86_64_compile_and_link; use crate::compile::commands::linux_x86_64_compile_and_link;
use super::commands::linux_x86_64_run;
pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
let mut of_c = PathBuf::from(&args.out_file); let mut of_c = PathBuf::from(&args.out_file);
@ -89,6 +91,48 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
ti += 1; ti += 1;
}, },
OpType::Dup2 => {
writeln!(writer, " ; -- DUP2")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?;
writeln!(writer, " push rbx")?;
writeln!(writer, " push rax")?;
writeln!(writer, " push rbx")?;
writeln!(writer, " push rax")?;
ti += 1;
},
OpType::Rot => {
writeln!(writer, " ; -- DUP")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?;
writeln!(writer, " pop rcx")?;
writeln!(writer, " push rbx")?;
writeln!(writer, " push rax")?;
writeln!(writer, " push rcx")?;
ti += 1;
},
OpType::Swap => {
writeln!(writer, " ; -- DUP")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?;
writeln!(writer, " push rbx")?;
writeln!(writer, " push rax")?;
ti += 1;
},
OpType::Over => {
writeln!(writer, " ; -- DUP")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?;
writeln!(writer, " push rbx")?;
writeln!(writer, " push rax")?;
writeln!(writer, " push rbx")?;
ti += 1;
},
//mem //mem
OpType::Mem => { OpType::Mem => {
@ -166,6 +210,58 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
ti += 1; ti += 1;
}, },
OpType::Band => {
writeln!(writer, " ; -- BAND")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?;
writeln!(writer, " and rax, rbx")?;
writeln!(writer, " push rax")?;
ti += 1;
},
OpType::Bor => {
writeln!(writer, " ; -- BOR")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?;
writeln!(writer, " or rax, rbx")?;
writeln!(writer, " push rax")?;
ti += 1;
},
OpType::Shr => {
writeln!(writer, " ; -- SHR")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?;
writeln!(writer, " shr rax, rbx")?;
writeln!(writer, " push rax")?;
ti += 1;
},
OpType::Shl => {
writeln!(writer, " ; -- SHL")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?;
writeln!(writer, " shl rax, rbx")?;
writeln!(writer, " push rax")?;
ti += 1;
},
OpType::Div => {
writeln!(writer, " ; -- DIV")?;
writeln!(writer, " xor rdx, rdx")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?;
writeln!(writer, " div rbx")?;
writeln!(writer, " push rax")?;
//writeln!(writer, " push rdx")?;
ti += 1;
},
OpType::Mul => {
writeln!(writer, " ; -- MUL")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?;
writeln!(writer, " mul rbx")?;
writeln!(writer, " push rax")?;
//writeln!(writer, " push rdx")?;
ti += 1;
},
// block // block
OpType::If => { OpType::If => {
@ -278,6 +374,10 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
writeln!(writer, " mem: resb {}", crate::compile::MEM_SZ)?; writeln!(writer, " mem: resb {}", crate::compile::MEM_SZ)?;
writer.flush()?; writer.flush()?;
linux_x86_64_compile_and_link(of_a, of_o, of_c)?; linux_x86_64_compile_and_link(&of_a, &of_o, &of_c, args.quiet)?;
if args.run {
linux_x86_64_run(&of_c, vec![], args.quiet)?;
}
Ok(()) Ok(())
} }

View File

@ -1,38 +1,55 @@
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub enum OpType { pub enum OpType {
// stack
Push, Push,
Pop, Pop,
Print,
Dup,
Dup2, // a b => a b a b
Rot, // a b c => b c a
Over, // a b => a b a
Swap, // a b => b a
// math
Minus, Minus,
Plus, Plus,
Equals, Equals,
Print,
If,
Else,
End,
Dup,
Gt, Gt,
Lt, Lt,
While, Band, // &
Do, Bor, // |
Shr, // >>
Shl, // <<
Div, // /
Mul,
// mem
Mem, Mem,
Load8, Load8,
Store8, Store8,
// block
If,
Else,
End,
While,
Do,
// syscalls
Syscall0, Syscall0,
Syscall1, Syscall1,
Syscall2, Syscall2,
Syscall3, Syscall3,
Syscall4, Syscall4,
Syscall5, Syscall5,
Syscall6 Syscall6,
} }
// #[derive(Debug)]
// pub enum OpType {
// }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Operator { pub struct Operator {
pub typ: OpType, pub typ: OpType,

View File

@ -37,6 +37,39 @@ pub fn run(tokens: Vec<crate::constants::Operator>) -> Result<(), &'static str>{
stack.push(a); stack.push(a);
ti += 1; ti += 1;
}, },
OpType::Dup2 => {
let a = stack_pop(&mut stack)?;
let b = stack_pop(&mut stack)?;
stack.push(b);
stack.push(a);
stack.push(b);
stack.push(a);
ti += 1;
}
OpType::Rot => {
let a = stack_pop(&mut stack)?;
let b = stack_pop(&mut stack)?;
let c = stack_pop(&mut stack)?;
stack.push(b);
stack.push(a);
stack.push(c);
ti += 1;
}
OpType::Swap => {
let a = stack_pop(&mut stack)?;
let b = stack_pop(&mut stack)?;
stack.push(b);
stack.push(a);
ti += 1;
}
OpType::Over => {
let a = stack_pop(&mut stack)?;
let b = stack_pop(&mut stack)?;
stack.push(b);
stack.push(a);
stack.push(b);
ti += 1;
}
OpType::Print => { OpType::Print => {
let a = stack_pop(&mut stack)?; let a = stack_pop(&mut stack)?;
@ -95,7 +128,49 @@ pub fn run(tokens: Vec<crate::constants::Operator>) -> Result<(), &'static str>{
stack.push((a < b) as u64); stack.push((a < b) as u64);
ti += 1; ti += 1;
}, },
OpType::Band => {
let b = stack_pop(&mut stack)?;
let a = stack_pop(&mut stack)?;
stack.push((a & b) as u64);
ti += 1;
}
OpType::Bor => {
let b = stack_pop(&mut stack)?;
let a = stack_pop(&mut stack)?;
stack.push((a | b) as u64);
ti += 1;
}
OpType::Shr => {
let b = stack_pop(&mut stack)?;
let a = stack_pop(&mut stack)?;
stack.push((a >> b) as u64);
ti += 1;
}
OpType::Shl => {
let b = stack_pop(&mut stack)?;
let a = stack_pop(&mut stack)?;
stack.push((a << b) as u64);
ti += 1;
}
OpType::Div => {
let b = stack_pop(&mut stack)?;
let a = stack_pop(&mut stack)?;
stack.push((a / b) as u64);
ti += 1;
}
OpType::Mul => {
let b = stack_pop(&mut stack)?;
let a = stack_pop(&mut stack)?;
stack.push((a * b) as u64);
ti += 1;
}
// blocks // blocks
OpType::If => { OpType::If => {
let a = stack_pop(&mut stack)?; let a = stack_pop(&mut stack)?;

View File

@ -27,14 +27,21 @@ pub struct Args {
/// Interpert /// Interpert
#[arg(long, short='s')] #[arg(long, short='s')]
interpret: bool interpret: bool,
/// Run the compiled executable
#[arg(long, short)]
run: bool,
/// Dont print any output exept the actual running codes output
#[arg(long, short)]
quiet: bool,
} }
fn main() -> Result<(), ()> { fn main() -> Result<(), ()> {
let args = Args::parse(); let args = Args::parse();
println!("MClang2 0.0.1");
let code = fs::read_to_string(&args.in_file).unwrap(); let code = fs::read_to_string(&args.in_file).unwrap();
let tokens = lexer::lex(code, &args.in_file).unwrap(); let tokens = lexer::lex(code, &args.in_file).unwrap();

View File

@ -92,6 +92,10 @@ impl Parser {
// stack // stack
"dup" => tokens.push(Operator::new(OpType::Dup, 0, token.file.clone(), token.line, token.col)), "dup" => tokens.push(Operator::new(OpType::Dup, 0, token.file.clone(), token.line, token.col)),
"drop" => 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)),
"2dup" => tokens.push(Operator::new(OpType::Dup2, 0, token.file.clone(), token.line, token.col)),
"rot" => tokens.push(Operator::new(OpType::Rot, 0, token.file.clone(), token.line, token.col)),
"over" => tokens.push(Operator::new(OpType::Over, 0, token.file.clone(), token.line, token.col)),
"swap" => tokens.push(Operator::new(OpType::Swap, 0, token.file.clone(), token.line, token.col)),
// comp and math // comp and math
"+" => tokens.push(Operator::new(OpType::Plus, 0, token.file.clone(), token.line, token.col)), "+" => tokens.push(Operator::new(OpType::Plus, 0, token.file.clone(), token.line, token.col)),
@ -99,6 +103,11 @@ impl Parser {
"=" => tokens.push(Operator::new(OpType::Equals, 0, token.file.clone(), token.line, token.col)), "=" => tokens.push(Operator::new(OpType::Equals, 0, token.file.clone(), token.line, token.col)),
">" => tokens.push(Operator::new(OpType::Gt, 0, token.file.clone(), token.line, token.col)), ">" => tokens.push(Operator::new(OpType::Gt, 0, token.file.clone(), token.line, token.col)),
"<" => tokens.push(Operator::new(OpType::Lt, 0, token.file.clone(), token.line, token.col)), "<" => tokens.push(Operator::new(OpType::Lt, 0, token.file.clone(), token.line, token.col)),
"band" => tokens.push(Operator::new(OpType::Band, 0, token.file.clone(), token.line, token.col)),
"bor" => tokens.push(Operator::new(OpType::Bor, 0, token.file.clone(), token.line, token.col)),
"shr" => tokens.push(Operator::new(OpType::Shr, 0, token.file.clone(), token.line, token.col)),
"shl" => tokens.push(Operator::new(OpType::Shl, 0, token.file.clone(), token.line, token.col)),
"/" => tokens.push(Operator::new(OpType::Div, 0, token.file.clone(), token.line, token.col)),
// block // block
"if" => tokens.push(Operator::new(OpType::If, 0, token.file.clone(), token.line, token.col)), "if" => tokens.push(Operator::new(OpType::If, 0, token.file.clone(), token.line, token.col)),