Skip to content

Commit

Permalink
fix(sol-thir): add debruijin files
Browse files Browse the repository at this point in the history
  • Loading branch information
aripiprazole committed May 12, 2024
1 parent 4cc0c85 commit d591e8a
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 8 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions sol-thir/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ sol-syntax.workspace = true
sol-vfs.workspace = true
salsa-2022.workspace = true
im.workspace = true
thiserror.workspace = true
79 changes: 79 additions & 0 deletions sol-thir/src/debruijin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//! Debruijin indexes and levels. It's used for type checker's efficient indexing
//! and substitution.
use super::*;

/// Defines a debruijin level. It does represent the level of the context/environment
///
/// It can be transformed into a debruijin index by using the [`Level::as_idx`] method.
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Level(pub usize);

#[derive(thiserror::Error, Debug, Clone)]
pub enum Level2IdxError {
/// The level is greater than the index.
#[error("expected l > x")]
LevelGreaterThanIndex,
/// The level is equal to zero.
#[error("expected l > 0")]
LevelEqualToZero,
}

impl Level {
/// Transforms a level into a debruijin index.
pub fn as_idx(&self, Level(l): Level) -> Result<Index, Level2IdxError> {
let Level(x) = *self;
if l > x {
return Err(Level2IdxError::LevelGreaterThanIndex);
}
if l == 0 {
return Err(Level2IdxError::LevelEqualToZero);
}
Ok(Index(0))
}
}

impl std::ops::Add<usize> for Level {
type Output = Self;

fn add(self, rhs: usize) -> Self::Output {
Self(self.0 + rhs)
}
}

impl std::ops::AddAssign<usize> for Level {
fn add_assign(&mut self, rhs: usize) {
self.0 += rhs
}
}

/// Defines a debruijin index. That can be converted by two levels.
///
/// It's used to represent a variable in the syntax tree.
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Index(usize);

impl From<usize> for Index {
fn from(value: usize) -> Self {
Self(value)
}
}

impl std::ops::Add<usize> for Index {
type Output = Self;

fn add(self, rhs: usize) -> Self::Output {
Self(self.0 + rhs)
}
}

impl std::ops::AddAssign<usize> for Index {
fn add_assign(&mut self, rhs: usize) {
self.0 += rhs
}
}

/// Debruijin indices construction, that can be used to get the names of the
/// variables.
#[salsa::accumulator]
pub struct Indices((String, source::Term));
3 changes: 2 additions & 1 deletion sol-thir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use crate::{

extern crate salsa_2022 as salsa;

pub mod debruijin;
pub mod shared;
pub mod source;
pub mod value;
Expand All @@ -50,7 +51,7 @@ pub trait ThirDb:
{
}

impl ThirDb for DB where
impl<DB> ThirDb for DB where
DB: ?Sized
+ ParseDb
+ DiagnosticDb
Expand Down
2 changes: 1 addition & 1 deletion sol-thir/src/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pub type Expr = Box<Term>;

#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub enum Term {
Var(Index, Option<Reference>),
Var(debruijin::Index, Option<Reference>),
Lam(Definition, shared::Implicitness, Expr),
App(Expr, Expr),
Pi(Option<Definition>, shared::Implicitness, Expr, Expr),
Expand Down
8 changes: 2 additions & 6 deletions sol-thir/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ pub struct Pi {
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub enum ValueKind {
U,
Var(Index, Option<Reference>),
Var(debruijin::Index, Option<Reference>),
Constructor(shared::Constructor),
Flexible(Meta, Vec<Value>),
Rigid(Level, Vec<Value>),
Rigid(debruijin::Level, Vec<Value>),
Pi(Pi),
Lam(Definition, shared::Implicitness, Closure),
Location(Location, Box<ValueKind>),
Expand All @@ -46,8 +46,4 @@ impl ValueKind {
pub fn located(location: Location, value: ValueKind) -> ValueKind {
ValueKind::Location(location, Box::new(value))
}

pub fn no() -> ValueKind {
ValueKind::Sorry(Location::CallSite, None)
}
}

0 comments on commit d591e8a

Please sign in to comment.