Skip to content

Commit

Permalink
feat: add 'run' arg to run bin from cli
Browse files Browse the repository at this point in the history
  • Loading branch information
vishruth-thimmaiah committed Nov 14, 2024
1 parent 5dc96ad commit 1d1c61f
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 22 deletions.
55 changes: 46 additions & 9 deletions src/args.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
use std::process::exit;

#[derive(Debug)]
pub struct Args {
pub print_lexer_ouput: bool,
pub print_ast_output: bool,
pub use_jit: bool,
pub jit: bool,
pub build: bool,
pub run: bool,
pub path: Option<String>,
pub dry_run: bool,
}

Expand All @@ -12,20 +16,27 @@ impl Default for Args {
Args {
print_lexer_ouput: false,
print_ast_output: false,
use_jit: false,
jit: false,
build: false,
run: false,
path: None,
dry_run: false,
}
}
}

const HELP_STRING: &str = r#"
Usage: sloppee <file> [OPTIONS]
Usage: sloppee [COMMAND] <file> [OPTIONS]
Commands:
build Build the project
run Run the project
jit Run the project with LLVM's JIT
Options:
--help, -h Show this help message
--print-lexer-output Print the lexer output
--print-ast-output Print the ast output
--use-jit Use LLVM's JIT
--dry-run Run without invoking LLVM
"#;

Expand All @@ -34,12 +45,32 @@ fn show_help() {
exit(0);
}

fn show_usage() {
eprintln!("Usage: sloppee [COMMAND] <file> [OPTIONS]");
exit(1);
}

pub fn parse_args(args: &Vec<String>) -> Args {
let mut result = Args::default();
let first_arg = args.get(1);
if first_arg == Some(&"--help".to_string()) || first_arg == Some(&"-h".to_string()) {
show_help();

match args.get(1) {
Some(arg) => match arg.as_str() {
"--help" | "-h" => show_help(),
"build" => result.build = true,
"run" => result.run = true,
"jit" => result.jit = true,
_ => show_usage(),
},
None => show_usage(),
}

if let Some(path) = args.get(2) {
result.path = Some(path.to_string());
} else {
eprintln!("No file provided");
exit(1);
}

if args.len() < 3 {
return result;
}
Expand All @@ -48,8 +79,14 @@ pub fn parse_args(args: &Vec<String>) -> Args {
"--help" | "-h" => show_help(),
"--print-lexer-output" => result.print_lexer_ouput = true,
"--print-ast-output" => result.print_ast_output = true,
"--use-jit" => result.use_jit = true,
"--dry-run" => result.dry_run = true,
"--dry-run" => {
if result.build {
result.dry_run = true
} else {
eprintln!("--dry-run can only be used with build");
exit(1);
}
}
_ => (),
}
}
Expand Down
22 changes: 18 additions & 4 deletions src/llvm/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,18 @@ use std::{fs, path::PathBuf, process::Command};

use inkwell::module::Module;

pub fn build_ir(module: &Module) {
fn run_binary() {
let path = PathBuf::from(".build/output");
let run_cmd = Command::new(path).status();

if let Ok(output) = run_cmd {
println!("\n> Binary ran with {}", output)
} else {
panic!("\n> Error running the binary.")
}
}

pub fn build_ir(module: &Module, run: bool) {
let path = PathBuf::from(".build/llvm-ir/");
let _ = fs::create_dir_all(&path);

Expand All @@ -21,14 +32,17 @@ pub fn build_ir(module: &Module) {

if let Ok(output) = clang_build {
if output.status.success() {
println!("Binary built.")
println!("> Binary built.\n")
} else {
panic!(
"Error while building the binary: {}",
"> Error while building the binary: {}",
std::str::from_utf8(&output.stderr).unwrap()
)
}
} else {
panic!("Error running clang to build the binary.")
panic!("> Error running clang to build the binary.")
}
if run {
run_binary();
}
}
4 changes: 2 additions & 2 deletions src/llvm/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ impl<'ctx> CodeGen<'ctx> {
}
}

pub fn compile(&self, build: bool) -> Option<u32> {
pub fn compile(&self, build: bool, run: bool) -> Option<u32> {
for node in &self.tokens {
match node.get_type() {
ParserTypes::IMPORT => {
Expand All @@ -94,7 +94,7 @@ impl<'ctx> CodeGen<'ctx> {
}
}
if build {
builder::build_ir(&self.module);
builder::build_ir(&self.module, run);
None
} else {
unsafe {
Expand Down
2 changes: 1 addition & 1 deletion src/llvm/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ pub fn generate_result(contents: &str) -> Option<u32> {

let context = Context::create();
let codegen = CodeGen::new(&context, parser);
codegen.compile(false)
codegen.compile(false, false)
}

10 changes: 4 additions & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ fn main() {
let parsed_args = args::parse_args(&args);

if args.len() > 1 {
let contents = fs::read_to_string(&args[1]).unwrap();
let contents = fs::read_to_string(parsed_args.path.unwrap()).unwrap();

let lexer = Lexer::new(&contents).tokenize();
if parsed_args.print_lexer_ouput {
Expand All @@ -35,13 +35,11 @@ fn main() {
let context = Context::create();
let codegen = CodeGen::new(&context, parser);

if parsed_args.use_jit {
let output = codegen.compile(false);
if parsed_args.jit {
let output = codegen.compile(false, false);
println!("Exit Code: {}", output.unwrap());
} else {
codegen.compile(true);
codegen.compile(true, parsed_args.run);
}
} else {
println!("Usage: sloppee <file>");
}
}

0 comments on commit 1d1c61f

Please sign in to comment.