real relative imports

This commit is contained in:
2026-07-15 18:26:28 +02:00
parent 9bbd382e10
commit af08d1888a
47 changed files with 101 additions and 124 deletions

View File

@@ -7,16 +7,11 @@ mod typechecker;
use std::{
collections::HashSet,
fs,
path::Path,
process::{self, Command},
};
use tokenizer::ZernError;
#[cfg(feature = "mimalloc")]
#[global_allocator]
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
fn compile_file(args: Args) -> Result<(), ZernError> {
let source = match fs::read_to_string(&args.path) {
Ok(x) => x,
@@ -26,10 +21,8 @@ fn compile_file(args: Args) -> Result<(), ZernError> {
}
};
let filename = Path::new(&args.path).file_name().unwrap().to_str().unwrap();
let mut included_paths = HashSet::new();
let tokenizer = tokenizer::Tokenizer::new(filename.to_owned(), source, &mut included_paths);
let tokenizer = tokenizer::Tokenizer::new(args.path, source, &mut included_paths);
let parser = parser::Parser::new(tokenizer.tokenize()?);
let statements = parser.parse()?;

View File

@@ -449,28 +449,40 @@ impl<'a> Tokenizer<'a> {
self.include_file(path)
}
fn include_file(&mut self, path: String) -> Result<(), ZernError> {
let canonical = match fs::canonicalize(&path) {
fn include_file(&mut self, mut path: String) -> Result<(), ZernError> {
if path.starts_with("$/") {
path = find_std_path()
.join(&path[2..])
.to_string_lossy()
.into_owned();
}
let base_dir = Path::new(&self.loc.filename).parent().unwrap();
let resolved_path = base_dir.join(&path);
let canonical = match fs::canonicalize(&resolved_path) {
Ok(p) => p,
Err(e) => {
return error!(self.loc, format!("failed to resolve {}: {}", path, e));
}
};
if !self.included_paths.insert(canonical) {
if !self.included_paths.insert(canonical.clone()) {
return Ok(());
}
let source = match fs::read_to_string(&path) {
let source = match fs::read_to_string(&canonical) {
Ok(x) => x,
Err(_) => {
return error!(self.loc, format!("failed to include {}", path));
}
};
let filename = Path::new(&path).file_name().unwrap().to_str().unwrap();
let tokenizer = Tokenizer::new(filename.to_owned(), source, &mut *self.included_paths);
let tokenizer = Tokenizer::new(
canonical.to_string_lossy().into_owned(),
source,
&mut *self.included_paths,
);
self.tokens.extend(tokenizer.tokenize()?);
self.tokens.pop(); // remove inner Eof
@@ -550,3 +562,15 @@ impl<'a> Tokenizer<'a> {
self.current >= self.source.len()
}
}
fn find_std_path() -> PathBuf {
let path = std::env::current_exe().unwrap();
for dir in path.ancestors() {
let candidate = dir.join("std");
if candidate.is_dir() {
return candidate;
}
}
panic!("could not find zern std directory");
}