Implement list resugar

This commit is contained in:
imaqtkatt 2024-01-23 09:57:02 -03:00
parent ebd469a4ae
commit 20558e7fdf
5 changed files with 44 additions and 1 deletions

View File

@ -230,6 +230,14 @@ impl Tag {
pub fn string_scons_head() -> Self {
Self::Named(Name::new("String.SCons.head"))
}
pub fn list() -> Self {
Self::Named(Name::new("List"))
}
pub fn list_lcons_head() -> Self {
Self::Named(Name::new("List.LCons.head"))
}
}
impl Book {

View File

@ -297,6 +297,34 @@ impl<'a> Reader<'a> {
go(term, &mut s, self);
Term::Str { val: s }
}
fn decode_list(&mut self, term: &mut Term) -> Term {
let mut els = Vec::new();
fn go(t: &mut Term, els: &mut Vec<Term>, rd: &mut Reader<'_>) {
match t {
Term::Lam { tag, bod, .. } if *tag == Tag::list() => go(bod, els, rd),
Term::App { tag, arg, .. } if *tag == Tag::list_lcons_head() => {
if let Term::Lam { tag, bod, .. } = &mut **arg {
if *tag == Tag::list() {
els.push(rd.decode_list(bod));
} else {
els.push(*arg.clone());
}
} else {
go(arg, els, rd)
}
}
Term::App { fun, arg, .. } => {
go(fun, els, rd);
go(arg, els, rd);
}
Term::Var { .. } => {}
other => els.push(other.clone()),
}
}
go(term, &mut els, self);
Term::List { els }
}
}
/// Represents `let (fst, snd) = val` if `tag` is `None`, and `dup#tag fst snd = val` otherwise.
@ -492,6 +520,7 @@ impl<'a> Reader<'a> {
fn resugar_adts(&mut self, term: &mut Term) {
match term {
Term::Lam { tag, bod, .. } if *tag == Tag::string() => *term = self.decode_str(bod),
Term::Lam { tag, bod, .. } if *tag == Tag::list() => *term = self.decode_list(bod),
Term::Lam { tag: Tag::Named(adt_name), bod, .. } | Term::Chn { tag: Tag::Named(adt_name), bod, .. } => {
let Some((adt_name, adt)) = self.book.adts.get_key_value(adt_name) else {
return self.resugar_adts(bod);

View File

@ -0,0 +1 @@
Main = (LCons 42 (LCons (LCons @x x LNil) LNil))

View File

@ -0,0 +1,5 @@
---
source: tests/golden_tests.rs
input_file: tests/golden_tests/run_file/list_resugar.hvm
---
[42, [λd d]]

View File

@ -2,4 +2,4 @@
source: tests/golden_tests.rs
input_file: tests/golden_tests/run_file/list_take.hvm
---
(LCons 3 (LCons 2 LNil))
[3, 2]