mirror of
https://github.com/HigherOrderCO/Bend.git
synced 2024-09-11 11:56:54 +03:00
Wip stacker and drop impl
This commit is contained in:
parent
0b98642d96
commit
6263b642bb
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -221,6 +221,7 @@ dependencies = [
|
||||
"interner",
|
||||
"itertools",
|
||||
"logos",
|
||||
"stacker",
|
||||
"stdext",
|
||||
"walkdir",
|
||||
]
|
||||
|
@ -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
5
aircraft.hvm2
Normal file
File diff suppressed because one or more lines are too long
4
gen.hvm
Normal file
4
gen.hvm
Normal 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
1
huge_str.hvm
Normal file
File diff suppressed because one or more lines are too long
@ -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}");
|
||||
}
|
||||
}
|
||||
|
@ -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(())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -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(())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -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(())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -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>),
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
@ -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(())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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(())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
@ -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(())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user