summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2024-05-01 00:09:30 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2024-05-01 00:09:30 +0200
commitcc318d3e7ee1006e98994f7d2e382a0a69445893 (patch)
treef814c73152086730338874716a91808057612a80
parentaa74f757abdabc386b76858f8a3c0babdb478a0b (diff)
downloadrebel-cc318d3e7ee1006e98994f7d2e382a0a69445893.tar
rebel-cc318d3e7ee1006e98994f7d2e382a0a69445893.zip
rebel-parse: add support for different path roots
Distinguish relative (unprefixed), absolute (`::` prefix) and section-specific (`recipe::`, `task::`) paths.
-rw-r--r--crates/rebel-lang/src/scope.rs12
-rw-r--r--crates/rebel-parse/src/ast/mod.rs9
-rw-r--r--crates/rebel-parse/src/grammar/recipe.rs13
-rw-r--r--crates/rebel-parse/src/grammar/tokenize.rs1
-rw-r--r--crates/rebel-parse/src/token.rs1
5 files changed, 35 insertions, 1 deletions
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<ast::Ident<'a>> {
+ 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<Ident<'a>>,
}
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,