summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2024-05-01 00:06:46 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2024-05-01 00:06:46 +0200
commit802884a04625b940a45aeb7cbeb504ff2c18a9ff (patch)
tree1b68c243d0e1af3cc1f01641bfa8401540ec5198
parent3d9d7fd594323d04f77c48ddc3ef2c2b6dc580b7 (diff)
downloadrebel-802884a04625b940a45aeb7cbeb504ff2c18a9ff.tar
rebel-802884a04625b940a45aeb7cbeb504ff2c18a9ff.zip
rebel-lang: scope: add helpers for path handling
-rw-r--r--crates/rebel-lang/src/scope.rs39
-rw-r--r--crates/rebel-lang/src/typing.rs17
-rw-r--r--crates/rebel-lang/src/value.rs7
3 files changed, 30 insertions, 33 deletions
diff --git a/crates/rebel-lang/src/scope.rs b/crates/rebel-lang/src/scope.rs
index 64fe505..ccf2064 100644
--- a/crates/rebel-lang/src/scope.rs
+++ b/crates/rebel-lang/src/scope.rs
@@ -42,15 +42,36 @@ impl Default for Context {
}
impl Context {
+ pub fn local_ident<'a>(path: &'a ast::Path) -> Option<ast::Ident<'a>> {
+ let [ident] = path.components[..] else {
+ return None;
+ };
+ Some(ident)
+ }
+
+ pub fn lookup_var(&self, path: &ast::Path) -> Option<&Var> {
+ if path.components == [ast::Ident { name: "_" }] {
+ return None;
+ }
+
+ self.vars.lookup(&path.components)
+ }
+
+ pub fn lookup_type(&self, path: &ast::Path) -> Option<&Type> {
+ if path.components == [ast::Ident { name: "_" }] {
+ return Some(&Type::Free);
+ }
+
+ self.types.lookup(&path.components)
+ }
+
pub fn record_type(&mut self, stmt: &ast::BlockStmt) -> typing::Result<Type> {
match stmt {
ast::BlockStmt::Let { dest, expr } => {
let ast::TypedPat { pat, typ } = dest.as_ref();
let pat::Pat::Path(dest_path) = pat;
- let [dest_ident] = dest_path.components[..] else {
- return Err(TypeError);
- };
+ let dest_ident = Context::local_ident(dest_path).ok_or(TypeError)?;
let explicit_type = if let Some(typ) = typ {
Type::ast_type(self, typ)?
@@ -80,9 +101,7 @@ impl Context {
}
ast::BlockStmt::Assign { dest, expr } => {
let pat::Pat::Path(dest_path) = dest.as_ref();
- let [dest_ident] = dest_path.components[..] else {
- return Err(TypeError);
- };
+ let dest_ident = Context::local_ident(dest_path).ok_or(TypeError)?;
let expr_type = Type::ast_expr_type(self, expr)?;
@@ -114,9 +133,7 @@ impl Context {
let ast::TypedPat { pat, typ } = dest.as_ref();
let pat::Pat::Path(dest_path) = pat;
- let [dest_ident] = dest_path.components[..] else {
- unreachable!("Type error during eval");
- };
+ let dest_ident = Context::local_ident(dest_path).expect("Type error during eval");
let explicit_type = if let Some(typ) = typ {
Type::ast_type(self, typ).expect("Type error during eval")
@@ -152,9 +169,7 @@ impl Context {
}
ast::BlockStmt::Assign { dest, expr } => {
let pat::Pat::Path(dest_path) = dest.as_ref();
- let [dest_ident] = dest_path.components[..] else {
- unreachable!("Type error during eval");
- };
+ let dest_ident = Context::local_ident(dest_path).expect("Type error during eval");
let value = Value::eval(self, expr)?;
let expr_type = value.typ().or(Err(EvalError))?;
diff --git a/crates/rebel-lang/src/typing.rs b/crates/rebel-lang/src/typing.rs
index 5eb781e..3fd0ee2 100644
--- a/crates/rebel-lang/src/typing.rs
+++ b/crates/rebel-lang/src/typing.rs
@@ -90,13 +90,7 @@ impl Type {
}
fn path_type(ctx: &Context, path: &ast::Path<'_>) -> Result<Type> {
- use Type::*;
-
- if path.components == [ast::Ident { name: "_" }] {
- return Ok(Free);
- }
-
- ctx.types.lookup(&path.components).cloned().ok_or(TypeError)
+ ctx.lookup_type(path).cloned().ok_or(TypeError)
}
fn literal_type(ctx: &Context, lit: &typ::Literal<'_>) -> Result<Type> {
@@ -298,14 +292,7 @@ impl Type {
}
fn path_expr_type(ctx: &Context, path: &ast::Path<'_>) -> Result<Type> {
- if path.components == [ast::Ident { name: "_" }] {
- return Err(TypeError);
- }
-
- ctx.vars
- .lookup(&path.components)
- .map(|var| var.inferred_type.clone())
- .ok_or(TypeError)
+ Ok(ctx.lookup_var(path).ok_or(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 ab21d0b..0780377 100644
--- a/crates/rebel-lang/src/value.rs
+++ b/crates/rebel-lang/src/value.rs
@@ -245,12 +245,7 @@ impl Value {
}
fn eval_path(ctx: &Context, path: &ast::Path<'_>) -> Result<Value> {
- if path.components == [ast::Ident { name: "_" }] {
- return Err(EvalError);
- }
-
- ctx.vars
- .lookup(&path.components)
+ ctx.lookup_var(path)
.and_then(|var| var.value.clone())
.ok_or(EvalError)
}