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 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<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(())
}

View File

@ -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<Operator>, args: Args) -> Result<()>{
let mut of_c = PathBuf::from(&args.out_file);
@ -89,6 +91,48 @@ pub fn compile(tokens: Vec<Operator>, 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<Operator>, 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<Operator>, 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(())
}

View File

@ -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,

View File

@ -37,6 +37,39 @@ pub fn run(tokens: Vec<crate::constants::Operator>) -> 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<crate::constants::Operator>) -> 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)?;

View File

@ -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();

View File

@ -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)),