summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2024-05-01 12:42:04 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2024-05-01 12:42:04 +0200
commit8308121242d3982152d1136dd485599d988fdb5d (patch)
treed4a41cfc2a04d1bc9763d077dc1b5fa83443eb7f
parent9d3b1c1c75cc44a67fc68d81fbe284b42fb466ec (diff)
downloadrebel-8308121242d3982152d1136dd485599d988fdb5d.tar
rebel-8308121242d3982152d1136dd485599d988fdb5d.zip
scope: introduce LookupError type
-rw-r--r--crates/rebel-lang/src/scope.rs21
-rw-r--r--crates/rebel-lang/src/typing.rs8
-rw-r--r--crates/rebel-lang/src/value.rs1
3 files changed, 20 insertions, 10 deletions
diff --git a/crates/rebel-lang/src/scope.rs b/crates/rebel-lang/src/scope.rs
index 3f2e682..bb3f2e9 100644
--- a/crates/rebel-lang/src/scope.rs
+++ b/crates/rebel-lang/src/scope.rs
@@ -15,6 +15,11 @@ pub struct Var {
pub value: Option<Value>,
}
+#[derive(Debug)]
+pub struct LookupError;
+
+pub type Result<T> = std::result::Result<T, LookupError>;
+
#[derive(Debug, Clone)]
pub struct Context {
pub vars: Module<Var>,
@@ -60,28 +65,28 @@ impl Context {
Some(ident)
}
- pub fn lookup_var(&self, path: &ast::Path) -> Option<&Var> {
+ pub fn lookup_var(&self, path: &ast::Path) -> Result<&Var> {
if path.root != ast::PathRoot::Relative {
- return None;
+ return Err(LookupError);
}
if path.components == [ast::Ident { name: "_" }] {
- return None;
+ return Err(LookupError);
}
- self.vars.lookup(&path.components)
+ self.vars.lookup(&path.components).ok_or(LookupError)
}
- pub fn lookup_type(&self, path: &ast::Path) -> Option<&Type> {
+ pub fn lookup_type(&self, path: &ast::Path) -> Result<&Type> {
if path.root != ast::PathRoot::Relative {
- return None;
+ return Err(LookupError);
}
if path.components == [ast::Ident { name: "_" }] {
- return Some(&Type::Free);
+ return Ok(&Type::Free);
}
- self.types.lookup(&path.components)
+ self.types.lookup(&path.components).ok_or(LookupError)
}
pub fn record_type(&mut self, stmt: &ast::BlockStmt) -> typing::Result<Type> {
diff --git a/crates/rebel-lang/src/typing.rs b/crates/rebel-lang/src/typing.rs
index 3fd0ee2..a441b1c 100644
--- a/crates/rebel-lang/src/typing.rs
+++ b/crates/rebel-lang/src/typing.rs
@@ -90,7 +90,7 @@ impl Type {
}
fn path_type(ctx: &Context, path: &ast::Path<'_>) -> Result<Type> {
- ctx.lookup_type(path).cloned().ok_or(TypeError)
+ ctx.lookup_type(path).cloned().or(Err(TypeError))
}
fn literal_type(ctx: &Context, lit: &typ::Literal<'_>) -> Result<Type> {
@@ -292,7 +292,11 @@ impl Type {
}
fn path_expr_type(ctx: &Context, path: &ast::Path<'_>) -> Result<Type> {
- Ok(ctx.lookup_var(path).ok_or(TypeError)?.inferred_type.clone())
+ Ok(ctx
+ .lookup_var(path)
+ .or(Err(TypeError))?
+ .inferred_type
+ .clone())
}
fn check_string_piece(
diff --git a/crates/rebel-lang/src/value.rs b/crates/rebel-lang/src/value.rs
index 0780377..f7bffbb 100644
--- a/crates/rebel-lang/src/value.rs
+++ b/crates/rebel-lang/src/value.rs
@@ -246,6 +246,7 @@ impl Value {
fn eval_path(ctx: &Context, path: &ast::Path<'_>) -> Result<Value> {
ctx.lookup_var(path)
+ .ok()
.and_then(|var| var.value.clone())
.ok_or(EvalError)
}