diff --git a/crates/prometeu-compiler/src/analysis/symbols/mod.rs b/crates/prometeu-compiler/src/analysis/symbols/mod.rs index b8c81f75..2a1629fc 100644 --- a/crates/prometeu-compiler/src/analysis/symbols/mod.rs +++ b/crates/prometeu-compiler/src/analysis/symbols/mod.rs @@ -36,7 +36,7 @@ pub struct Symbol { pub decl_span: Span, } -#[derive(Debug, Default, Clone)] +#[derive(Debug, Default, Clone, Serialize, Deserialize)] pub struct SymbolArena { pub symbols: Vec, } diff --git a/crates/prometeu-compiler/src/frontends/pbs/resolve.rs b/crates/prometeu-compiler/src/frontends/pbs/resolve.rs index 62760984..1fb612bf 100644 --- a/crates/prometeu-compiler/src/frontends/pbs/resolve.rs +++ b/crates/prometeu-compiler/src/frontends/pbs/resolve.rs @@ -234,7 +234,7 @@ mod tests { use super::*; use crate::frontends::pbs::ast::{ AstArena, BlockNodeArena, CallNodeArena, ExprStmtNodeArena, FileNodeArena, FnDeclNodeArena, - IdentNodeArena, NodeId, TypeDeclNodeArena, + IdentNodeArena, TypeDeclNodeArena, }; use crate::common::spans::Span; @@ -436,7 +436,7 @@ mod tests { arena.roots.push(file_id); - let (symbols, index, ref_index, node_to_symbol, diagnostics) = build_def_index(&arena, 1, &interner, None); + let (_symbols, index, ref_index, node_to_symbol, diagnostics) = build_def_index(&arena, 1, &interner, None); assert!(diagnostics.is_empty(), "Diagnostics should be empty: {:?}", diagnostics); @@ -499,4 +499,64 @@ mod tests { assert_eq!(diagnostics[0].code, Some("E_RESOLVE_VISIBILITY".to_string())); assert_eq!(diagnostics[0].span, Some(Span::new(0, 50, 62))); } + + #[test] + fn test_determinism() { + let mut arena = AstArena::default(); + let mut interner = NameInterner::new(); + + let target_name = interner.intern("target"); + let target_body = arena.push(NodeKind::Block(BlockNodeArena { stmts: vec![], tail: None }), Span::new(0, 5, 5)); + let target_id = arena.push(NodeKind::FnDecl(FnDeclNodeArena { + vis: Some("pub".to_string()), + name: target_name, + params: vec![], + ret: None, + else_fallback: None, + body: target_body, + }), Span::new(0, 0, 10)); + + let caller_name = interner.intern("caller"); + let ident_id = arena.push(NodeKind::Ident(IdentNodeArena { name: target_name }), Span::new(0, 50, 56)); + let call_id = arena.push(NodeKind::Call(CallNodeArena { callee: ident_id, args: vec![] }), Span::new(0, 50, 58)); + let expr_stmt = arena.push(NodeKind::ExprStmt(ExprStmtNodeArena { expr: call_id }), Span::new(0, 50, 58)); + let body_id = arena.push(NodeKind::Block(BlockNodeArena { stmts: vec![expr_stmt], tail: None }), Span::new(0, 40, 70)); + + let caller_id = arena.push(NodeKind::FnDecl(FnDeclNodeArena { + vis: None, + name: caller_name, + params: vec![], + ret: None, + else_fallback: None, + body: body_id, + }), Span::new(0, 30, 80)); + + let file_id = arena.push(NodeKind::File(FileNodeArena { + imports: vec![], + decls: vec![target_id, caller_id], + }), Span::new(0, 0, 100)); + + arena.roots.push(file_id); + + let run1 = build_def_index(&arena, 1, &interner, None); + let run2 = build_def_index(&arena, 1, &interner, None); + + // runX is (SymbolArena, DefIndex, RefIndex, NodeToSymbol, Vec) + + let json1_symbols = serde_json::to_string(&run1.0).unwrap(); + let json2_symbols = serde_json::to_string(&run2.0).unwrap(); + assert_eq!(json1_symbols, json2_symbols, "SymbolArena should be deterministic"); + + let json1_refs = serde_json::to_string(&run1.2).unwrap(); + let json2_refs = serde_json::to_string(&run2.2).unwrap(); + assert_eq!(json1_refs, json2_refs, "RefIndex should be deterministic"); + + let json1_node_to_symbol = serde_json::to_string(&run1.3).unwrap(); + let json2_node_to_symbol = serde_json::to_string(&run2.3).unwrap(); + assert_eq!(json1_node_to_symbol, json2_node_to_symbol, "NodeToSymbol should be deterministic"); + + let json1_diags = serde_json::to_string(&run1.4).unwrap(); + let json2_diags = serde_json::to_string(&run2.4).unwrap(); + assert_eq!(json1_diags, json2_diags, "Diagnostics should be deterministic"); + } } diff --git a/test-cartridges/canonical/golden/program.pbc b/test-cartridges/canonical/golden/program.pbc index 666448e9..b06b91ca 100644 Binary files a/test-cartridges/canonical/golden/program.pbc and b/test-cartridges/canonical/golden/program.pbc differ diff --git a/test-cartridges/test01/cartridge/program.pbc b/test-cartridges/test01/cartridge/program.pbc index eafefd12..dbb0922a 100644 Binary files a/test-cartridges/test01/cartridge/program.pbc and b/test-cartridges/test01/cartridge/program.pbc differ