Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 1 addition & 30 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 21 additions & 5 deletions crates/rue-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,16 @@ fn build(args: BuildArgs) -> Result<()> {
let mut ctx = Compiler::new(project.options);

let tree = FileTree::compile_path(&mut ctx, &project.entrypoint, &mut HashMap::new())?;
let base_path = if project.entrypoint.is_file() {
project.entrypoint.parent().unwrap().canonicalize()?
} else {
project.entrypoint.canonicalize()?
};

let mut codegen = true;

for diagnostic in ctx.take_diagnostics() {
let message = diagnostic.message();
let message = diagnostic.message(&base_path);
let severity = diagnostic.kind.severity();

if severity == DiagnosticSeverity::Error {
Expand All @@ -156,7 +161,13 @@ fn build(args: BuildArgs) -> Result<()> {

let program = if let Some(export) = args.export {
let Some(program) = tree
.exports(&mut ctx, &mut allocator, file_kind.as_ref(), Some(&export))?
.exports(
&mut ctx,
&mut allocator,
file_kind.as_ref(),
Some(&export),
&base_path,
)?
.into_iter()
.next()
else {
Expand All @@ -166,7 +177,7 @@ fn build(args: BuildArgs) -> Result<()> {

program.ptr
} else if let Some(main_kind) = main_kind
&& let Some(ptr) = tree.main(&mut ctx, &mut allocator, &main_kind)?
&& let Some(ptr) = tree.main(&mut ctx, &mut allocator, &main_kind, base_path)?
{
ptr
} else {
Expand Down Expand Up @@ -210,11 +221,16 @@ fn test(args: TestArgs) -> Result<()> {
let mut ctx = Compiler::new(project.options);

let tree = FileTree::compile_path(&mut ctx, &project.entrypoint, &mut HashMap::new())?;
let base_path = if project.entrypoint.is_file() {
project.entrypoint.parent().unwrap().canonicalize()?
} else {
project.entrypoint.canonicalize()?
};

let mut codegen = true;

for diagnostic in ctx.take_diagnostics() {
let message = diagnostic.message();
let message = diagnostic.message(&base_path);
let severity = diagnostic.kind.severity();

if severity == DiagnosticSeverity::Error {
Expand All @@ -229,7 +245,7 @@ fn test(args: TestArgs) -> Result<()> {
process::exit(1);
}

let tests = tree.tests(&mut ctx, &mut allocator, None, None)?;
let tests = tree.tests(&mut ctx, &mut allocator, None, None, &base_path)?;

let len = tests.len();

Expand Down
9 changes: 9 additions & 0 deletions crates/rue-compiler/src/compile/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,15 @@ where
);
PathResult::Unresolved
}
(PathResult::Symbol(symbol, _, _), PathKind::Symbol) => {
if let Symbol::Module(_) = ctx.symbol(symbol) {
ctx.diagnostic(
range,
DiagnosticKind::CannotReferenceModule(previous_name.unwrap()),
);
}
value
}
_ => value,
}
}
33 changes: 21 additions & 12 deletions crates/rue-compiler/src/file.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::{
collections::{HashMap, HashSet},
fs, io,
path::Path,
path::{Path, PathBuf},
sync::Arc,
};

Expand Down Expand Up @@ -32,7 +32,7 @@ pub enum Error {
#[error("Codegen error: {0}")]
Lir(#[from] rue_lir::Error),

#[error("Source not found in compilation unit: {0}")]
#[error("Source not found in compilation unit")]
SourceNotFound(SourceKind),
}

Expand All @@ -58,14 +58,11 @@ pub enum FileTree {
}

impl FileTree {
pub fn compile_file(ctx: &mut Compiler, path: &Path, file_name: String) -> Result<Self, Error> {
pub fn compile_file(ctx: &mut Compiler, path: &Path) -> Result<Self, Error> {
let tree = Self::File(File::new(
ctx,
"main".to_string(),
Source::new(
Arc::from(fs::read_to_string(path)?),
SourceKind::File(file_name),
),
Source::new(Arc::from(fs::read_to_string(path)?), normalize_path(path)?),
));

tree.compile(ctx);
Expand Down Expand Up @@ -250,6 +247,7 @@ impl FileTree {
ctx: &mut Compiler,
allocator: &mut Allocator,
path: &SourceKind,
base_path: PathBuf,
) -> Result<Option<NodePtr>, Error> {
let tree = self
.find(path)
Expand All @@ -260,7 +258,7 @@ impl FileTree {
return Ok(None);
};

Ok(Some(codegen(ctx, allocator, main)?))
Ok(Some(codegen(ctx, allocator, main, base_path)?))
}

pub fn exports(
Expand All @@ -269,12 +267,21 @@ impl FileTree {
allocator: &mut Allocator,
path: Option<&SourceKind>,
export_name: Option<&str>,
base_path: &Path,
) -> Result<Vec<CompiledExport>, Error> {
let Some(path) = path else {
return Ok(self
.all_files()
.iter()
.map(|file| self.exports(ctx, allocator, Some(&file.source.kind), export_name))
.map(|file| {
self.exports(
ctx,
allocator,
Some(&file.source.kind),
export_name,
base_path,
)
})
.collect::<Result<Vec<_>, Error>>()?
.into_iter()
.flatten()
Expand All @@ -301,7 +308,7 @@ impl FileTree {
continue;
}

let ptr = codegen(ctx, allocator, symbol)?;
let ptr = codegen(ctx, allocator, symbol, base_path.to_path_buf())?;
exports.push(CompiledExport { name, symbol, ptr });
}

Expand All @@ -314,6 +321,7 @@ impl FileTree {
allocator: &mut Allocator,
path: Option<&SourceKind>,
search_term: Option<&str>,
base_path: &Path,
) -> Result<Vec<CompiledTest>, Error> {
let tests = ctx
.tests()
Expand All @@ -340,7 +348,7 @@ impl FileTree {
let mut outputs = Vec::new();

for test in tests {
let ptr = codegen(ctx, allocator, test.symbol)?;
let ptr = codegen(ctx, allocator, test.symbol, base_path.to_path_buf())?;
outputs.push(CompiledTest {
name: test.name,
path: test.path,
Expand Down Expand Up @@ -635,12 +643,13 @@ fn codegen(
ctx: &mut Compiler,
allocator: &mut Allocator,
symbol: SymbolId,
base_path: PathBuf,
) -> Result<NodePtr, Error> {
let options = *ctx.options();
let graph = DependencyGraph::build(ctx, symbol, options);

let mut arena = Arena::new();
let mut lowerer = Lowerer::new(ctx, &mut arena, &graph, options, symbol);
let mut lowerer = Lowerer::new(ctx, &mut arena, &graph, options, symbol, base_path);
let mut lir = lowerer.lower_symbol_value(&Environment::default(), symbol);

if options.optimize_lir {
Expand Down
1 change: 0 additions & 1 deletion crates/rue-diagnostic/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,3 @@ workspace = true

[dependencies]
thiserror = { workspace = true }
derive_more = { workspace = true, features = ["display"] }
11 changes: 9 additions & 2 deletions crates/rue-diagnostic/src/diagnostic.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::path::Path;

use crate::{DiagnosticKind, LineCol, SrcLoc};

#[derive(Debug, Clone)]
Expand All @@ -19,9 +21,14 @@ impl Diagnostic {
self.srcloc.end()
}

pub fn message(&self) -> String {
pub fn message(&self, relative_to: &Path) -> String {
let start = self.start();

format!("{} at {}:{}", self.kind, self.srcloc.source.kind, start)
format!(
"{} at {}:{}",
self.kind,
self.srcloc.source.kind.display(relative_to),
start
)
}
}
4 changes: 4 additions & 0 deletions crates/rue-diagnostic/src/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ pub enum DiagnosticKind {
#[error("Expected type, but found symbol `{0}`")]
ExpectedType(String),

#[error("Cannot reference module `{0}`")]
CannotReferenceModule(String),

#[error("Generic arguments are not permitted on symbol references")]
GenericArgumentsOnSymbolReference,

Expand Down Expand Up @@ -269,6 +272,7 @@ impl DiagnosticKind {
| Self::PrivateType(..)
| Self::ExpectedSymbol(..)
| Self::ExpectedType(..)
| Self::CannotReferenceModule(..)
| Self::GenericArgumentsOnSymbolReference
| Self::NonStructInitializer(..)
| Self::MissingRequiredFields(..)
Expand Down
24 changes: 13 additions & 11 deletions crates/rue-diagnostic/src/srcloc.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use std::{fmt, ops::Range, sync::Arc};

use derive_more::Display;
use std::{ops::Range, path::Path, sync::Arc};

use crate::LineCol;

Expand All @@ -16,12 +14,9 @@ impl Source {
}
}

#[derive(Debug, Clone, Display, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum SourceKind {
#[display("std")]
Std,

#[display("{_0}")]
File(String),
}

Expand All @@ -32,6 +27,15 @@ impl SourceKind {
Self::File(_) => true,
}
}

pub fn display(&self, relative_to: &Path) -> String {
match self {
Self::Std => "std".to_string(),
Self::File(path) => Path::new(path)
.strip_prefix(relative_to)
.map_or_else(|_| path.clone(), |path| path.to_string_lossy().to_string()),
}
}
}

#[derive(Debug, Clone)]
Expand All @@ -52,10 +56,8 @@ impl SrcLoc {
pub fn end(&self) -> LineCol {
LineCol::new(&self.source.text, self.span.end)
}
}

impl fmt::Display for SrcLoc {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}:{}", self.source.kind, self.start())
pub fn display(&self, relative_to: &Path) -> String {
format!("{}:{}", self.source.kind.display(relative_to), self.start())
}
}
Loading
Loading