Skip to content

Commit

Permalink
fix(sol-hir-lowering): fix term file
Browse files Browse the repository at this point in the history
  • Loading branch information
aripiprazole committed May 29, 2024
1 parent c529839 commit 8f0e769
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 101 deletions.
205 changes: 105 additions & 100 deletions sol-hir-lowering/src/term.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
//!
//! It's only a module, to organization purposes.
use sol_diagnostic::{message, Diagnostics, ErrorId, Report};
use sol_diagnostic::report_error;
use sol_hir::{
solver::{HirDiagnostic, HirLevel},
errors::{HirError, HirErrorKind},
solver::HirLevel,
source::{
expr::{MatchArm, MatchExpr, MatchKind},
expr::{MatchArm, MatchExpr, MatchKind, Pi, Type},
literal::Literal,
pattern::Pattern,
type_rep::ArrowKind,
HirElement,
},
};
Expand Down Expand Up @@ -69,8 +69,8 @@ impl HirLowering<'_, '_> {
AppExpr(app) => self.app_expr(app, level),

// Type level expressions
PiExpr(pi) => self.pi_expr(pi).downgrade(self.db),
SigmaExpr(sigma) => self.sigma_expr(sigma).downgrade(self.db),
PiExpr(pi) => self.pi_expr(pi).downgrade(),
SigmaExpr(sigma) => self.sigma_expr(sigma).downgrade(),
}
}

Expand All @@ -87,7 +87,11 @@ impl HirLowering<'_, '_> {
.solve(self, |this, expr| this.type_expr(expr));
let location = self.range(tree.range());

Expr::Ann(AnnExpr::new(self.db, value, type_rep, location))
Expr::Ann(AnnExpr {
value: Box::new(value),
type_rep,
location,
})
}

/// Resolves a binary expression.
Expand Down Expand Up @@ -120,14 +124,13 @@ impl HirLowering<'_, '_> {

let reference = self.scope.using(self.db, op, location.clone());

Expr::Call(CallExpr::new(
self.db,
/* kind = */ CallKind::Infix,
/* callee = */ Callee::Reference(reference),
/* arguments = */ vec![lhs, rhs],
/* do_notation = */ None,
/* location = */ location,
))
Expr::Call(CallExpr {
kind: CallKind::Infix,
callee: Callee::Reference(reference),
arguments: vec![lhs, rhs],
do_notation: None,
location,
})
}

/// Resolves a lambda expression.
Expand All @@ -151,7 +154,12 @@ impl HirLowering<'_, '_> {

let scope = self.pop_scope();

Expr::Lam(LamExpr::new(self.db, parameters, value, location, scope))
Expr::Lam(LamExpr {
parameters,
value: Box::new(value),
location,
scope,
})
}

/// Resolves a call expression.
Expand Down Expand Up @@ -180,14 +188,13 @@ impl HirLowering<'_, '_> {

let location = self.range(tree.range());

Expr::Call(CallExpr::new(
self.db,
/* kind = */ CallKind::Infix,
/* callee = */ Callee::Expr(callee.into()),
/* arguments = */ arguments,
/* do_notation = */ do_notation,
/* location = */ location,
))
Expr::Call(CallExpr {
kind: CallKind::Infix,
callee: Callee::Expr(callee.into()),
arguments,
do_notation,
location,
})
}

/// Resolves a type level application expression.
Expand All @@ -208,7 +215,15 @@ impl HirLowering<'_, '_> {

let location = self.range(tree.range());

TypeRep::App(AppTypeRep::new(self.db, callee, arguments, location))
TypeRep {
expr: Box::new(Expr::Call(CallExpr {
kind: CallKind::Prefix,
callee: Callee::Expr(callee.downgrade().into()),
do_notation: None,
arguments: arguments.into_iter().map(|expr| expr.downgrade()).collect(),
location,
})),
}
}

/// Resolves a pi type expression.
Expand Down Expand Up @@ -249,17 +264,15 @@ impl HirLowering<'_, '_> {
});

let value = tree.value().solve(self, |this, expr| this.type_expr(expr));

let scope = self.pop_scope();

TypeRep::Pi(PiTypeRep::new(
self.db,
/* kind = */ ArrowKind::Fun,
/* parameters = */ parameters,
/* value = */ value,
/* location = */ self.range(tree.range()),
/* scope = */ scope,
))
let _ = self.pop_scope();

TypeRep {
expr: Box::new(Expr::Pi(Pi {
parameters,
value: Box::new(value),
location: self.range(tree.range()),
})),
}
}

/// Resolves a sigma type expression.
Expand Down Expand Up @@ -292,7 +305,9 @@ impl HirLowering<'_, '_> {
self::Parameter::new(
self.db,
/* binding = */ pattern,
/* type_rep = */ TypeRep::Hole,
/* type_rep = */ TypeRep {
expr: Box::new(Expr::Hole(location.clone())),
},
/* is_implicit = */ true,
/* rigid = */ false,
/* level = */ HirLevel::Type,
Expand All @@ -304,17 +319,15 @@ impl HirLowering<'_, '_> {
.collect::<Vec<_>>();

let value = tree.value().solve(self, |this, expr| this.type_expr(expr));

let scope = self.pop_scope();

TypeRep::Pi(PiTypeRep::new(
self.db,
/* kind = */ ArrowKind::Sigma,
/* parameters = */ parameters,
/* value = */ value,
/* location = */ self.range(tree.range()),
/* scope = */ scope,
))
let _ = self.pop_scope();

TypeRep {
expr: Box::new(Expr::Sigma(Pi {
parameters,
value: Box::new(value),
location: self.range(tree.range()),
})),
}
}

/// Resolves a match expression.
Expand Down Expand Up @@ -350,13 +363,12 @@ impl HirLowering<'_, '_> {
})
.collect();

Expr::Match(MatchExpr::new(
self.db,
/* kind = */ MatchKind::Match,
/* scrutinee = */ scrutinee,
/* clauses = */ clauses,
/* location = */ location,
))
Expr::Match(MatchExpr {
kind: MatchKind::Match,
scrutinee: Box::new(scrutinee),
clauses,
location,
})
}

