Skip to content

Commit f28321e

Browse files
committed
De-cell, decls bind typevars explicitly
Explicitly bind type variables in declarations
1 parent 1b65ccb commit f28321e

File tree

10 files changed

+175
-190
lines changed

10 files changed

+175
-190
lines changed

crates/sml-core/src/arenas.rs

+30-22
Original file line numberDiff line numberDiff line change
@@ -180,11 +180,7 @@ impl<'a> CoreArena<'a> {
180180
}
181181

182182
pub fn expr_var(&self, var: Symbol, ty: &'a Type<'a>) -> Expr<'a> {
183-
Expr::new(
184-
self.exprs.alloc(ExprKind::Var(Cell::new(var))),
185-
ty,
186-
Span::dummy(),
187-
)
183+
Expr::new(self.exprs.alloc(ExprKind::Var(var)), ty, Span::dummy())
188184
}
189185

190186
/// Create a `let val var_name : (ty1, ty2, ty3) = (s1, ... sN) in expr`
@@ -194,15 +190,17 @@ impl<'a> CoreArena<'a> {
194190
iter: I,
195191
var_name: Symbol,
196192
body: Expr<'a>,
193+
tyvar_rank: usize,
197194
) -> Expr<'a> {
198-
let expr = self.expr_tuple(
199-
iter.into_iter()
200-
.map(|(sym, ty)| (ExprKind::Var(Cell::new(sym)), ty)),
195+
let expr = self.expr_tuple(iter.into_iter().map(|(sym, ty)| (ExprKind::Var(sym), ty)));
196+
let tyvars = expr.ty.ftv_rank(tyvar_rank + 1);
197+
let decl = Decl::Val(
198+
tyvars,
199+
Rule {
200+
pat: self.pat_var(var_name, expr.ty),
201+
expr,
202+
},
201203
);
202-
let decl = Decl::Val(Rule {
203-
pat: self.pat_var(var_name, expr.ty),
204-
expr,
205-
});
206204
Expr::new(
207205
self.exprs.alloc(ExprKind::Let(vec![decl], body)),
208206
body.ty,
@@ -217,12 +215,17 @@ impl<'a> CoreArena<'a> {
217215
iter: I,
218216
var_name: Symbol,
219217
body: Expr<'a>,
218+
tyvar_rank: usize,
220219
) -> Expr<'a> {
221220
let pat = self.pat_tuple(iter.into_iter().map(|(sym, ty)| (PatKind::Var(sym), ty)));
222-
let decl = Decl::Val(Rule {
223-
pat,
224-
expr: self.expr_var(var_name, pat.ty),
225-
});
221+
let tyvars = pat.ty.ftv_rank(tyvar_rank + 1);
222+
let decl = Decl::Val(
223+
tyvars,
224+
Rule {
225+
pat,
226+
expr: self.expr_var(var_name, pat.ty),
227+
},
228+
);
226229
Expr::new(
227230
self.exprs.alloc(ExprKind::Let(vec![decl], body)),
228231
body.ty,
@@ -237,15 +240,21 @@ impl<'a> CoreArena<'a> {
237240
iter: I,
238241
var_name: Symbol,
239242
body: Expr<'a>,
243+
tyvar_rank: usize,
240244
) -> Expr<'a> {
241245
let pat = self.pat_record(
242246
iter.into_iter()
243247
.map(|(field, sym, ty)| (field, PatKind::Var(sym), ty)),
244248
);
245-
let decl = Decl::Val(Rule {
246-
pat,
247-
expr: self.expr_var(var_name, pat.ty),
248-
});
249+
250+
let tyvars = pat.ty.ftv_rank(tyvar_rank + 1);
251+
let decl = Decl::Val(
252+
tyvars,
253+
Rule {
254+
pat,
255+
expr: self.expr_var(var_name, pat.ty),
256+
},
257+
);
249258
Expr::new(
250259
self.exprs.alloc(ExprKind::Let(vec![decl], body)),
251260
body.ty,
@@ -272,8 +281,7 @@ impl<'ar> ExprArena<'ar> {
272281
}
273282

274283
pub fn fresh_var(&self) -> &'ar ExprKind<'ar> {
275-
self.arena
276-
.alloc(ExprKind::Var(Cell::new(self.allocate_id())))
284+
self.arena.alloc(ExprKind::Var(self.allocate_id()))
277285
}
278286

279287
pub fn allocate_id(&self) -> Symbol {

crates/sml-core/src/core_pp.rs

+63-52
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ impl<'a> Print for Expr<'a> {
117117
}
118118
pp.text(")")
119119
}
120-
Var(s) => pp.print(&s.get()),
120+
Var(s) => pp.print(s),
121121
}
122122
}
123123
}
@@ -204,21 +204,55 @@ impl<'a> Type<'a> {
204204
}
205205
}
206206

