From 8a53271a918801fc09e41f378ee38a70768b1997 Mon Sep 17 00:00:00 2001 From: MCorange Date: Tue, 14 Mar 2023 23:37:43 +0200 Subject: [PATCH] added like a shit load of math and stack instructions --- src/compile/commands.rs | 47 +++++++++++--- src/compile/linux_x86_64.rs | 102 +++++++++++++++++++++++++++++- src/constants.rs | 45 +++++++++---- src/interpret/linux_x86_64/mod.rs | 75 ++++++++++++++++++++++ src/main.rs | 13 +++- src/parser.rs | 9 +++ 6 files changed, 264 insertions(+), 27 deletions(-) diff --git a/src/compile/commands.rs b/src/compile/commands.rs index 1b16419..15efa90 100644 --- a/src/compile/commands.rs +++ b/src/compile/commands.rs @@ -3,7 +3,7 @@ use std::process::{Command, Stdio}; use color_eyre::Result; 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 = [ "-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") { - todo!("Windows compiling"); + return Ok(()); } else { Command::new("nasm") .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()) .spawn()? }; - - logger::info(format!("running 'nasm {}'", nasm_args.join(" ")).as_str()); + if !quiet{ + logger::info(format!("running 'nasm {}'", nasm_args.join(" ")).as_str()); + } 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") { - todo!("Windows compiling"); + return Ok(()); } else { Command::new("ld") .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()) .spawn()? }; - - logger::info(format!("running 'ld {}'", ld_args.join(" ")).as_str()); + if (!quiet) { + logger::info(format!("running 'ld {}'", ld_args.join(" ")).as_str()); + } 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, 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(()) } \ No newline at end of file diff --git a/src/compile/linux_x86_64.rs b/src/compile/linux_x86_64.rs index c01f994..3f1c59e 100644 --- a/src/compile/linux_x86_64.rs +++ b/src/compile/linux_x86_64.rs @@ -3,6 +3,8 @@ use crate::{constants::{Operator, OpType}, Args}; use color_eyre::Result; use crate::compile::commands::linux_x86_64_compile_and_link; +use super::commands::linux_x86_64_run; + pub fn compile(tokens: Vec, args: Args) -> Result<()>{ let mut of_c = PathBuf::from(&args.out_file); @@ -89,6 +91,48 @@ pub fn compile(tokens: Vec, args: Args) -> Result<()>{ 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 OpType::Mem => { @@ -166,6 +210,58 @@ pub fn compile(tokens: Vec, args: Args) -> Result<()>{ 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 OpType::If => { @@ -278,6 +374,10 @@ pub fn compile(tokens: Vec, args: Args) -> Result<()>{ writeln!(writer, " mem: resb {}", crate::compile::MEM_SZ)?; 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(()) } \ No newline at end of file diff --git a/src/constants.rs b/src/constants.rs index 26f4a82..4da2bd1 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -1,38 +1,55 @@ #[derive(Debug, Clone, PartialEq)] pub enum OpType { + + // stack Push, 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, Plus, Equals, - Print, - If, - Else, - End, - Dup, Gt, Lt, - While, - Do, + Band, // & + Bor, // | + Shr, // >> + Shl, // << + Div, // / + Mul, + + + // mem Mem, Load8, Store8, + + // block + If, + Else, + End, + While, + Do, + + // syscalls Syscall0, Syscall1, Syscall2, Syscall3, Syscall4, Syscall5, - Syscall6 + Syscall6, + + } - -// #[derive(Debug)] -// pub enum OpType { - -// } - #[derive(Debug, Clone)] pub struct Operator { pub typ: OpType, diff --git a/src/interpret/linux_x86_64/mod.rs b/src/interpret/linux_x86_64/mod.rs index 9d3cfba..f4859f2 100644 --- a/src/interpret/linux_x86_64/mod.rs +++ b/src/interpret/linux_x86_64/mod.rs @@ -37,6 +37,39 @@ pub fn run(tokens: Vec) -> Result<(), &'static str>{ stack.push(a); 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 => { let a = stack_pop(&mut stack)?; @@ -95,7 +128,49 @@ pub fn run(tokens: Vec) -> Result<(), &'static str>{ stack.push((a < b) as u64); 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 OpType::If => { let a = stack_pop(&mut stack)?; diff --git a/src/main.rs b/src/main.rs index 642bbb9..b131451 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,14 +27,21 @@ pub struct Args { /// Interpert #[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<(), ()> { let args = Args::parse(); - println!("MClang2 0.0.1"); - let code = fs::read_to_string(&args.in_file).unwrap(); let tokens = lexer::lex(code, &args.in_file).unwrap(); diff --git a/src/parser.rs b/src/parser.rs index 78c93f9..ced6720 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -92,6 +92,10 @@ impl Parser { // stack "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)), + "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 "+" => 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::Gt, 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 "if" => tokens.push(Operator::new(OpType::If, 0, token.file.clone(), token.line, token.col)),