From e7cd2c01290d9a13823ce20c105a22b692e6b59a Mon Sep 17 00:00:00 2001 From: Jakub Doka Date: Sat, 30 Nov 2024 15:44:51 +0100 Subject: [PATCH] making the loader function customizable Signed-off-by: Jakub Doka --- lang/README.md | 2 +- lang/src/fs.rs | 48 +++++++++++++++++++++++++++++++----------------- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/lang/README.md b/lang/README.md index ca753f33d..f2443ae3d 100644 --- a/lang/README.md +++ b/lang/README.md @@ -571,7 +571,7 @@ Vec := fn($Elem: type): type return struct { len: uint, cap: uint, - new := fn(): Self return .{data: @bitcast(0), len: 0, cap: 0} + new := fn(): Self return .{data: @bitcast(@alignof(Elem)), len: 0, cap: 0} deinit := fn(vec: ^Self): void { free(@bitcast(vec.data), vec.cap * @sizeof(Elem), @alignof(Elem)); diff --git a/lang/src/fs.rs b/lang/src/fs.rs index 23c504715..eed314a79 100644 --- a/lang/src/fs.rs +++ b/lang/src/fs.rs @@ -37,15 +37,16 @@ impl log::Log for Logger { } #[derive(Default)] -pub struct Options { +pub struct Options<'a> { pub fmt: bool, pub fmt_stdout: bool, pub dump_asm: bool, pub in_house_regalloc: bool, pub extra_threads: usize, + pub resolver: Option>, } -impl Options { +impl Options<'static> { pub fn from_args(args: &[&str], out: &mut Vec) -> std::io::Result { if args.contains(&"--help") || args.contains(&"-h") { writeln!(out, "Usage: hbc [OPTIONS...] ")?; @@ -71,6 +72,7 @@ impl Options { .transpose()? .map_or(1, NonZeroUsize::get) - 1, + ..Default::default() }) } } @@ -81,7 +83,11 @@ pub fn run_compiler( out: &mut Vec, warnings: &mut String, ) -> std::io::Result<()> { - let parsed = parse_from_fs(options.extra_threads, root_file)?; + let parsed = parse_from_fs( + options.extra_threads, + root_file, + options.resolver.unwrap_or(&default_resolve), + )?; if (options.fmt || options.fmt_stdout) && !parsed.errors.is_empty() { *out = parsed.errors.into_bytes(); @@ -220,23 +226,31 @@ pub struct Loaded { errors: String, } -pub fn parse_from_fs(extra_threads: usize, root: &str) -> io::Result { - fn resolve(path: &str, from: &str, tmp: &mut PathBuf) -> Result { - tmp.clear(); - match Path::new(from).parent() { - Some(parent) => tmp.extend([parent, Path::new(path)]), - None => tmp.push(path), - }; +fn default_resolve(path: &str, from: &str, tmp: &mut PathBuf) -> Result { + tmp.clear(); + match Path::new(from).parent() { + Some(parent) => tmp.extend([parent, Path::new(path)]), + None => tmp.push(path), + }; - tmp.canonicalize().map_err(|source| CantLoadFile { path: std::mem::take(tmp), source }) - } + tmp.canonicalize().map_err(|source| CantLoadFile { path: std::mem::take(tmp), source }) +} - #[derive(Debug)] - struct CantLoadFile { - path: PathBuf, - source: io::Error, - } +/// fn(path, from, tmp) +pub type PathResolver<'a> = + &'a (dyn Fn(&str, &str, &mut PathBuf) -> Result + Send + Sync); +#[derive(Debug)] +pub struct CantLoadFile { + path: PathBuf, + source: io::Error, +} + +pub fn parse_from_fs( + extra_threads: usize, + root: &str, + resolve: PathResolver, +) -> io::Result { impl core::fmt::Display for CantLoadFile { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { write!(f, "can't load file: {}", display_rel_path(&self.path),)