record update foundations

This commit is contained in:
Folkert 2020-10-03 21:44:25 +02:00
parent c8e5acf142
commit 16ec417324
4 changed files with 71 additions and 1 deletions

View file

@ -1035,6 +1035,8 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
Reset(_) => todo!(), Reset(_) => todo!(),
Reuse { .. } => todo!(), Reuse { .. } => todo!(),
Update { .. } => todo!(),
AccessAtIndex { AccessAtIndex {
index, index,
structure, structure,

View file

@ -337,6 +337,7 @@ impl<'a> BorrowInfState<'a> {
self.own_var(*x); self.own_var(*x);
} }
} }
Update { .. } => todo!(),
FunctionCall { FunctionCall {
call_type, call_type,
args, args,

View file

@ -100,6 +100,13 @@ pub fn occuring_variables_expr(expr: &Expr<'_>, result: &mut MutSet<Symbol>) {
result.insert(*symbol); result.insert(*symbol);
} }
Update {
structure, updates, ..
} => {
result.insert(*structure);
result.extend(updates.iter().map(|r| r.1));
}
FunctionCall { args, .. } => { FunctionCall { args, .. } => {
// NOTE thouth the function name does occur, it is a static constant in the program // NOTE thouth the function name does occur, it is a static constant in the program
// for liveness, it should not be included here. // for liveness, it should not be included here.
@ -456,6 +463,8 @@ impl<'a> Context<'a> {
self.arena.alloc(Stmt::Let(z, v, l, b)) self.arena.alloc(Stmt::Let(z, v, l, b))
} }
Update { .. } => todo!(),
RunLowLevel(op, args) => { RunLowLevel(op, args) => {
let ps = crate::borrow::lowlevel_borrow_signature(self.arena, op); let ps = crate::borrow::lowlevel_borrow_signature(self.arena, op);
let b = self.add_dec_after_lowlevel(args, ps, b, b_live_vars); let b = self.add_dec_after_lowlevel(args, ps, b, b_live_vars);

View file

@ -680,12 +680,18 @@ pub enum Expr<'a> {
arguments: &'a [Symbol], arguments: &'a [Symbol],
}, },
Struct(&'a [Symbol]), Struct(&'a [Symbol]),
AccessAtIndex { AccessAtIndex {
index: u64, index: u64,
field_layouts: &'a [Layout<'a>], field_layouts: &'a [Layout<'a>],
structure: Symbol, structure: Symbol,
wrapped: Wrapped, wrapped: Wrapped,
}, },
Update {
structure: Symbol,
field_layouts: &'a [Layout<'a>],
updates: &'a [(u64, Symbol)],
},
Array { Array {
elem_layout: Layout<'a>, elem_layout: Layout<'a>,
@ -846,6 +852,23 @@ impl<'a> Expr<'a> {
.text(format!("Index {} ", index)) .text(format!("Index {} ", index))
.append(symbol_to_doc(alloc, *structure)), .append(symbol_to_doc(alloc, *structure)),
Update {
structure, updates, ..
} => {
let it = updates.iter().map(|(index, symbol)| {
alloc
.text(format!(".{} => ", index))
.append(symbol_to_doc(alloc, *symbol))
});
alloc
.text("Update ")
.append(symbol_to_doc(alloc, *structure))
.append(alloc.text("{ "))
.append(alloc.intersperse(it, ", "))
.append(alloc.text(" }"))
}
RuntimeErrorFunction(s) => alloc.text(format!("ErrorFunction {}", s)), RuntimeErrorFunction(s) => alloc.text(format!("ErrorFunction {}", s)),
} }
} }
@ -2017,7 +2040,12 @@ pub fn with_hole<'a>(
} }
} }
Update { .. } => todo!("record access/accessor/update"), Update {
record_var, // Variable,
ext_var, // Variable,
symbol, // Symbol,
updates, // SendMap<Lowercase, Field>,
} => todo!("record access/accessor/update"),
Closure { Closure {
function_type, function_type,
@ -2965,6 +2993,36 @@ fn substitute_in_expr<'a>(
}), }),
None => None, None => None,
}, },
Update {
structure,
field_layouts,
updates,
} => {
let mut did_change = false;
let new_updates = Vec::from_iter_in(
updates.iter().map(|(index, s)| match substitute(subs, *s) {
None => (*index, *s),
Some(s) => {
did_change = true;
(*index, s)
}
}),
arena,
);
if did_change {
let updates = new_updates.into_bump_slice();
Some(Update {
structure: *structure,
field_layouts,
updates,
})
} else {
None
}
}
} }
} }