diff --git a/src/main.rs b/src/main.rs index 6168e38..bf44d57 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,8 @@ use std::collections::HashMap; use std::env; use std::fs; use std::iter::Peekable; +use std::process::Command; +use std::process::Stdio; use std::process::exit; #[derive(Debug, Clone, PartialEq)] @@ -106,12 +108,14 @@ fn main() } let mut debug = false; let mut interpret = false; + let mut run = false; for arg in &args[3..] { match arg.as_str() { "-d" | "--debug" => debug = true, "-i" | "--interpret" => interpret = true, + "-r" | "--run" => run = true, _ => panic!("Unknown option {}", arg), } } @@ -125,7 +129,7 @@ fn main() let f = f.unwrap(); let file_content = fs::read_to_string(f.path()).unwrap().replace("\r\n", "\n"); println!("========NOW TESTING {:?}========", f.path()); - match compile(&file_content, &intrinsics, interpret, debug) + match compile(&file_content, &intrinsics, interpret, run, debug) { Ok(maybe_msg) => { @@ -182,7 +186,7 @@ fn main() "-c" | "--compile" => { let file_content = fs::read_to_string(&args[2]).expect("Could not read the source file"); - match compile(&file_content, &intrinsics, interpret, debug) + match compile(&file_content, &intrinsics, interpret, run, debug) { Ok(maybe_msg) => { @@ -198,7 +202,7 @@ fn main() } } -fn compile(file_content: &String, intrinsics: &HashMap<&str, (Vec, Vec)>, interpret: bool, debug: bool) -> Result, String> +fn compile(file_content: &String, intrinsics: &HashMap<&str, (Vec, Vec)>, interpret: bool, run: bool, debug: bool) -> Result, String> { let mut tokens: Vec = tokenize(&file_content)?; println!("---Done tokenizing, got {} tokens---", tokens.len()); @@ -223,11 +227,57 @@ fn compile(file_content: &String, intrinsics: &HashMap<&str, (Vec, Vec }; if !interpret { - match generate_assembly_linux_x64(&operations, &functions, &intrinsics, &arrays, debug) + if let Err(err) = generate_assembly_linux_x64(&operations, &functions, &intrinsics, &arrays, debug) { - Ok(()) => return Ok(None), - Err(error) => return Err(error.to_string()), + return Err(err.to_string()); } + let mut fasm_process = match Command::new("fasm").arg("out.asm").spawn() + { + Ok(process) => process, + Err(err) => return Err(err.to_string()), + }; + match fasm_process.wait() + { + Ok(status) => + { + if !status.success() + { + return Err(format!("fasm exited with an error: {}", status)); + } + } + Err(err) => return Err(err.to_string()), + } + } + if run + { + let process = match Command::new("./out").stdout(Stdio::piped()).stderr(Stdio::piped()).spawn() + { + Ok(process) => process, + Err(err) => return Err(err.to_string()), + }; + return match process.wait_with_output() + { + Ok(output) => + { + match String::from_utf8(output.stdout) + { + Ok(stdout) => + { + match String::from_utf8(output.stderr) + { + Ok(stderr) => + { + println!("{:?}", stdout.as_bytes()); + Ok(Some(format!("{}{}", stdout, stderr))) + } + Err(err) => Err(err.to_string()), + } + } + Err(err) => Err(err.to_string()), + } + } + Err(err) => Err(err.to_string()), + }; } return Ok(output); } @@ -346,7 +396,17 @@ fn generate_assembly_linux_x64_block(operations: &Vec, functions: &Ve } Datatype::String => { - data.strings += format!("\tstr_{}_{}: dq {}, \"{}\", 0\n", line, col, value.len(), value).as_str(); + data.strings += format!("\tstr_{}_{}: db {}, {}, {}, {}, {}, {}, {}, {}, \"{}\", 0\n", + line, col, + value.len() % 256, + (value.len() >> 8) % 256, + (value.len() >> 16) % 256, + (value.len() >> 24) % 256, + (value.len() >> 32) % 256, + (value.len() >> 40) % 256, + (value.len() >> 48) % 256, + (value.len() >> 56) % 256, + value).as_str(); data.code += format!("\tlea rax, [str_{}_{}]\n", line, col).as_str(); data.code += "\tmov [queue+8*r13], rax\n"; } @@ -431,7 +491,7 @@ fn generate_assembly_linux_x64_block(operations: &Vec, functions: &Ve // data data.code += "\tlea rsi, [rsi+8]\n"; // incorporate the null byte - data.code += "\tinc rdx\n"; + //data.code += "\tinc rdx\n"; data.code += "\tsyscall\n"; // TODO: factor this out data.code += "\tinc r12\n"; @@ -449,7 +509,7 @@ fn generate_assembly_linux_x64_block(operations: &Vec, functions: &Ve // data data.code += "\tlea rsi, [rsi+8]\n"; // incorporate the null byte - data.code += "\tinc rdx\n"; + //data.code += "\tinc rdx\n"; data.code += "\tsyscall\n"; // TODO: factor this out data.code += "\tinc r12\n"; diff --git a/tests/comparisons.qbl b/tests/comparisons.qbl index ebcd278..8d4474e 100644 --- a/tests/comparisons.qbl +++ b/tests/comparisons.qbl @@ -3,7 +3,10 @@ //true //false //false +// //false +//false +//true //true //true //:END: diff --git a/tests/test.qbl b/tests/test.qbl index 281254d..3864e14 100644 --- a/tests/test.qbl +++ b/tests/test.qbl @@ -1,7 +1,7 @@ //valid,Hello, World! //4242test2Falsetesttesttest:END: -"Hello, World!\n" print 43 foo foo deq +"Hello, World!" println 43 foo foo deq // Dequeues, enqueues 42 and 17, prints the head @@ -39,4 +39,4 @@ function int => whileFunction deq } -3 whileFunction \ No newline at end of file +3 whileFunction