Wip stacker and drop impl

This commit is contained in:
LunaAmora 2024-02-28 15:00:48 -03:00
parent 0b98642d96
commit 6263b642bb
18 changed files with 628 additions and 549 deletions

1
Cargo.lock generated
View File

@ -221,6 +221,7 @@ dependencies = [
"interner",
"itertools",
"logos",
"stacker",
"stdext",
"walkdir",
]

View File

@ -29,6 +29,7 @@ indexmap = "2.2.3"
interner = "0.2.1"
itertools = "0.11.0"
logos = "0.14.0"
stacker = "0.1"
[dev-dependencies]
insta = "1.34.0"

5
aircraft.hvm2 Normal file

File diff suppressed because one or more lines are too long

4
gen.hvm Normal file
View File

@ -0,0 +1,4 @@
MakeLongStr 0 acc = acc
MakeLongStr 1+p acc = (String.cons '*' (MakeLongStr p acc))
main = (MakeLongStr 16339 String.nil)

1
huge_str.hvm Normal file

File diff suppressed because one or more lines are too long

View File

@ -80,7 +80,7 @@ pub fn create_host(book: Arc<Book>, labels: Arc<Labels>, compile_opts: CompileOp
term.resugar_builtins();
readback_errors.extend(resugar_errs);
if let Term::Str { val } = term {
if let Term::Str { ref val } = term {
println!("{val}");
}
}

View File

@ -75,6 +75,7 @@ impl Pattern {
impl Term {
pub fn check_ctrs_arities(&self, arities: &HashMap<Name, usize>) -> Result<(), MatchErr> {
stacker::maybe_grow(1024 * 32, 1024 * 1024, move || {
match self {
Term::Mat { args, rules } => {
for arg in args {
@ -116,5 +117,6 @@ impl Term {
| Term::Err => {}
}
Ok(())
})
}
}

View File

@ -33,6 +33,7 @@ impl Definition {
impl Term {
pub fn check_match_arity(&self) -> Result<(), MatchErr> {
stacker::maybe_grow(1024 * 32, 1024 * 1024, move || {
match self {
Term::Mat { args, rules } => {
let expected = args.len();
@ -69,5 +70,6 @@ impl Term {
| Term::Err => {}
}
Ok(())
})
}
}

View File

@ -67,6 +67,7 @@ impl Pattern {
impl Term {
pub fn check_unbound_pats(&self, is_ctr: &impl Fn(&Name) -> bool) -> Result<(), UnboundCtrErr> {
stacker::maybe_grow(1024 * 32, 1024 * 1024, move || {
match self {
Term::Let { pat, val, nxt } => {
pat.check_unbounds(is_ctr)?;
@ -103,5 +104,6 @@ impl Term {
| Term::Err => (),
}
Ok(())
})
}
}

View File

@ -140,6 +140,44 @@ pub enum Term {
Err,
}
impl Drop for Term {
fn drop(&mut self) {
let mut stack = vec![self];
while let Some(term) = stack.pop() {
match term {
Term::Lam { bod, .. } | Term::Chn { bod, .. } => {
stack.push(bod);
}
Term::Let { val: fst, nxt: snd, .. }
| Term::App { fun: fst, arg: snd, .. }
| Term::Tup { fst, snd }
| Term::Dup { val: fst, nxt: snd, .. }
| Term::Sup { fst, snd, .. }
| Term::Opx { fst, snd, .. } => {
stack.push(fst);
stack.push(snd);
}
Term::Mat { args, rules } => {
for arg in args.iter_mut() {
stack.push(arg);
}
for Rule { body, .. } in rules.iter_mut() {
stack.push(body);
}
}
Term::Lst { els } => {
for el in els.iter_mut() {
stack.push(el);
}
}
_ => {}
}
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Pattern {
Var(Option<Name>),

View File

@ -58,6 +58,7 @@ pub struct Reader<'a> {
impl<'a> Reader<'a> {
fn read_term(&mut self, next: Port) -> Term {
stacker::maybe_grow(1024 * 32, 1024 * 1024, move || {
if self.dup_paths.is_none() && !self.seen.insert(next) {
self.error(ReadbackError::Cyclic);
return Term::Var { nam: Name::from("...") };
@ -105,10 +106,12 @@ impl<'a> Reader<'a> {
Term::native_num_match(scrutinee, Term::Era, Term::Era, None)
} else {
let zero_term = self.read_term(self.net.enter_port(Port(sel_node, 1)));
let succ_term = self.read_term(self.net.enter_port(Port(sel_node, 2)));
let mut succ_term = self.read_term(self.net.enter_port(Port(sel_node, 2)));
match succ_term {
Term::Lam { nam, bod, .. } => Term::native_num_match(scrutinee, zero_term, *bod, Some(nam)),
match &mut succ_term {
Term::Lam { nam, bod, .. } => {
Term::native_num_match(scrutinee, zero_term, std::mem::take(bod), Some(nam.take()))
}
_ => {
self.error(ReadbackError::InvalidNumericMatch);
Term::native_num_match(scrutinee, zero_term, succ_term, None)
@ -214,6 +217,7 @@ impl<'a> Reader<'a> {
};
term
})
}
/// Enters both ports 1 and 2 of a node,

View File

@ -64,6 +64,7 @@ impl<'a> EncodeTermState<'a> {
/// `global_vars` has the same information for global lambdas. Must be linked outside this function.
/// Expects variables to be affine, refs to be stored as Refs and all names to be bound.
fn encode_term(&mut self, term: &Term, up: Port) -> Option<Port> {
stacker::maybe_grow(1024 * 32, 1024 * 1024, move || {
match term {
// A lambda becomes to a con node. Ports:
// - 0: points to where the lambda occurs.
@ -247,6 +248,7 @@ impl<'a> EncodeTermState<'a> {
}
Term::Err => unreachable!(),
}
})
}
fn push_scope(&mut self, name: &Option<Name>, decl_port: Port) {

View File

@ -43,7 +43,10 @@ impl Term {
| Term::Err => (),
Term::Let { .. } => {
let Term::Let { pat, mut val, mut nxt } = std::mem::take(self) else { unreachable!() };
let Term::Let { pat, val, nxt } = self else { unreachable!() };
let pat = pat.clone();
let mut val = std::mem::take(val);
let mut nxt = std::mem::take(nxt);
val.desugar_let_destructors();
nxt.desugar_let_destructors();

View File

@ -24,6 +24,7 @@ impl Ctx<'_> {
impl Term {
fn linearize_simple_matches(&mut self, lift_all_vars: bool) -> Result<(), MatchErr> {
stacker::maybe_grow(1024 * 32, 1024 * 1024, move || {
match self {
Term::Mat { args: _, rules } => {
for rule in rules.iter_mut() {
@ -62,6 +63,7 @@ impl Term {
};
Ok(())
})
}
}

View File

@ -62,7 +62,10 @@ fn term_to_affine(term: &mut Term, inst_count: &mut HashMap<Name, u64>) {
if val.has_unscoped() {
term_to_affine(val, inst_count);
let Term::Let { val, nxt, .. } = std::mem::take(term) else { unreachable!() };
let Term::Let { val, nxt, .. } = term else { unreachable!() };
let val = std::mem::take(val);
let nxt = std::mem::take(nxt);
*term = Term::Let { pat: Pattern::Var(None), val, nxt };
return;
@ -86,7 +89,8 @@ fn term_to_affine(term: &mut Term, inst_count: &mut HashMap<Name, u64>) {
if val.has_unscoped() {
term_to_affine(val, inst_count);
} else {
let Term::Let { nxt, .. } = std::mem::take(term) else { unreachable!() };
let Term::Let { nxt, .. } = term else { unreachable!() };
let nxt = std::mem::take(nxt);
*term = *nxt;
}
}

View File

@ -49,6 +49,7 @@ impl Term {
main: Option<&Name>,
scope: &mut HashMap<&'a Name, usize>,
) -> Result<(), ReferencedMainErr> {
stacker::maybe_grow(1024 * 32, 1024 * 1024, move || {
match self {
Term::Lam { nam, bod, .. } => {
push_scope(nam.as_ref(), scope);
@ -122,9 +123,12 @@ impl Term {
}
}
Term::Lst { .. } => unreachable!("Should have been desugared already"),
Term::Lnk { .. } | Term::Ref { .. } | Term::Num { .. } | Term::Str { .. } | Term::Era | Term::Err => (),
Term::Lnk { .. } | Term::Ref { .. } | Term::Num { .. } | Term::Str { .. } | Term::Era | Term::Err => {
()
}
}
Ok(())
})
}
}

View File

@ -17,15 +17,13 @@ impl Term {
} => {
head.resugar_strings();
tail.resugar_strings();
let head = std::mem::take(head);
let mut tail = std::mem::take(tail);
if ctr == SCONS
&& let Term::Num { val } = head
&& let Term::Str { val: tail } = tail
{
// If well formed string, add the next character to the string we're building
let head = unsafe { char::from_u32_unchecked(val as u32) }.to_string();
let head = unsafe { char::from_u32_unchecked(*val as u32) }.to_string();
let str = head + &tail;
*self = Term::str(&str);
} else {
@ -33,8 +31,12 @@ impl Term {
// Create `(Cons head Nil)` instead of `(Cons head "")`
if matches!(&tail, Term::Str { val } if val.is_empty()) {
tail = Term::r#ref(SNIL);
*tail = Term::r#ref(SNIL);
}
let head = std::mem::take(head);
let tail = std::mem::take(tail);
*self = Term::call(Term::Ref { nam: ctr.clone() }, [head, tail]);
}
}
@ -88,16 +90,16 @@ impl Term {
head.resugar_lists();
tail.resugar_lists();
let head = std::mem::take(head);
let tail = std::mem::take(tail);
if ctr == LCONS
&& let Term::Lst { els: tail } = tail
{
// If well formed list, cons the next element to the list being formed
let mut els = vec![head];
els.extend(tail);
els.extend(std::mem::take(tail));
*self = Term::Lst { els };
} else {
let tail = std::mem::take(tail);
*self = Term::call(Term::Ref { nam: ctr.clone() }, [head, tail]);
}
}

View File

@ -39,12 +39,13 @@ impl Term {
///
/// See `[simplify_match_expression]` for more information.
pub fn simplify_matches(&mut self, ctrs: &Constructors, adts: &Adts) -> Result<(), MatchErr> {
stacker::maybe_grow(1024 * 32, 1024 * 1024, move || {
match self {
Term::Mat { args, rules } => {
let (new_args, extracted) = extract_args(args);
*self = simplify_match_expression(&new_args, rules, ctrs, adts)?;
*self = bind_extracted_args(extracted, std::mem::take(self));
let term = simplify_match_expression(&new_args, rules, ctrs, adts)?;
*self = bind_extracted_args(extracted, term);
}
Term::Lst { els } => {
@ -71,6 +72,7 @@ impl Term {
Term::Err => unreachable!(),
}
Ok(())
})
}
}