From cc318d3e7ee1006e98994f7d2e382a0a69445893 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 1 May 2024 00:09:30 +0200 Subject: rebel-parse: add support for different path roots Distinguish relative (unprefixed), absolute (`::` prefix) and section-specific (`recipe::`, `task::`) paths. --- crates/rebel-lang/src/scope.rs | 12 ++++++++++++ crates/rebel-parse/src/ast/mod.rs | 9 +++++++++ crates/rebel-parse/src/grammar/recipe.rs | 13 ++++++++++++- crates/rebel-parse/src/grammar/tokenize.rs | 1 + crates/rebel-parse/src/token.rs | 1 + 5 files changed, 35 insertions(+), 1 deletion(-) diff --git a/crates/rebel-lang/src/scope.rs b/crates/rebel-lang/src/scope.rs index ccf2064..4b47435 100644 --- a/crates/rebel-lang/src/scope.rs +++ b/crates/rebel-lang/src/scope.rs @@ -43,6 +43,10 @@ impl Default for Context { impl Context { pub fn local_ident<'a>(path: &'a ast::Path) -> Option> { + if path.root != ast::PathRoot::Relative { + return None; + } + let [ident] = path.components[..] else { return None; }; @@ -50,6 +54,10 @@ impl Context { } pub fn lookup_var(&self, path: &ast::Path) -> Option<&Var> { + if path.root != ast::PathRoot::Relative { + return None; + } + if path.components == [ast::Ident { name: "_" }] { return None; } @@ -58,6 +66,10 @@ impl Context { } pub fn lookup_type(&self, path: &ast::Path) -> Option<&Type> { + if path.root != ast::PathRoot::Relative { + return None; + } + if path.components == [ast::Ident { name: "_" }] { return Some(&Type::Free); } diff --git a/crates/rebel-parse/src/ast/mod.rs b/crates/rebel-parse/src/ast/mod.rs index 4fa8e63..eb6a7bd 100644 --- a/crates/rebel-parse/src/ast/mod.rs +++ b/crates/rebel-parse/src/ast/mod.rs @@ -131,8 +131,17 @@ pub struct FuncParam<'a> { pub typ: Type<'a>, } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum PathRoot { + Absolute, + Relative, + Recipe, + Task, +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct Path<'a> { + pub root: PathRoot, pub components: Vec>, } diff --git a/crates/rebel-parse/src/grammar/recipe.rs b/crates/rebel-parse/src/grammar/recipe.rs index b1ac32f..50a0694 100644 --- a/crates/rebel-parse/src/grammar/recipe.rs +++ b/crates/rebel-parse/src/grammar/recipe.rs @@ -164,7 +164,18 @@ peg::parser! { } rule path() -> ast::Path<'a> - = components:ident() ++ p2(':', ':') { ast::Path { components } } + = components:(ident() ++ p2(':', ':')) { + ast::Path { root: ast::PathRoot::Relative, components } + } + / components:(p2(':', ':') ident:ident() { ident })+ { + ast::Path { root: ast::PathRoot::Absolute, components } + } + / [Token::Keyword(Keyword::Recipe)] components:(p2(':', ':') ident:ident() { ident })* { + ast::Path { root: ast::PathRoot::Recipe, components } + } + / [Token::Keyword(Keyword::Task)] components:(p2(':', ':') ident:ident() { ident })* { + ast::Path { root: ast::PathRoot::Task, components } + } rule field() -> ast::Ident<'a> = ident() diff --git a/crates/rebel-parse/src/grammar/tokenize.rs b/crates/rebel-parse/src/grammar/tokenize.rs index 8696a89..70df2c3 100644 --- a/crates/rebel-parse/src/grammar/tokenize.rs +++ b/crates/rebel-parse/src/grammar/tokenize.rs @@ -8,6 +8,7 @@ static KEYWORDS: phf::Map<&'static str, Keyword> = phf::phf_map! { "let" => Keyword::Let, "map" => Keyword::Map, "mut" => Keyword::Mut, + "recipe" => Keyword::Recipe, "set" => Keyword::Set, "struct" => Keyword::Struct, "task" => Keyword::Task, diff --git a/crates/rebel-parse/src/token.rs b/crates/rebel-parse/src/token.rs index cbdd932..2f86dbd 100644 --- a/crates/rebel-parse/src/token.rs +++ b/crates/rebel-parse/src/token.rs @@ -14,6 +14,7 @@ pub enum Keyword { Let, Map, Mut, + Recipe, Set, Struct, Task, -- cgit v1.2.3