diff --git a/compiler/cl-ast/src/desugar.rs b/compiler/cl-ast/src/desugar.rs index 2b5e631..2f1466b 100644 --- a/compiler/cl-ast/src/desugar.rs +++ b/compiler/cl-ast/src/desugar.rs @@ -1,5 +1,9 @@ //! Desugaring passes for Conlang +pub mod path_absoluter; +pub mod squash_groups; pub mod while_else; -pub mod squash_groups; +pub use path_absoluter::NormalizePaths; +pub use squash_groups::SquashGroups; +pub use while_else::WhileElseDesugar; diff --git a/compiler/cl-ast/src/desugar/path_absoluter.rs b/compiler/cl-ast/src/desugar/path_absoluter.rs new file mode 100644 index 0000000..6176eb3 --- /dev/null +++ b/compiler/cl-ast/src/desugar/path_absoluter.rs @@ -0,0 +1,54 @@ +use crate::{ast::*, ast_visitor::Fold}; + +/// Converts relative paths into absolute paths +pub struct NormalizePaths { + path: Path, +} + +impl NormalizePaths { + pub fn new() -> Self { + Self { path: Path { absolute: true, parts: vec![] } } + } + /// Normalizes paths as if they came from within the provided paths + pub fn in_path(path: Path) -> Self { + Self { path } + } +} + +impl Default for NormalizePaths { + fn default() -> Self { + Self::new() + } +} + +impl Fold for NormalizePaths { + fn fold_module(&mut self, m: Module) -> Module { + let Module { name, kind } = m; + self.path.push(PathPart::Ident(name.clone())); + + let (name, kind) = (self.fold_identifier(name), self.fold_module_kind(kind)); + + self.path.pop(); + Module { name, kind } + } + + fn fold_path(&mut self, p: Path) -> Path { + if p.absolute { + p + } else { + self.path.clone().concat(&p) + } + } + + fn fold_use(&mut self, u: Use) -> Use { + let Use { absolute, mut tree } = u; + + if !absolute { + for segment in self.path.parts.iter().rev() { + tree = UseTree::Path(segment.clone(), Box::new(tree)) + } + } + + Use { absolute: true, tree: self.fold_use_tree(tree) } + } +} diff --git a/compiler/cl-typeck/examples/typeck.rs b/compiler/cl-typeck/examples/typeck.rs index 53a02db..23c06f3 100644 --- a/compiler/cl-typeck/examples/typeck.rs +++ b/compiler/cl-typeck/examples/typeck.rs @@ -1,6 +1,6 @@ use cl_ast::{ ast_visitor::{Fold, Visit}, - desugar::{squash_groups::SquashGroups, while_else::WhileElseDesugar}, + desugar::*, }; use cl_lexer::Lexer; use cl_parser::{inliner::ModuleInliner, Parser}; @@ -104,6 +104,9 @@ fn live_desugar() -> Result<(), RlError> { let code = WhileElseDesugar.fold_stmt(code); println!("WhileElseDesugar\n{C_LISTING}{code}\x1b[0m"); + let code = NormalizePaths::new().fold_stmt(code); + println!("NormalizePaths\n{C_LISTING}{code}\x1b[0m"); + Ok(Response::Accept) }) }