-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Enable object file and executable output
* Added C-derived main code generation, using clang * Use llc and clang for object files and executables * Added cli shorthand flags for convenience * Removed lit crate dependency and tests * Refactored code and tests * Version bump
- Loading branch information
Showing
65 changed files
with
1,394 additions
and
488 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
// Copyright 2024, Giordano Salvador | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
|
||
use crate::exit_code; | ||
use exit_code::exit; | ||
use exit_code::ExitCode; | ||
|
||
use std::io::Write; | ||
use std::process; | ||
use std::process::Stdio; | ||
|
||
pub struct CommandResult { | ||
pub success: bool, | ||
pub stdout: Option<String>, | ||
} | ||
|
||
impl CommandResult { | ||
pub fn new(success: bool, stdout: Option<String>) -> Self { | ||
CommandResult{success, stdout} | ||
} | ||
} | ||
|
||
pub struct Command {} | ||
|
||
impl Command { | ||
pub fn run(bin: &str, args: &[&str]) -> CommandResult { | ||
let output = match process::Command::new(bin).args(args.iter()).output() { | ||
Ok(output) => output, | ||
Err(msg) => { | ||
eprintln!("Failed to run with {}: {}", bin, msg); | ||
exit(ExitCode::CommandError); | ||
}, | ||
}; | ||
let stderr: &[u8] = output.stderr.as_slice(); | ||
let stdout: &[u8] = output.stdout.as_slice(); | ||
if !stderr.is_empty() { | ||
eprintln!("{} stderr:\n{}", bin, std::str::from_utf8(stderr).unwrap()); | ||
} | ||
let stdout_opt = if !stdout.is_empty() { | ||
Some(std::str::from_utf8(stdout).unwrap().to_string()) | ||
} else { | ||
None | ||
}; | ||
CommandResult::new(output.status.success(), stdout_opt) | ||
} | ||
|
||
pub fn run_with_input(bin: &str, args: &[&str], input: &str) -> CommandResult { | ||
let mut proc = match process::Command::new(bin) | ||
.args(args.iter()) | ||
.stdin(Stdio::piped()) | ||
.spawn() { | ||
Ok(proc) => proc, | ||
Err(msg) => { | ||
eprintln!("Failed to spawn {} child process: {}", bin, msg); | ||
exit(ExitCode::CommandError); | ||
}, | ||
}; | ||
let proc_stdin = match proc.stdin.as_mut() { | ||
Some(stdin) => stdin, | ||
None => { | ||
eprintln!("Failed to get {} process stdin handle", bin); | ||
exit(ExitCode::CommandError); | ||
}, | ||
}; | ||
match proc_stdin.write_all(input.as_bytes()) { | ||
Ok(()) => (), | ||
Err(msg) => { | ||
eprintln!("Failed to write input to {} process stdin: {}", bin, msg); | ||
exit(ExitCode::CommandError); | ||
}, | ||
}; | ||
let output = match proc.wait_with_output() { | ||
Ok(output) => output, | ||
Err(msg) => { | ||
eprintln!("Failed to run with {}: {}", bin, msg); | ||
exit(ExitCode::CommandError); | ||
}, | ||
}; | ||
let stderr: &[u8] = output.stderr.as_slice(); | ||
let stdout: &[u8] = output.stdout.as_slice(); | ||
if !stderr.is_empty() { | ||
eprintln!("{} stderr:\n{}", bin, std::str::from_utf8(stderr).unwrap()); | ||
} | ||
let stdout_opt = if !stdout.is_empty() { | ||
Some(std::str::from_utf8(stdout).unwrap().to_string()) | ||
} else { | ||
None | ||
}; | ||
CommandResult::new(output.status.success(), stdout_opt) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// Copyright 2024, Giordano Salvador | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
|
||
/// Description: A C-stub used to generate the main module for linking during compile time. | ||
/// Values prefixed by `@@` are expected inputs from the compiler for text substitution. | ||
/// Inputs: | ||
/// * NUM_ARGS : a `usize` for the length of the parameters list | ||
/// * USAGE_ARGS : a comma separated list of args for the usage prompt | ||
/// : (e.g., <arg0>, <arg1>, ... | ||
/// * PARAM_TYPES_LIST : a comma separated list of types for the callee prototype | ||
/// * PARAM_DECLS_LIST : a sequence of statements assigning temporaries for the callee | ||
/// (e.g., const t_i64 p0 = (t_i64)atoll(argv[BASE + 0]); ... ) | ||
/// * PARAMS_LIST : a comma separated list of uses of the temporaries for the callee | ||
/// (e.g., p0, p1, ... ) | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
|
||
#define BASE 1 | ||
#define NUM_ARGS @@NUM_ARGS | ||
#define USAGE "<exe> @@USAGE_ARGS\n" | ||
|
||
typedef long long t_i64; | ||
extern t_i64 calcc_main(@@PARAM_TYPES_LIST); | ||
|
||
int main(int argc, char **argv) { | ||
if (argc != BASE + NUM_ARGS) { | ||
(void) fprintf(stderr, "Invalid number of args to main. Expected %d args\n", NUM_ARGS); | ||
(void) fprintf(stderr, USAGE); | ||
return 1; | ||
} | ||
|
||
/* Parameter declaration section: */ | ||
@@PARAM_DECLS_LIST | ||
|
||
/* Function call section: */ | ||
const t_i64 result = calcc_main(@@PARAMS_LIST); | ||
(void) printf("calcc_main result: %lld\n", result); | ||
|
||
return 0; | ||
} |
Oops, something went wrong.