Add asm compilation and running
This commit is contained in:
parent
ffdc54947b
commit
2ce863c899
78
src/main.rs
78
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<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";
|
||||
|
@ -3,7 +3,10 @@
|
||||
//true
|
||||
//false
|
||||
//false
|
||||
//
|
||||
//false
|
||||
//false
|
||||
//true
|
||||
//true
|
||||
//true
|
||||
//:END:
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user