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::env;
use std::fs; use std::fs;
use std::iter::Peekable; use std::iter::Peekable;
use std::process::Command;
use std::process::Stdio;
use std::process::exit; use std::process::exit;
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
@ -106,12 +108,14 @@ fn main()
} }
let mut debug = false; let mut debug = false;
let mut interpret = false; let mut interpret = false;
let mut run = false;
for arg in &args[3..] for arg in &args[3..]
{ {
match arg.as_str() match arg.as_str()
{ {
"-d" | "--debug" => debug = true, "-d" | "--debug" => debug = true,
"-i" | "--interpret" => interpret = true, "-i" | "--interpret" => interpret = true,
"-r" | "--run" => run = true,
_ => panic!("Unknown option {}", arg), _ => panic!("Unknown option {}", arg),
} }
} }
@ -125,7 +129,7 @@ fn main()
let f = f.unwrap(); let f = f.unwrap();
let file_content = fs::read_to_string(f.path()).unwrap().replace("\r\n", "\n"); let file_content = fs::read_to_string(f.path()).unwrap().replace("\r\n", "\n");
println!("========NOW TESTING {:?}========", f.path()); println!("========NOW TESTING {:?}========", f.path());
match compile(&file_content, &intrinsics, interpret, debug) match compile(&file_content, &intrinsics, interpret, run, debug)
{ {
Ok(maybe_msg) => Ok(maybe_msg) =>
{ {
@ -182,7 +186,7 @@ fn main()
"-c" | "--compile" => "-c" | "--compile" =>
{ {
let file_content = fs::read_to_string(&args[2]).expect("Could not read the source file"); 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) => 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)?; let mut tokens: Vec<Token> = tokenize(&file_content)?;
println!("---Done tokenizing, got {} tokens---", tokens.len()); println!("---Done tokenizing, got {} tokens---", tokens.len());
@ -223,11 +227,57 @@ fn compile(file_content: &String, intrinsics: &HashMap<&str, (Vec<Datatype>, Vec
}; };
if !interpret 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), return Err(err.to_string());
Err(error) => return Err(error.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); return Ok(output);
} }
@ -346,7 +396,17 @@ fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Ve
} }
Datatype::String => 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 += format!("\tlea rax, [str_{}_{}]\n", line, col).as_str();
data.code += "\tmov [queue+8*r13], rax\n"; 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
data.code += "\tlea rsi, [rsi+8]\n"; data.code += "\tlea rsi, [rsi+8]\n";
// incorporate the null byte // incorporate the null byte
data.code += "\tinc rdx\n"; //data.code += "\tinc rdx\n";
data.code += "\tsyscall\n"; data.code += "\tsyscall\n";
// TODO: factor this out // TODO: factor this out
data.code += "\tinc r12\n"; data.code += "\tinc r12\n";
@ -449,7 +509,7 @@ fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Ve
// data // data
data.code += "\tlea rsi, [rsi+8]\n"; data.code += "\tlea rsi, [rsi+8]\n";
// incorporate the null byte // incorporate the null byte
data.code += "\tinc rdx\n"; //data.code += "\tinc rdx\n";
data.code += "\tsyscall\n"; data.code += "\tsyscall\n";
// TODO: factor this out // TODO: factor this out
data.code += "\tinc r12\n"; data.code += "\tinc r12\n";

View File

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

View File

@ -1,7 +1,7 @@
//valid,Hello, World! //valid,Hello, World!
//4242test2Falsetesttesttest:END: //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 // Dequeues, enqueues 42 and 17, prints the head
@ -39,4 +39,4 @@ function int => whileFunction
deq deq
} }
3 whileFunction 3 whileFunction