Skip to content

Commit

Permalink
fix: global scope node identifiers
Browse files Browse the repository at this point in the history
  • Loading branch information
ebastien committed Oct 25, 2023
1 parent 48c8606 commit b66f1db
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 6 deletions.
18 changes: 12 additions & 6 deletions oal-compiler/src/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,15 @@ impl<'a> Context<'a> {
.cloned()
}

/// Returns a unique identifier for the given node within the current scope.
fn node_identifier(&self, node: NRef) -> atom::Ident {
let scope_id = self.scopes.last().map_or(0, |(id, _)| *id);
/// Returns a unique identifier for the given node.
///
/// If `scoped` is true, the identifier is unique per evaluation scope.
fn node_identifier(&self, node: NRef, scoped: bool) -> atom::Ident {
let mut hash = Sha256::new();
hash.update(scope_id.to_be_bytes());
if scoped {
let scope_id = self.scopes.last().map_or(0, |(id, _)| *id);
hash.update(scope_id.to_be_bytes());
}
node.digest(&mut hash);
atom::Ident::from(format!("hash-{:x}", hash.finalize()))
}
Expand Down Expand Up @@ -437,7 +441,9 @@ pub fn eval_declaration<'a>(

if ident.is_reference() || decl.node().syntax().core_ref().is_recursive {
if !ident.is_reference() {
ident = ctx.node_identifier(decl.node());
// As declarations only appear at the global scope,
// The identifier does not depend on the scope of evaluation.
ident = ctx.node_identifier(decl.node(), false);
}
// Make sure we evaluate the reference or recursive declaration only once.
let expr = if !ctx.refs.contains_key(&ident) {
Expand Down Expand Up @@ -755,7 +761,7 @@ pub fn eval_recursion<'a>(
rec: syn::Recursion<'a, Core>,
ann: AnnRef,
) -> Result<(Expr<'a>, AnnRef)> {
let ident = ctx.node_identifier(rec.node());
let ident = ctx.node_identifier(rec.node(), true);
let mut scope = HashMap::new();
let recursion = (Expr::Recursion(ident.clone()), AnnRef::default());
scope.insert(rec.binding().ident(), recursion);
Expand Down
14 changes: 14 additions & 0 deletions oal-compiler/src/eval_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,20 @@ fn eval_recursive_content() -> anyhow::Result<()> {
Ok(())
}

#[test]
fn eval_recursive_content_function() -> anyhow::Result<()> {
let s = eval_check(
r#"
let c s = <status=s, headers={ 'Location r }, {}>;
let r = / on get -> c 200;
res r;
"#,
)?;
assert_eq!(s.rels.len(), 1);
assert_eq!(s.refs.len(), 1);
Ok(())
}

#[test]
fn eval_inner_recursive_lambda() -> anyhow::Result<()> {
let s = eval_check(
Expand Down

0 comments on commit b66f1db

Please sign in to comment.