207+
fn print_tyvars<'b, 'c>(
208+
ids: &[usize],
209+
map: &mut HashMap<usize, String>,
210+
pp: &'b mut PrettyPrinter<'c>,
211+
) -> &'b mut PrettyPrinter<'c> {
212+
match ids.len() {
213+
0 => pp,
214+
1 => {
215+
map.insert(ids[0], "'a".into());
216+
pp.text("'a ")
217+
}
218+
_ => {
219+
for (idx, tyvar) in ids.iter().enumerate() {
220+
let last = ((idx % 26) as u8 + b'a' as u8) as char;
221+
let name = format!(
222+
"'{}",
223+
(0..idx / 26)
224+
.map(|_| 'z')
225+
.chain(std::iter::once(last))
226+
.collect::<String>()
227+
);
228+
pp.text(&name);
229+
map.insert(*tyvar, name);
230+
if idx != ids.len() - 1 {
231+
pp.text(", ");
232+
}
233+
}
234+
pp.text(" ")
235+
}
236+
}
237+
}
238+
207239
impl<'a> Print for Decl<'a> {
208240
fn print<'b, 'c>(&self, pp: &'b mut PrettyPrinter<'c>) -> &'b mut PrettyPrinter<'c> {
241+
let mut map = HashMap::new();
209242
match self {
210-
Decl::Val(Rule { pat, expr }) => pp
211-
.line()
212-
.text("val ")
213-
.print(pat)
214-
.text(": ")
215-
.print(pat.ty)
216-
.text(" = ")
217-
.print(expr),
218-
Decl::Fun(_, binds) => {
243+
Decl::Val(vars, Rule { pat, expr }) => {
244+
pp.line().text("val ");
245+
print_tyvars(&vars, &mut map, pp)
246+
.print(pat)
247+
.text(": ")
248+
.print(pat.ty)
249+
.text(" = ")
250+
.print(expr)
251+
}
252+
Decl::Fun(vars, binds) => {
219253
for (name, lam) in binds {
220-
pp.line()
221-
.text("val ")
254+
pp.line().text("val ");
255+
print_tyvars(&vars, &mut map, pp)
222256
.print(name)
223257
.text(": ")
224258
.print(&Type::Con(
@@ -240,50 +274,27 @@ impl<'a> Print for Decl<'a> {
240274
.text(" of ")
241275
.print(*ty),
242276
Decl::Exn(con, None) => pp.text("exception ").print(&con.name),
243-
Decl::Datatype(dt) => {
244-
let mut map = HashMap::new();
245-
pp.line();
246-
let pp = match dt.tyvars.len() {
247-
0 => pp.text("datatype ").print(&dt.tycon.name),
248-
1 => {
249-
map.insert(dt.tyvars[0], "'a".into());
250-
pp.text("datatype 'a ").print(&dt.tycon.name)
251-
}
252-
_ => {
253-
pp.text("datatype (");
254-
for (idx, tyvar) in dt.tyvars.iter().enumerate() {
255-
let last = ((idx % 26) as u8 + b'a' as u8) as char;
256-
let name = format!(
257-
"'{}",
258-
(0..idx / 26)
259-
.map(|_| 'z')
260-
.chain(std::iter::once(last))
261-
.collect::<String>()
262-
);
263-
pp.text(&name);
264-
map.insert(*tyvar, name);
265-
if idx != dt.tyvars.len() - 1 {
266-
pp.text(", ");
267-
}
268-
}
269-
pp.text(") ").print(&dt.tycon.name)
270-
}
271-
};
272-
pp.text(" = ");
277+
Decl::Datatype(dts) => {
278+
for dt in dts {
279+
pp.line().text("datatype ");
280+
print_tyvars(&dt.tyvars, &mut map, pp)
281+
.print(&dt.tycon.name)
282+
.text(" = ");
273283

274-
for (idx, con) in dt.constructors.iter().enumerate() {
275-
match con {
276-
(con, Some(ty)) => {
277-
pp.print(&con.name).text(" of ");
278-
ty.print_rename(pp, &mut map);
284+
for (idx, con) in dt.constructors.iter().enumerate() {
285+
match con {
286+
(con, Some(ty)) => {
287+
pp.print(&con.name).text(" of ");
288+
ty.print_rename(pp, &mut map);
289+
}
290+
(con, None) => {
291+
pp.print(&con.name);
292+
}
279293
}
280-
(con, None) => {
281-
pp.print(&con.name);
294+
if idx != dt.constructors.len().saturating_sub(1) {
295+
pp.text(" | ");
282296
}
283297
}
284-
if idx != dt.constructors.len().saturating_sub(1) {
285-
pp.text(" | ");
286-
}
287298
}
288299
pp
289300
}

0 commit comments

Comments
 (0)