Skip to content

Commit

Permalink
Moved the problem of uncover_get!.
Browse files Browse the repository at this point in the history
We still need to pass whether the lhs of let-bindings are actually mutable.
  • Loading branch information
julia committed Nov 30, 2023
1 parent a2c34f6 commit 1a69267
Showing 1 changed file with 43 additions and 31 deletions.
74 changes: 43 additions & 31 deletions compiler/src/passes/atomize/atomize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::passes::parse::types::Type;
use crate::passes::parse::{Meta, Typed};
use crate::passes::reveal::{DefRevealed, PrgRevealed, RExpr};
use crate::utils::gen_sym::{gen_sym, UniqueSym};
use crate::utils::push_map::PushMap;

impl<'p> PrgRevealed<'p> {
#[must_use]
Expand All @@ -26,17 +27,25 @@ fn atomize_def(def: DefRevealed) -> DefAtomized {
params,
typ,
bdy,
} => DefAtomized::Fn {
sym,
params,
typ,
bdy: atomize_expr(bdy),
},
} => {
let mut scope =
PushMap::from_iter(params.iter().map(|param| (param.sym, param.mutable)));

DefAtomized::Fn {
sym,
params,
typ,
bdy: atomize_expr(bdy, &mut scope),
}
}
DefRevealed::TypeDef { sym, def } => DefAtomized::TypeDef { sym, def },
}
}

fn atomize_expr<'p>(expr: Typed<'p, RExpr<'p>>) -> Typed<'p, AExpr<'p>> {
fn atomize_expr<'p>(
expr: Typed<'p, RExpr<'p>>,
scope: &mut PushMap<UniqueSym<'p>, bool>,
) -> Typed<'p, AExpr<'p>> {
// Keep track of all the priors. These are bindings that should come before evaluating the expression.
let mut priors = Vec::new();

Expand All @@ -54,69 +63,71 @@ fn atomize_expr<'p>(expr: Typed<'p, RExpr<'p>>) -> Typed<'p, AExpr<'p>> {
} => AExpr::BinaryOp {
op,
exprs: [
atomize_atom(*lhs, &mut priors),
atomize_atom(*rhs, &mut priors),
atomize_atom(*lhs, &mut priors, scope),
atomize_atom(*rhs, &mut priors, scope),
],
},
RExpr::UnaryOp { op, expr: arg } => AExpr::UnaryOp {
op,
expr: atomize_atom(*arg, &mut priors),
},
RExpr::Let { sym, bnd, bdy } => AExpr::Let {
sym,
bnd: Box::new(atomize_expr(*bnd)),
bdy: Box::new(atomize_expr(*bdy)),
expr: atomize_atom(*arg, &mut priors, scope),
},
RExpr::Let { sym, bnd, bdy } => {
let bnd = Box::new(atomize_expr(*bnd, scope));
// todo: this is too conservative, not every variable is mutable!
let bdy = Box::new(scope.push(sym, true, |scope| atomize_expr(*bdy, scope)));

AExpr::Let { sym, bnd, bdy }
}
RExpr::If { cnd, thn, els } => AExpr::If {
cnd: Box::new(atomize_expr(*cnd)),
thn: Box::new(atomize_expr(*thn)),
els: Box::new(atomize_expr(*els)),
cnd: Box::new(atomize_expr(*cnd, scope)),
thn: Box::new(atomize_expr(*thn, scope)),
els: Box::new(atomize_expr(*els, scope)),
},
RExpr::Apply { fun, args } => {
let Type::Fn { params, .. } = fun.meta.clone() else {
unreachable!()
};

AExpr::Apply {
fun: atomize_atom(*fun, &mut priors),
fun: atomize_atom(*fun, &mut priors, scope),
args: args
.into_iter()
.map(|arg| atomize_atom(arg, &mut priors))
.map(|arg| atomize_atom(arg, &mut priors, scope))
.zip(params)
.collect(),
}
}
RExpr::FunRef { sym } => AExpr::FunRef { sym },
RExpr::Loop { bdy } => AExpr::Loop {
bdy: Box::new(atomize_expr(*bdy)),
bdy: Box::new(atomize_expr(*bdy, scope)),
},
RExpr::Break { bdy } => AExpr::Break {
bdy: Box::new(atomize_expr(*bdy)),
bdy: Box::new(atomize_expr(*bdy, scope)),
},
RExpr::Seq { stmt, cnt } => AExpr::Seq {
stmt: Box::new(atomize_expr(*stmt)),
cnt: Box::new(atomize_expr(*cnt)),
stmt: Box::new(atomize_expr(*stmt, scope)),
cnt: Box::new(atomize_expr(*cnt, scope)),
},
RExpr::Assign { sym, bnd } => AExpr::Assign {
sym,
bnd: Box::new(atomize_expr(*bnd)),
bnd: Box::new(atomize_expr(*bnd, scope)),
},
RExpr::Continue => AExpr::Continue,
RExpr::Return { bdy } => AExpr::Return {
bdy: Box::new(atomize_expr(*bdy)),
bdy: Box::new(atomize_expr(*bdy, scope)),
},
RExpr::Struct { sym, fields } => AExpr::Struct {
sym,
fields: fields
.into_iter()
.map(|(sym, expr)| {
let field = atomize_atom(expr, &mut priors);
let field = atomize_atom(expr, &mut priors, scope);
(sym, field)
})
.collect(),
},
RExpr::AccessField { strct, field } => AExpr::AccessField {
strct: atomize_atom(*strct, &mut priors),
strct: atomize_atom(*strct, &mut priors, scope),
field,
},
RExpr::Asm { instrs } => AExpr::Asm { instrs },
Expand All @@ -143,14 +154,15 @@ fn atomize_expr<'p>(expr: Typed<'p, RExpr<'p>>) -> Typed<'p, AExpr<'p>> {
fn atomize_atom<'p>(
expr: Typed<'p, RExpr<'p>>,
priors: &mut Vec<(UniqueSym<'p>, Typed<'p, AExpr<'p>>)>,
scope: &mut PushMap<UniqueSym<'p>, bool>,
) -> Atom<'p> {
match expr.inner {
RExpr::Lit { val } => Atom::Val { val },
RExpr::Var { sym} => Atom::Var { sym },
RExpr::Var { sym } if !scope[&sym] => Atom::Var { sym },
_ => {
let tmp = gen_sym("tmp");
priors.push((tmp, atomize_expr(expr)));
priors.push((tmp, atomize_expr(expr, scope)));
Atom::Var { sym: tmp }
}
}
}
}

0 comments on commit 1a69267

Please sign in to comment.