pub struct Ctx<'book> {
pub book: &'book mut Book,
pub info: Diagnostics,
}
Fields§
§book: &'book mut Book
§info: Diagnostics
Implementations§
Source§impl Ctx<'_>
impl Ctx<'_>
Sourcepub fn check_untyped_terms(&mut self) -> Result<(), Diagnostics>
pub fn check_untyped_terms(&mut self) -> Result<(), Diagnostics>
Checks that terms that cannot be typed are only used inside untyped functions.
Source§impl Ctx<'_>
impl Ctx<'_>
pub fn set_entrypoint(&mut self)
Source§impl Ctx<'_>
impl Ctx<'_>
Checks if there are any repeated top level names. Constructors and functions can’t share names and adts can’t share names.
Source§impl Ctx<'_>
impl Ctx<'_>
pub fn type_check(&mut self) -> Result<(), Diagnostics>
Source§impl Ctx<'_>
impl Ctx<'_>
pub fn check_unbound_refs(&mut self) -> Result<(), Diagnostics>
Source§impl Ctx<'_>
impl Ctx<'_>
Sourcepub fn check_unbound_vars(&mut self) -> Result<(), Diagnostics>
pub fn check_unbound_vars(&mut self) -> Result<(), Diagnostics>
Checks that there are no unbound variables in all definitions.
Source§impl Ctx<'_>
impl Ctx<'_>
Sourcepub fn apply_args(&mut self, args: Option<Vec<Term>>) -> Result<(), Diagnostics>
pub fn apply_args(&mut self, args: Option<Vec<Term>>) -> Result<(), Diagnostics>
Applies the arguments to the program being run by applying them to the main function.
Example:
main x1 x2 x3 = (MainBody x1 x2 x3)
Calling with bend run <file> arg1 arg2 arg3
, it becomes:
main = (λx1 λx2 λx3 (MainBody x1 x2 x3) arg1 arg2 arg3)
Source§impl Ctx<'_>
impl Ctx<'_>
pub fn desugar_bend(&mut self) -> Result<(), Diagnostics>
Source§impl Ctx<'_>
impl Ctx<'_>
Sourcepub fn desugar_fold(&mut self) -> Result<(), Diagnostics>
pub fn desugar_fold(&mut self) -> Result<(), Diagnostics>
Desugars fold
expressions into recursive match
es.
foo xs =
...
fold bind = init with x1 x2 {
Type/Ctr1: (Foo bind.rec_fld bind.fld x1 x2 free_var)
Type/Ctr2: (Bar bind.fld x1 x2)
}
Desugars to:
foo xs =
...
(foo__fold0 init x1 x2 free_var)
foo__fold0 = @bind match bind {
Type/Ctr1: (Foo (foo_fold0 bind.rec_fld x1 x2 free_var) bind.fld x1 x2 free_var)
Type/Ctr2: (Bar bind.fld x1 x2)
}
Source§impl Ctx<'_>
impl Ctx<'_>
Sourcepub fn desugar_match_defs(&mut self) -> Result<(), Diagnostics>
pub fn desugar_match_defs(&mut self) -> Result<(), Diagnostics>
Converts equational-style pattern matching function definitions into trees of match terms.
Source§impl Ctx<'_>
impl Ctx<'_>
pub fn desugar_open(&mut self) -> Result<(), Diagnostics>
Source§impl Ctx<'_>
impl Ctx<'_>
Sourcepub fn desugar_with_blocks(&mut self) -> Result<(), Diagnostics>
pub fn desugar_with_blocks(&mut self) -> Result<(), Diagnostics>
Converts ask
terms inside with
blocks into calls to a monadic bind operation.
Source§impl Ctx<'_>
impl Ctx<'_>
Sourcepub fn fix_match_defs(&mut self) -> Result<(), Diagnostics>
pub fn fix_match_defs(&mut self) -> Result<(), Diagnostics>
Makes every pattern matching definition have correct a left-hand side.
Does not check exhaustiveness of rules and type mismatches. (Inter-ctr/type proprieties)
Source§impl Ctx<'_>
impl Ctx<'_>
Sourcepub fn fix_match_terms(&mut self) -> Result<(), Diagnostics>
pub fn fix_match_terms(&mut self) -> Result<(), Diagnostics>
Convert all match and switch expressions to a normalized form.
- For matches, resolve the constructors and create the name of the field variables.
- For switches, the resolution and name bind is already done during parsing.
- Check for redundant arms and non-exhaustive matches.
- Converts the initial bind to an alias on every arm, rebuilding the eliminated constructor
- Since the bind is not needed anywhere else, it’s erased from the term.
Example: For the program
data MyList = (Cons h t) | Nil
match x {
Cons: (A x.h x.t)
Nil: switch %arg = (Foo y) { 0: B; 1: C; _ %arg-2: D }
}
The following AST transformations will be made:
- The binds
x.h
andx.t
will be generated and stored in the match term. - If it was missing one of the match cases, we’d get an error.
- If it included one of the cases more than once (including wildcard patterns), we’d get a warning.
match * = x {
Cons x.h x.t: use x = (Cons x.h x.t); (A x.h x.t)
Nil: use x = Nil;
switch * = (Foo y) {
0: use %arg = 0; B;
1: use %arg = 1; C;
_: use %arg = (+ %arg-2 2); D
}
}
Source§impl Ctx<'_>
impl Ctx<'_>
Sourcepub fn resolve_refs(&mut self) -> Result<(), Diagnostics>
pub fn resolve_refs(&mut self) -> Result<(), Diagnostics>
Decides if names inside a term belong to a Var or to a Ref.
Converts Term::Var(nam)
into Term::Ref(nam)
when the name
refers to a function definition and there is no variable in
scope shadowing that definition.
Precondition: Refs are encoded as vars, Constructors are resolved.
Postcondition: Refs are encoded as refs, with the correct def id.
Source§impl Ctx<'_>
impl Ctx<'_>
Sourcepub fn resolve_type_ctrs(&mut self) -> Result<(), Diagnostics>
pub fn resolve_type_ctrs(&mut self) -> Result<(), Diagnostics>
Resolves type constructors in the book.
Trait Implementations§
Auto Trait Implementations§
impl<'book> Freeze for Ctx<'book>
impl<'book> RefUnwindSafe for Ctx<'book>
impl<'book> Send for Ctx<'book>
impl<'book> Sync for Ctx<'book>
impl<'book> Unpin for Ctx<'book>
impl<'book> !UnwindSafe for Ctx<'book>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more