/// Resolves a if expression.
Expand Down Expand Up @@ -401,13 +413,12 @@ impl HirLowering<'_, '_> {

let location = self.range(tree.range());

Expr::Match(MatchExpr::new(
self.db,
/* kind = */ MatchKind::If,
/* scrutinee = */ scrutinee,
/* clauses = */ clauses,
/* location = */ location,
))
Expr::Match(MatchExpr {
kind: MatchKind::If,
scrutinee: Box::new(scrutinee),
clauses,
location,
})
}

/// Resolves an array expression.
Expand All @@ -422,14 +433,13 @@ impl HirLowering<'_, '_> {
.map(|item| item.solve(self, |this, node| this.expr(node, level)))
.collect::<Vec<_>>();

Expr::Call(CallExpr::new(
self.db,
/* kind = */ CallKind::Prefix,
/* callee = */ Callee::Array,
/* arguments = */ items,
/* do_notation = */ None,
/* location = */ location,
))
Expr::Call(CallExpr {
kind: CallKind::Prefix,
callee: Callee::Array,
arguments: items,
do_notation: None,
location,
})
}

/// Resolves a tuple expression.
Expand All @@ -439,58 +449,53 @@ impl HirLowering<'_, '_> {
pub fn tuple_expr(&mut self, tree: sol_syntax::TupleExpr, level: HirLevel) -> Expr {
let location = self.range(tree.range());

let items = tree
let arguments = tree
.children(&mut tree.walk())
.map(|item| item.solve(self, |this, node| this.expr(node, level)))
.collect::<Vec<_>>();

Expr::Call(CallExpr::new(
self.db,
/* kind = */ CallKind::Prefix,
/* callee = */ Callee::Tuple,
/* arguments = */ items,
/* do_notation = */ None,
/* location = */ location,
))
Expr::Call(CallExpr {
kind: CallKind::Prefix,
callee: Callee::Tuple,
arguments,
do_notation: None,
location,
})
}

/// Resolves a return expression.
///
/// It does translate the syntax return expression
/// into a high-level return expression.
pub fn return_expr(&mut self, tree: sol_syntax::ReturnExpr, level: HirLevel) -> Expr {
let location = self.range(tree.range());

// Reports errors, because "return expression" is equivalent
// to pure expression, and it's only allowed inside do notation.
//
// Or in other words, it's only allowed inside a do notation scope.
if !self.scope.is_do_notation_scope() {
Diagnostics::push(
self.db,
Report::new(HirDiagnostic {
id: ErrorId("escaping-return"),
message: message!["return expression is only allowed inside do notation"],
location: self.range(tree.range()),
}),
)
report_error(self.db, HirError {
label: location.as_source_span(),
source_code: location,
kind: HirErrorKind::ReturnOutsideDoNotation,
})
}

let location = self.range(tree.range());

// If it's a return expression, it will return the value of the expression, otherwise it
// will return a default value.
let value = tree
.value()
.map(|node| node.solve(self, |this, node| this.expr(node, level)))
.unwrap_or_else(|| Expr::call_unit_expr(location.clone(), self.db));

Expr::Call(CallExpr::new(
self.db,
/* kind = */ CallKind::Prefix,
/* callee = */ Callee::Pure,
/* arguments = */ vec![value],
/* do_notation = */ None,
/* location = */ location,
))
.unwrap_or_else(|| Expr::call_unit_expr(location.clone()));

Expr::Call(CallExpr {
kind: CallKind::Prefix,
callee: Callee::Pure,
arguments: vec![value],
do_notation: None,
location,
})
}

/// Resolves a primary expression.
Expand Down Expand Up @@ -559,7 +564,7 @@ impl HirLowering<'_, '_> {
// Creates a new [`Expr`] with the [`Definition`] as the callee.
Expr::Path(this.scope.insert_free_variable(this.db, path))
}
UniverseExpr(_) => TypeRep::Type.downgrade(this.db),
UniverseExpr(_) => Expr::Type(Type::Universe, location),
})
}
}
5 changes: 5 additions & 0 deletions sol-hir/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ pub enum HirErrorKind {
/// An error occurred while parsing the source code.
#[error("incorrect kind: {0}")]
IncorrectKind(String),

/// Return outside do notation.
#[error("return outside do notation")]
#[diagnostic(code(solc::hir_return_outside_do_notation), url(docsrs))]
ReturnOutsideDoNotation,
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, thiserror::Error, miette::Diagnostic)]
Expand Down
2 changes: 1 addition & 1 deletion sol-hir/src/source/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ pub enum Type {

#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct Pi {
pub parameters: Vec<pattern::Pattern>,
pub parameters: Vec<declaration::Parameter>,
pub value: Box<type_rep::TypeRep>,
pub location: Location,
}
Expand Down
14 changes: 14 additions & 0 deletions sol-hir/src/source/type_rep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@ pub struct TypeRep {
pub expr: Box<expr::Expr>,
}

impl TypeRep {
pub fn downgrade(&self) -> expr::Expr {
*self.expr.clone()
}
}

impl Default for TypeRep {
fn default() -> Self {
Self {
expr: Box::new(expr::Expr::Empty),
}
}
}

impl HirElement for TypeRep {
fn location(&self, db: &dyn crate::HirDb) -> Location {
self.expr.location(db)
Expand Down

0 comments on commit 8f0e769

Please sign in to comment.