Skip to content

Commit

Permalink
Refactored and cleaned up some main driver code
Browse files Browse the repository at this point in the history
  • Loading branch information
IsaacShelton committed Dec 9, 2024
1 parent ff4f922 commit 5644a63
Show file tree
Hide file tree
Showing 9 changed files with 156 additions and 129 deletions.
4 changes: 2 additions & 2 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::target::{Target, TargetOs};
use std::{path::PathBuf, process::exit, str::FromStr};
use std::{path::PathBuf, str::FromStr};

pub struct Command {
pub kind: CommandKind,
Expand All @@ -12,7 +12,7 @@ impl Command {
match args.peek().map(|string| string.as_str()) {
None | Some("-h" | "--help") => {
show_help();
exit(0);
Err(())
}
Some("new") => Self::parse_new_project(args),
_ => Self::parse_build_project(args),
Expand Down
76 changes: 39 additions & 37 deletions src/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,51 +22,53 @@ pub struct Compiler<'a> {
}

impl<'a> Compiler<'a> {
pub fn maybe_execute_result(&self, output_binary_filepath: &Path) {
if self.options.excute_result {
println!(" ==== executing result ====");
pub fn maybe_execute_result(&self, output_binary_filepath: &Path) -> Result<(), ()> {
if !self.options.excute_result {
return Ok(());
}

// Avoid using a relative filename to invoke the resulting executable
let output_binary_filepath = if output_binary_filepath.is_relative() {
let Ok(absolute_filename) = absolute(&output_binary_filepath) else {
eprintln!(
"error: Failed to get absolute filename of resulting executable '{}'",
output_binary_filepath.to_string_lossy().as_ref(),
);
std::process::exit(1);
};
println!(" ==== executing result ====");

Cow::Owned(absolute_filename)
} else {
Cow::Borrowed(output_binary_filepath)
// Avoid using a relative filename to invoke the resulting executable
let output_binary_filepath = if output_binary_filepath.is_relative() {
let Ok(absolute_filename) = absolute(&output_binary_filepath) else {
eprintln!(
"error: Failed to get absolute filename of resulting executable '{}'",
output_binary_filepath.to_string_lossy().as_ref(),
);
return Err(());
};

let mut last_error = None;
Cow::Owned(absolute_filename)
} else {
Cow::Borrowed(output_binary_filepath)
};

for retry_duration in [10, 10, 10, 50, 100, 250].map(Duration::from_millis) {
match Command::new(output_binary_filepath.as_os_str())
.args([] as [&str; 0])
.spawn()
{
Ok(mut process) => {
let _ = process.wait();
return;
}
Err(e) => {
last_error = Some(e);
let mut last_error = None;

// Try again in few milliseconds
std::thread::sleep(retry_duration);
}
for retry_duration in [10, 10, 10, 50, 100, 250].map(Duration::from_millis) {
match Command::new(output_binary_filepath.as_os_str())
.args([] as [&str; 0])
.spawn()
{
Ok(mut process) => {
let _ = process.wait();
return Ok(());
}
}
Err(e) => {
last_error = Some(e);

eprintln!(
"error: failed to run resulting executable '{}' - {}",
output_binary_filepath.to_string_lossy().as_ref(),
last_error.unwrap()
);
std::process::exit(1);
// Try again in few milliseconds
std::thread::sleep(retry_duration);
}
}
}

eprintln!(
"error: failed to run resulting executable '{}' - {}",
output_binary_filepath.to_string_lossy().as_ref(),
last_error.unwrap()
);
return Err(());
}
}
17 changes: 10 additions & 7 deletions src/generate_workspace/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@

use crate::cli::NewCommand;
use indoc::indoc;
use std::{borrow::Borrow, fs, path::Path, process::exit};
use std::{borrow::Borrow, fs, path::Path};

pub fn new_project(new_command: NewCommand) {
pub fn new_project(new_command: NewCommand) -> Result<(), ()> {
if std::fs::create_dir(&new_command.project_name).is_err() {
eprintln!(
"error: Failed to create project directory '{}'",
&new_command.project_name
);
exit(1);
return Err(());
}

let folder = Path::new(&new_command.project_name);
Expand All @@ -27,7 +27,7 @@ pub fn new_project(new_command: NewCommand) {
adept("3.0")
}
"#},
);
)?;

put_file(
folder.join("main.adept"),
Expand All @@ -37,12 +37,13 @@ pub fn new_project(new_command: NewCommand) {
println("Hello World!")
}
"#},
);
)?;

println!("Project created!");
Ok(())
}

fn put_file(path: impl Borrow<Path>, content: &str) {
fn put_file(path: impl Borrow<Path>, content: &str) -> Result<(), ()> {
let path = path.borrow();

if fs::write(path, content).is_err() {
Expand All @@ -52,6 +53,8 @@ fn put_file(path: impl Borrow<Path>, content: &str) {
.unwrap_or("<invalid unicode filename>");

eprintln!("error: Failed to create '{}' file", error_filename);
exit(1);
return Err(());
}

Ok(())
}
9 changes: 4 additions & 5 deletions src/linking/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,11 @@ pub fn link_result(
.join(&format!("from_{}_{}", host_arch.unwrap(), host_os.unwrap()))
.join("x86_64-w64-mingw32-ld")
} else {
please_manually_link(args, diagnostics);
return Err(please_manually_link(args, diagnostics));
}
}
Some(TargetOs::Mac | TargetOs::Linux | TargetOs::FreeBsd) | None => {
please_manually_link(args, diagnostics);
return Err(please_manually_link(args, diagnostics));
}
}
};
Expand All @@ -143,7 +143,7 @@ pub fn link_result(
Ok(start_time.elapsed())
}

fn please_manually_link(args: Vec<OsString>, diagnostics: &Diagnostics) -> ! {
fn please_manually_link(args: Vec<OsString>, diagnostics: &Diagnostics) -> BackendError {
let args = args.join(OsStr::new(" "));

diagnostics.push(WarningDiagnostic::plain(
Expand All @@ -153,8 +153,7 @@ fn please_manually_link(args: Vec<OsString>, diagnostics: &Diagnostics) -> ! {
)
));

eprintln!("Success, but requires manual linking, exiting with 1");
std::process::exit(1);
BackendError::plain("Success, but requires manual linking, exiting with 1")
}

fn is_flag_like(string: &str) -> bool {
Expand Down
47 changes: 24 additions & 23 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,27 +48,31 @@ mod version;
mod workspace;

use crate::{cli::BuildCommand, show::Show, source_files::SourceFiles, text::IntoText};
use cli::CommandKind;
use compiler::Compiler;
use diagnostics::{DiagnosticFlags, Diagnostics, WarningDiagnostic};
use generate_workspace::new_project;
use single_file_only::compile_single_file_only;
use std::{fs::metadata, path::Path, process::exit};
use std::{fs::metadata, path::Path, process::ExitCode};
use target::{TargetArch, TargetOs};
use text::IntoTextStream;
use workspace::compile_workspace;

fn main() {
fn main() -> ExitCode {
let Ok(args) = cli::Command::parse_env_args() else {
exit(1)
return ExitCode::FAILURE;
};

match args.kind {
cli::CommandKind::Build(build_command) => build_project(build_command),
cli::CommandKind::New(new_command) => new_project(new_command),
match match args.kind {
CommandKind::Build(build_command) => build_project(build_command),
CommandKind::New(new_command) => new_project(new_command),
} {
Ok(()) => ExitCode::SUCCESS,
Err(()) => ExitCode::FAILURE,
}
}

fn build_project(build_command: BuildCommand) {
fn build_project(build_command: BuildCommand) -> Result<(), ()> {
let BuildCommand { filename, options } = build_command;
let source_files = SourceFiles::new();
let filepath = Path::new(&filename);
Expand All @@ -77,7 +81,7 @@ fn build_project(build_command: BuildCommand) {

let Ok(metadata) = metadata(filepath) else {
eprintln!("error: File or folder does not exist");
exit(1);
return Err(());
};

if target.arch().is_none() {
Expand Down Expand Up @@ -120,20 +124,17 @@ fn build_project(build_command: BuildCommand) {
};

if metadata.is_dir() {
compile_workspace(&mut compiler, filepath, None);
return;
return compile_workspace(&mut compiler, filepath, None);
}

// Experimental header parsing
if filepath.extension().unwrap_or_default() == "h" {
let source_files = compiler.source_files;

let content = std::fs::read_to_string(filepath)
.map_err(|err| {
eprintln!("{}", err);
exit(1);
})
.unwrap();
let content = std::fs::read_to_string(filepath).map_err(|err| {
eprintln!("{}", err);
()
})?;

let header_key = source_files.add(filepath.into(), content);

Expand All @@ -144,30 +145,30 @@ fn build_project(build_command: BuildCommand) {
.into_text_stream(header_key)
.into_text();

let preprocessed = exit_unless(
let preprocessed = unerror(
c::preprocessor::preprocess(header_contents, &diagnostics),
&source_files,
);
)?;

println!("{preprocessed:?}");
return;
return Ok(());
}

let project_folder = filepath.parent().unwrap();
compile_single_file_only(&mut compiler, project_folder, filepath);
compile_single_file_only(&mut compiler, project_folder, filepath)
}

fn exit_unless<T, E: Show>(result: Result<T, E>, source_files: &SourceFiles) -> T {
fn unerror<T, E: Show>(result: Result<T, E>, source_files: &SourceFiles) -> Result<T, ()> {
match result {
Ok(value) => value,
Ok(value) => Ok(value),
Err(err) => {
let mut message = String::new();

err.show(&mut message, source_files)
.expect("show error message");

eprintln!("{message}");
exit(1);
Err(())
}
}
}
6 changes: 5 additions & 1 deletion src/single_file_only/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
use crate::{compiler::Compiler, workspace::compile_workspace};
use std::path::Path;

pub fn compile_single_file_only(compiler: &mut Compiler, project_folder: &Path, filepath: &Path) {
pub fn compile_single_file_only(
compiler: &mut Compiler,
project_folder: &Path,
filepath: &Path,
) -> Result<(), ()> {
compile_workspace(compiler, project_folder, Some(filepath.to_path_buf()))
}
37 changes: 37 additions & 0 deletions src/workspace/explore_within.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use super::{
explore::{explore, ExploreResult},
fs::{Fs, FsNodeId},
module_file::ModuleFile,
};
use std::path::{Path, PathBuf};

pub struct ExploreWithinResult {
pub explored: Option<ExploreResult>,
pub entry: Option<FsNodeId>,
}

pub fn explore_within(
fs: &Fs,
project_folder: &Path,
single_file: Option<PathBuf>,
) -> ExploreWithinResult {
if let Some(single_file) = single_file {
let fs_node_id = fs.insert(&single_file, None).expect("inserted");

ExploreWithinResult {
explored: Some(ExploreResult {
normal_files: vec![],
module_files: vec![ModuleFile {
path: single_file,
fs_node_id,
}],
}),
entry: Some(fs_node_id),
}
} else {
ExploreWithinResult {
explored: explore(fs, project_folder),
entry: None,
}
}
}
Loading

0 comments on commit 5644a63

Please sign in to comment.