Add asm compilation and running

This commit is contained in:
0x4261756D 2023-01-05 00:19:29 +01:00
parent ffdc54947b
commit 2ce863c899
3 changed files with 74 additions and 11 deletions

View File

@ -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<Datatype>, Vec<Datatype>)>, interpret: bool, debug: bool) -> Result<Option<String>, String>
fn compile(file_content: &String, intrinsics: &HashMap<&str, (Vec<Datatype>, Vec<Datatype>)>, interpret: bool, run: bool, debug: bool) -> Result<Option<String>, String>
{
let mut tokens: Vec<Token> = tokenize(&file_content)?;
println!("---Done tokenizing, got {} tokens---", tokens.len());
@ -223,11 +227,57 @@ fn compile(file_content: &String, intrinsics: &HashMap<&str, (Vec<Datatype>, 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<Operation>, 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<Operation>, 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<Operation>, 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";

View File

@ -3,7 +3,10 @@
//true
//false
//false
//
//false
//false
//true
//true
//true
//:END:

View File

@ -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
3 whileFunction