move fresh symbol generation into Env

This commit is contained in:
Folkert 2020-03-12 16:55:45 +01:00
parent de40cf62f3
commit f372e4d108
2 changed files with 103 additions and 10 deletions

View file

@ -104,6 +104,20 @@ struct Env<'a, 'i> {
pub home: ModuleId, pub home: ModuleId,
pub ident_ids: &'i mut IdentIds, pub ident_ids: &'i mut IdentIds,
pub pointer_size: u32, pub pointer_size: u32,
symbol_counter: usize,
}
impl<'a, 'i> Env<'a, 'i> {
pub fn fresh_symbol(&mut self) -> Symbol {
let ident_id = self
.ident_ids
.add(format!("_{}", self.symbol_counter).into());
self.symbol_counter += 1;
self.home.register_debug_idents(&self.ident_ids);
Symbol::new(self.home, ident_id)
}
} }
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
@ -206,6 +220,7 @@ impl<'a> Expr<'a> {
home, home,
ident_ids, ident_ids,
pointer_size, pointer_size,
symbol_counter: 0,
}; };
from_can(&mut env, can_expr, procs, None) from_can(&mut env, can_expr, procs, None)
@ -357,7 +372,7 @@ fn from_can<'a>(
None => { None => {
// an anonymous closure. These will always be specialized already // an anonymous closure. These will always be specialized already
// by the surrounding context // by the surrounding context
let symbol = gen_closure_name(procs, &mut env.ident_ids, env.home); let symbol = env.fresh_symbol();
let opt_proc = specialize_proc_body( let opt_proc = specialize_proc_body(
env, env,
procs, procs,
@ -637,14 +652,6 @@ fn store_pattern<'a>(
} }
} }
fn gen_closure_name(procs: &Procs<'_>, ident_ids: &mut IdentIds, home: ModuleId) -> Symbol {
let ident_id = ident_ids.add(format!("_{}", procs.len()).into());
home.register_debug_idents(&ident_ids);
Symbol::new(home, ident_id)
}
fn from_can_when<'a>( fn from_can_when<'a>(
env: &mut Env<'a, '_>, env: &mut Env<'a, '_>,
cond_var: Variable, cond_var: Variable,
@ -935,7 +942,7 @@ fn call_by_name<'a>(
)); ));
// generate a symbol for this specialization // generate a symbol for this specialization
gen_closure_name(procs, &mut env.ident_ids, env.home) env.fresh_symbol()
} }
} else { } else {
opt_specialize_body = None; opt_specialize_body = None;

View file

@ -160,6 +160,92 @@ mod test_mono {
) )
} }
#[test]
fn polymorphic_identity() {
compiles_to(
r#"
id = \x -> x
id { x: id 0x4 }
"#,
{
use self::Builtin::*;
use Layout::Builtin;
let home = test_home();
let gen_symbol_3 = Interns::from_index(home, 3);
let gen_symbol_4 = Interns::from_index(home, 4);
CallByName(
gen_symbol_3,
&[(
Struct {
fields: &[(
"x".into(),
CallByName(gen_symbol_4, &[(Int(4), Builtin(Int64))]),
)],
layout: Layout::Struct(&[("x".into(), Builtin(Int64))]),
},
Layout::Struct(&[("x".into(), Builtin(Int64))]),
)],
)
},
)
}
// needs LetRec to be converted to mono
// #[test]
// fn polymorphic_recursive() {
// compiles_to(
// r#"
// f = \x ->
// when x < 10 is
// True -> f (x + 1)
// False -> x
//
// { x: f 0x4, y: f 3.14 }
// "#,
// {
// use self::Builtin::*;
// use Layout::Builtin;
// let home = test_home();
//
// let gen_symbol_3 = Interns::from_index(home, 3);
// let gen_symbol_4 = Interns::from_index(home, 4);
//
// Float(3.4)
//
// },
// )
// }
// needs layout for non-empty tag union
// #[test]
// fn is_nil() {
// let arena = Bump::new();
//
// compiles_to_with_interns(
// r#"
// LinkedList a : [ Cons a (LinkedList a), Nil ]
//
// isNil : LinkedList a -> Bool
// isNil = \list ->
// when list is
// Nil -> True
// Cons _ _ -> False
//
// listInt : LinkedList Int
// listInt = Nil
//
// isNil listInt
// "#,
// |interns| {
// let home = test_home();
// let var_is_nil = interns.symbol(home, "isNil".into());
// },
// );
// }
#[test] #[test]
fn bool_literal() { fn bool_literal() {
let arena = Bump::new(); let arena = Bump::new();