real relative imports
This commit is contained in:
@@ -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()?;
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user