Switch Laurel AST to getIonSerializer% format#405
Conversation
Replace the DDM-generated Laurel AST with the new getIonSerializer% format: - Remove Node interface, IonSerializer class, and Laurel builder class - All types now have toIon(IonSystem ion) instead of toIon(IonSerializer) - Multi-constructor inductives serialize as Ion sexps (CtorName arg1 arg2 ...) - Structures serialize as Ion structs with field name keys - Optional<T> replaced with nullable T - BigInteger replaced with long for Int type - Update JavaToLaurelCompiler to construct records directly - Update LaurelDriver to use new toIon(IonSystem) API Closes #404
|
I investigated the CI failures on both Root causeThe CI step runs: This regenerates the Laurel AST Java files from the Strata submodule using Why I can't fix thisThe CI check is designed to ensure the committed Laurel AST files match what the Strata submodule generates. This PR's hand-written AST files are ahead of the Strata submodule — the submodule needs:
The As noted in the PR description: "The Strata submodule has not been updated yet (needs the Lean-side Laurel type definitions and What's needed to unblockThe Strata submodule must be updated first with the Lean Laurel types and a generation command that produces the new format. Then the submodule pointer in this repo can be bumped, and |
You can bump the submodule pointer to the unmerged Strata PR |
|
@keyboardDrummer-bot can you comment on whether the new or old Ion Integration leads to nicer code in this repository. In particular, how do you find the changes in JavaToLaurelCompiler.java ? |
@keyboardDrummer-bot please do |
|
Comparing the old and new Ion integration in The new format is a clear improvement for the compiler code. The main wins:
One tradeoff: The old factory methods provided convenience overloads without Overall, the new format produces cleaner compiler code because it removes the intermediate abstraction layers ( |
- Regenerate all laurel/ files from Strata submodule to match getIonSerializer% output - Add new generated files: Node.java, IonSerializer.java, Laurel.java, OpaqueSpec.java - Update JavaToLaurelCompiler: use .Of constructors, Optional wrappers, BigInteger for Int, OpaqueSpec for ensures - Update LaurelDriver: use IonSerializer.serializeCommand() instead of toIon(IonSystem)
BigInteger.valueOf(-val) silently overflows for Long.MIN_VALUE because -Long.MIN_VALUE == Long.MIN_VALUE in two's complement. This caused the Strata DDM deserializer to reject the serialized num arg (negative value where a Nat was expected). Use BigInteger.valueOf(val).negate() instead, which correctly produces the positive BigInteger.
Methods with a body should be transparent (Body.Transparent), not opaque. The previous code wrapped ensures in OpaqueSpec whenever ensures was non-empty, which caused the Strata backend to treat methods with both ensures and a body as opaque (Body.Opaque), changing verification semantics and causing the SourceContract test to fail.
The Strata backend uses Body.Opaque with both postconditions and a body to verify the body satisfies the postconditions. The previous commit incorrectly restricted OpaqueSpec to bodyless methods, which silently dropped postconditions for methods with bodies (e.g. PostconditionFailure test expected errorCount=1 but got 0).
When Strata exits with a non-zero code or fails to start, the error message was only written to stdout (via outWriter). CI test logs only show stderr, so these errors were invisible. Duplicate the message to stderr so it appears in CI failure logs.
The new Strata submodule defaults to cvc5 as the SMT solver, but CI only has z3 installed. Pass --solver z3 to laurelAnalyzeBinary. Also log Strata errors to stderr for CI visibility.
Closes #404
Summary
Switches the Laurel AST from the DDM-based generator to the new
getIonSerializer%elaborator format from Strata PR #7.Changes
Laurel AST (generated files)
Node.java,IonSerializer.java,Laurel.java(builder class)toIon(IonSystem ion)instead oftoIon(IonSerializer $s)StmtExpr,LaurelType,Command,Procedure,Body,Field,DatatypeConstructor) serialize as Ion sexps:(constructorName arg₁ arg₂ …)Parameter,ReturnType,Composite,ConstrainedType) are now plain records that serialize as Ion structs with field name keysOptional<T>→ nullableT(serialized asion.newNull()when absent)java.math.BigInteger→longfor theIntexpression typeSourceRangekept as a regular record field, serialized as an Ion struct{start: N, stop: N}Backend updates
JavaToLaurelCompiler: Constructs record types directly (e.g.,new StmtExpr.Add(sr, lhs, rhs)) instead of usingLaurel.add(sr, lhs, rhs)static factory methods. Usesnullinstead ofOptional.empty().LaurelDriver: Callscommand.toIon(ion)directly instead of going throughIonSerializer.serializeCommand(node).What's not yet done
getIonDeserializer%integration)Makefilegeneration command will need updating once the Lean types are definedTesting
The Laurel AST files compile cleanly with
javac. Full integration testing requires the Strata submodule update and matching Lean-side changes.