Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
273 commits
Select commit Hold shift + click to select a range
fbe4de5
Move back Boogie examples
keyboardDrummer Dec 15, 2025
e827d76
Remove white line
keyboardDrummer Dec 15, 2025
ff76419
Moved examples
keyboardDrummer Dec 15, 2025
ce236d8
Delete Examples.lean files since they're obsolete
keyboardDrummer Dec 15, 2025
79fbeb9
Remove duplication
keyboardDrummer Dec 15, 2025
b0832e6
Expand test
keyboardDrummer Dec 15, 2025
2de306c
Do not use type and fn feature from DDM
keyboardDrummer Dec 15, 2025
6e90ace
Fix parser
keyboardDrummer Dec 15, 2025
8ff685d
Update translate file
keyboardDrummer Dec 15, 2025
086f6f8
Added some expected errors
keyboardDrummer Dec 15, 2025
0ea1bbb
Fix test
keyboardDrummer Dec 15, 2025
c397cb5
Attempt at translating to Boogie
keyboardDrummer Dec 15, 2025
126885b
Add sequencing of impure expressions
keyboardDrummer Dec 15, 2025
b547baf
Move towards combining test and source file
keyboardDrummer Dec 15, 2025
83c28d6
Improve translator to Boogie
keyboardDrummer Dec 16, 2025
a496a14
Merge remote-tracking branch 'origin/main' into laurelParsing
keyboardDrummer Dec 16, 2025
4ac44c9
Merge branch 'main' into moveExamples
keyboardDrummer Dec 16, 2025
c2164e2
Merge branch 'laurelParsing' into laurelMoreStmtExpr
keyboardDrummer Dec 16, 2025
245f7ad
Fix after merge
keyboardDrummer Dec 16, 2025
4683301
Merge branch 'laurelParsing' into laurelMoreStmtExpr
keyboardDrummer Dec 16, 2025
69e05e4
Update test
keyboardDrummer Dec 16, 2025
95bb904
Fix
keyboardDrummer Dec 16, 2025
1d19b86
Fix oops
keyboardDrummer Dec 16, 2025
0ebc51d
Merge branch 'laurelParsing' into laurelMoreStmtExpr
keyboardDrummer Dec 16, 2025
c44fad1
Fix warning
keyboardDrummer Dec 16, 2025
d0bada5
Fixes
keyboardDrummer Dec 16, 2025
125bf17
Fix warning
keyboardDrummer Dec 16, 2025
fd1374f
Renames
keyboardDrummer Dec 16, 2025
cd77f34
T2_NestedImpureStatements.lean
keyboardDrummer Dec 16, 2025
de4e4a4
Restructure files
keyboardDrummer Dec 16, 2025
110fc87
Improvements
keyboardDrummer Dec 16, 2025
0104e5a
Updates
keyboardDrummer Dec 16, 2025
a7562b5
Updates to the grammar
keyboardDrummer Dec 16, 2025
d530725
Updates
keyboardDrummer Dec 16, 2025
d37c57a
Add panics
keyboardDrummer Dec 16, 2025
871b27e
Translate all operators
keyboardDrummer Dec 16, 2025
8ddbaa3
Merge branch 'main' into moveExamples
aqjune-aws Dec 16, 2025
5624f00
Progress with T3
keyboardDrummer Dec 17, 2025
02c5cdd
Merge remote-tracking branch 'origin/main' into moveExamples
keyboardDrummer Dec 17, 2025
9efa44a
Undo bad changes
keyboardDrummer Dec 17, 2025
853aa4d
Merge branch 'laurelParsing' into laurelMoreStmtExpr
keyboardDrummer Dec 17, 2025
088816c
Merge branch 'moveExamples' into laurelMoreStmtExpr
keyboardDrummer Dec 17, 2025
f0454dd
T3 passes now
keyboardDrummer Dec 17, 2025
b70f84d
Added failing assertion
keyboardDrummer Dec 17, 2025
6b0c417
Add breaking comment
keyboardDrummer Dec 18, 2025
67f4b31
Test update
keyboardDrummer Dec 18, 2025
333fc61
Test passes now
keyboardDrummer Dec 18, 2025
eae1536
Merge branch 'main' into laurelParsing
keyboardDrummer Dec 18, 2025
7e16741
Merge remote-tracking branch 'origin/main' into laurelParsing
keyboardDrummer Dec 18, 2025
f711bdc
Merge branch 'laurelParsing' of github.com:keyboardDrummer/Strata int…
keyboardDrummer Dec 18, 2025
fbb9a07
Merge branch 'laurelParsing' into laurelMoreStmtExpr
keyboardDrummer Dec 18, 2025
0d964e3
Add missing file
keyboardDrummer Dec 18, 2025
b3c66a3
Fix
keyboardDrummer Dec 18, 2025
f75ed44
Improve testing output and fix some issues
keyboardDrummer Dec 18, 2025
c6c8d5c
Use dbg_trace instead of IO
keyboardDrummer Dec 18, 2025
f878398
Cleanup
keyboardDrummer Dec 18, 2025
f80e775
Rename
keyboardDrummer Dec 18, 2025
b7f4f86
Fix TestGrammar file
keyboardDrummer Dec 18, 2025
78b8c88
Refactoring
keyboardDrummer Dec 18, 2025
f24afe5
Cleanup
keyboardDrummer Dec 18, 2025
3283f93
Improvements to output parameters
keyboardDrummer Dec 18, 2025
b423c9e
Cleanup
keyboardDrummer Dec 18, 2025
4cec349
Rename file
keyboardDrummer Dec 19, 2025
c32a3d5
Move file
keyboardDrummer Dec 19, 2025
44c4082
Merge remote-tracking branch 'origin/main' into laurelParsing
keyboardDrummer Dec 19, 2025
d803b56
Fixes
keyboardDrummer Dec 19, 2025
613fec6
feat(DDM): Java code generator for dialects
fabiomadge Dec 23, 2025
e18f450
Merge remote-tracking branch 'origin/main' into feat/java-codegen
fabiomadge Dec 23, 2025
f99ea87
docs: update module docstring to mention builders
fabiomadge Dec 23, 2025
780c78e
test: verify deserialized AST structure
fabiomadge Dec 23, 2025
e0b2bb5
chore: remove redundant inline comments
fabiomadge Dec 23, 2025
da67291
refactor: use #load_dialect instead of inline dialect definition
fabiomadge Dec 23, 2025
67c170d
fix: correct test 2 title
fabiomadge Dec 23, 2025
8731075
test: use Simple dialect for compile test, include builders
fabiomadge Dec 23, 2025
98c3a4a
fix: disambiguate builders filename to avoid collisions
fabiomadge Dec 23, 2025
b36929a
refactor: use get! and alter for cleaner lookups
fabiomadge Dec 23, 2025
9856651
Fix TestGrammar
keyboardDrummer Dec 23, 2025
f6dfea9
Merge branch 'main' into laurelParsing
keyboardDrummer Dec 23, 2025
91ad85f
Merge branch 'laurelParsing' into laurelMoreStmtExpr
keyboardDrummer Dec 23, 2025
89d9008
Fixes
keyboardDrummer Dec 23, 2025
1404ab0
fix: escape builder method names for Java reserved words
fabiomadge Dec 23, 2025
f8a9a67
Merge branch 'main' into laurelParsing
shigoel Dec 24, 2025
e05f137
Add tests for what is not supported
keyboardDrummer Dec 24, 2025
1dde070
Code review from previous PR
keyboardDrummer Dec 24, 2025
721c6c0
Merge remote-tracking branch 'fork/laurelParsing' into laurelMoreStmt…
keyboardDrummer Dec 24, 2025
79203e4
Merge commit '23050398e4a9782' into laurelMoreStmtExpr
keyboardDrummer Dec 24, 2025
d0ea8bf
Small refactoring
keyboardDrummer Dec 24, 2025
a40faed
Merge branch 'laurelMoreStmtExpr' into laurelFundamentalsNotSupported
keyboardDrummer Dec 24, 2025
7cf21e0
Improve error reporting when calling solver
keyboardDrummer Dec 24, 2025
4f9e815
refactor: address PR #292 review comments
fabiomadge Dec 24, 2025
be0acbf
Merge remote-tracking branch 'origin/main' into feat/java-codegen
fabiomadge Dec 24, 2025
775600c
fix: support qualified names with dotted identifiers
fabiomadge Dec 24, 2025
22d07ed
Add LaurelGrammar.st file
keyboardDrummer Jan 2, 2026
bf0b2b9
Merge remote-tracking branch 'origin/main' into laurelMoreStmtExpr
keyboardDrummer Jan 5, 2026
53bab9c
Add missing import
keyboardDrummer Jan 5, 2026
cfc4a3a
Add laurelVerify command
keyboardDrummer Jan 5, 2026
b845049
Remove obsolete TestGrammar file
keyboardDrummer Jan 5, 2026
705cfb4
Fixes
keyboardDrummer Jan 5, 2026
28c581c
Fix namespace
keyboardDrummer Jan 5, 2026
b738175
Fix concrete tree converter
keyboardDrummer Jan 5, 2026
9e5a509
Add missing files to run regenerate-testdata.sh, and enable including…
keyboardDrummer Jan 6, 2026
52e1f3f
Added filepaths as well
keyboardDrummer Jan 6, 2026
e2f5f47
Consume list of StrataFiles when consuming Laurel over ion
keyboardDrummer Jan 7, 2026
ac9400b
Remove lineOffsets from StrataFile
keyboardDrummer Jan 7, 2026
8d10e11
Store source code byte offsets in the metadata instead of 2d positions
keyboardDrummer Jan 7, 2026
e2715f1
Fix printed filepath
keyboardDrummer Jan 7, 2026
9e7994d
Fixes
keyboardDrummer Jan 7, 2026
c3aec77
fix: address PR review comments
fabiomadge Jan 7, 2026
a3e9ec9
Merge branch 'main' into feat/java-codegen
fabiomadge Jan 7, 2026
46e0e58
Refactoring
keyboardDrummer Jan 8, 2026
44155c0
Refactoring
keyboardDrummer Jan 8, 2026
7400e34
Cleanup
keyboardDrummer Jan 8, 2026
f0068d6
Merge remote-tracking branch 'fabiomadge/feat/java-codegen' into forJ…
keyboardDrummer Jan 8, 2026
9c06af7
Cleanup
keyboardDrummer Jan 8, 2026
3948293
Cleanup
keyboardDrummer Jan 8, 2026
91058f8
Merge branch 'main' into laurelMoreStmtExpr
keyboardDrummer Jan 8, 2026
1c186a0
Fix errors
keyboardDrummer Jan 8, 2026
4bc6a2b
Remove hack
keyboardDrummer Jan 8, 2026
fbe3a2c
Fixes
keyboardDrummer Jan 8, 2026
e805c57
Merge branch 'laurelMoreStmtExpr' into laurelFundamentalsNotSupported
keyboardDrummer Jan 8, 2026
2a4fdf7
Fix issues
keyboardDrummer Jan 8, 2026
583f7ea
More fixes
keyboardDrummer Jan 8, 2026
c37e396
Fixes
keyboardDrummer Jan 8, 2026
122f63d
Improve error reporting
keyboardDrummer Jan 9, 2026
e8c8a13
Fixes to Strata/Languages/Laurel/LiftExpressionAssignments.lean
keyboardDrummer Jan 9, 2026
8ed03a4
Better error handling around solver process
keyboardDrummer Jan 9, 2026
7abbc3e
Attempt at getting better debug output
keyboardDrummer Jan 9, 2026
c711142
Refactoring
keyboardDrummer Jan 9, 2026
202633a
Refactoring
keyboardDrummer Jan 9, 2026
9451e45
Refactoring
keyboardDrummer Jan 9, 2026
2ff9f17
Refactoring
keyboardDrummer Jan 9, 2026
6197e3c
Turns things around
keyboardDrummer Jan 9, 2026
d4efe5b
Merge branch 'main' into laurelMoreStmtExpr
keyboardDrummer Jan 9, 2026
6a865f0
Fix
keyboardDrummer Jan 9, 2026
c90a7de
Add termination proofs for formatStmtExpr and translateExpr
Jan 9, 2026
98ca32b
Update docs Lean version to 4.26.0
keyboardDrummer Jan 12, 2026
14957b2
Merge remote-tracking branch 'origin/main' into forJVerify
keyboardDrummer Jan 12, 2026
a4d6089
Revert toolchain update
keyboardDrummer Jan 12, 2026
2104a31
Fixes
keyboardDrummer Jan 12, 2026
d19710f
Fixes
keyboardDrummer Jan 12, 2026
f0aa528
Sequence the program using a reversed list for bookkeeping
keyboardDrummer Jan 12, 2026
f282147
Merge branch 'main' into laurelMoreStmtExpr
keyboardDrummer Jan 12, 2026
a84748a
Remove noise
keyboardDrummer Jan 12, 2026
285ffc8
Bump documentation to 4.26.0
joehendrix Jan 12, 2026
5170e51
Merge branch 'laurelMoreStmtExpr' of github.com:keyboardDrummer/Strat…
keyboardDrummer Jan 12, 2026
212226d
Merge branch 'jhx/v4.26.0_docs' into forJVerify
keyboardDrummer Jan 12, 2026
5da0ff4
Merge remote-tracking branch 'origin/main' into forJVerify
keyboardDrummer Jan 13, 2026
e332bad
Fix merge mistakes
keyboardDrummer Jan 13, 2026
5d30ca5
Fixes
keyboardDrummer Jan 13, 2026
d15ab9a
Merge remote-tracking branch 'origin/main' into forJVerify
keyboardDrummer Jan 14, 2026
9d40949
Refactoring
keyboardDrummer Jan 14, 2026
6d7fc13
Merge remote-tracking branch 'origin/main' into forJVerify
keyboardDrummer Jan 14, 2026
a223c5d
Fix merge error
keyboardDrummer Jan 14, 2026
84d86e7
Fix errors
keyboardDrummer Jan 14, 2026
e283b22
Merge branch 'laurelMoreStmtExpr' into laurelFundamentalsNotSupported
keyboardDrummer Jan 14, 2026
fe86098
Merge commit 'da9169e0597~1' into laurelFundamentalsNotSupported
keyboardDrummer Jan 14, 2026
ed227ef
Merge commit 'da9169e0597' into laurelFundamentalsNotSupported
keyboardDrummer Jan 14, 2026
b694fae
Merge remote-tracking branch 'origin/main' into laurelFundamentalsNot…
keyboardDrummer Jan 14, 2026
c5f9687
Merge branch 'forJVerify' into laurelFundamentalsNotSupported
keyboardDrummer Jan 14, 2026
3d358ca
Cleanup
keyboardDrummer Jan 14, 2026
086bf22
Draft work
keyboardDrummer Jan 14, 2026
8da23f6
Cleanup
keyboardDrummer Jan 15, 2026
2797281
Merge remote-tracking branch 'origin/main' into forJVerify
keyboardDrummer Jan 15, 2026
49bac76
Fix failing proof by adding ': h'
keyboardDrummer Jan 15, 2026
4b86292
Fix merge mistakes
keyboardDrummer Jan 15, 2026
e6142e3
Merge branch 'forJVerify' into mutableFields
keyboardDrummer Jan 15, 2026
61b305e
Some updates
keyboardDrummer Jan 15, 2026
0a777e0
Updates
keyboardDrummer Jan 15, 2026
4ab53da
Fix translator
keyboardDrummer Jan 15, 2026
25c36f5
Start
keyboardDrummer Jan 15, 2026
6c964ad
Progress
keyboardDrummer Jan 15, 2026
d539bec
Some changes
keyboardDrummer Jan 15, 2026
e4df61f
Updates
keyboardDrummer Jan 15, 2026
dd16f98
Updates
keyboardDrummer Jan 15, 2026
bafb7d2
Remove repr usage
keyboardDrummer Jan 16, 2026
79ee155
Merge remote-tracking branch 'origin/main' into forJVerify
keyboardDrummer Jan 16, 2026
8e20c05
Fix build error
keyboardDrummer Jan 16, 2026
a5b1e4b
Additional fix
keyboardDrummer Jan 16, 2026
39d7d71
Fix
keyboardDrummer Jan 16, 2026
b6cd5c1
T1_MutableFields passes, although it's partially commented out
keyboardDrummer Jan 16, 2026
f4b1ab9
Merge remote-tracking branch 'origin/main' into mutableFields
keyboardDrummer Jan 16, 2026
ff3bb23
Merge remote-tracking branch 'fork/forJVerify' into mutableFields
keyboardDrummer Jan 16, 2026
da8413c
Merge branch 'main' into forJVerify
keyboardDrummer Jan 16, 2026
3a16928
Merge remote-tracking branch 'fork/forJVerify' into mutableFields
keyboardDrummer Jan 16, 2026
d72523c
Add limited procedure calls test
keyboardDrummer Jan 16, 2026
2812fc0
Improved test
keyboardDrummer Jan 16, 2026
89aa89a
T5_ProcedureCallsBoogie.lean passes now
keyboardDrummer Jan 16, 2026
a9d5c60
Add comment
keyboardDrummer Jan 16, 2026
9022bf6
Merge remote-tracking branch 'origin/main' into forJVerify
keyboardDrummer Jan 17, 2026
c5dad5c
Remove obsolete comment
keyboardDrummer Jan 19, 2026
e76bd6d
Merge remote-tracking branch 'fork/forJVerify' into mutableFields
keyboardDrummer Jan 19, 2026
03a9c58
Use removeIrrelevantAxioms
keyboardDrummer Jan 19, 2026
221ca78
Fixes
keyboardDrummer Jan 19, 2026
3d7fde2
Fix T1_MutableFields
keyboardDrummer Jan 19, 2026
363ef03
Phase 1: Add missing operators to Laurel grammar
fabiomadge Jan 20, 2026
9c24041
Phase 2: Add while loops with invariants
fabiomadge Jan 20, 2026
1f84638
Phase 3: Extend pre/postconditions from single to list
fabiomadge Jan 20, 2026
babc4d5
Phase 3b: Add constrained types with boundary checks
fabiomadge Jan 20, 2026
53c4e80
Phase 3b: Add constraint checks for local variables
fabiomadge Jan 20, 2026
eba55e9
Phase 3b: Add constraint checks for reassignments
fabiomadge Jan 20, 2026
255e547
Phase 3b: Fix Assign with StaticCall to generate call statement
fabiomadge Jan 20, 2026
8c2f6c7
Refactor: Extract helper functions to reduce duplication
fabiomadge Jan 20, 2026
adca6b8
Phase 4: Add quantifiers (forall/exists)
fabiomadge Jan 20, 2026
3c65a1f
Phase 4: Add constraint checks for quantifier bound variables
fabiomadge Jan 20, 2026
3481661
Phase 4: Make translateExpr non-partial with pre-translated constraints
fabiomadge Jan 20, 2026
87cae72
Improve error messages for unsupported constraint expressions
fabiomadge Jan 20, 2026
4ceec58
Refactor: Extract translateBinOp and translateUnaryOp helpers
fabiomadge Jan 20, 2026
e150b27
Phase 5: Arrays - Array type, indexing, length, parameter expansion
fabiomadge Jan 20, 2026
815252f
Phase 6: Sequence operations - Seq.Contains, Seq.Take, Seq.Drop
fabiomadge Jan 20, 2026
83f4601
Refactor: extract isExpressionCall helper to reduce duplication
fabiomadge Jan 20, 2026
ea55c82
Fix isPureExpr for quantifiers and Map type SMT encoding
fabiomadge Jan 20, 2026
6e24372
Add function type annotations to static calls in Laurel to Core trans…
fabiomadge Jan 20, 2026
62afe4d
Improve Laurel grammar formatting and translator error handling
fabiomadge Jan 23, 2026
65c5cc0
Stop silently ignoring internal errors
keyboardDrummer Jan 23, 2026
5abd846
Prevent leaving out metadata from check.
keyboardDrummer Jan 23, 2026
060b694
Move more source locations through the Laurel compilation pipeline
keyboardDrummer Jan 23, 2026
f4dd2ac
More usages of md
keyboardDrummer Jan 23, 2026
fd36fb6
Generate SourceRange overloads for Java factory methods
fabiomadge Jan 23, 2026
f7e24e8
Merge origin/main into jverify-strata-backend
fabiomadge Feb 2, 2026
845fad0
Improve grammar formatting with proper spacing
fabiomadge Feb 2, 2026
e285bab
Fix C_Simp while loop formatting (decreases/invariant spacing)
fabiomadge Feb 2, 2026
4ed8870
Fix C_Simp formatting: proper indentation and NewlineSepBy for blocks
fabiomadge Feb 2, 2026
abf11f9
Fix formatting and Laurel translator bugs
fabiomadge Feb 2, 2026
bb06625
Merge origin/main
fabiomadge Feb 2, 2026
6418a27
Add constrained array element type support in Laurel translator
fabiomadge Feb 3, 2026
bbb18c5
Reorganize Laurel tests, fix insideCondition bug, revert unused Laure…
fabiomadge Feb 4, 2026
73e22b0
Merge origin/main
fabiomadge Feb 4, 2026
f3a902b
Remove accidentally committed file
fabiomadge Feb 4, 2026
526a654
Add missing copyright headers
fabiomadge Feb 4, 2026
533dbe6
Fix array argument expansion in procedure calls
fabiomadge Feb 5, 2026
9512afb
Remove trailing whitespace
fabiomadge Feb 5, 2026
199be91
Merge origin/main
fabiomadge Feb 5, 2026
9e61e38
Improve comment wording
fabiomadge Feb 5, 2026
191ffc4
Improve syntax error message
fabiomadge Feb 5, 2026
f5671ea
Simplify newline separator formatting
fabiomadge Feb 5, 2026
8122075
Fix comment parsing when / is a token
fabiomadge Feb 6, 2026
6793173
Heap parameterization with explicit in/out parameters and multi-targe…
fabiomadge Feb 10, 2026
7517b51
Merge remote-tracking branch 'origin/main' into jverify-strata-backend
fabiomadge Feb 10, 2026
0912973
Fix minor issues found during PR review
fabiomadge Feb 10, 2026
cce0f77
Use Map.ofEntries instead of Map.of for separator maps to avoid 10-en…
fabiomadge Feb 10, 2026
89891a3
Add cutoff to liftBVars for correct shifting under binders; revert un…
fabiomadge Feb 10, 2026
77e8a5c
Remove stale Determinism comment, add trailing newline to grammar, re…
fabiomadge Feb 10, 2026
56f7cca
Make LaurelFormat functions total, revert field access separator to #
fabiomadge Feb 10, 2026
2abee36
Simplify termination proofs in LiftExpressionAssignments
fabiomadge Feb 10, 2026
e2d5da5
Fix <- to ← for consistency
fabiomadge Feb 10, 2026
2dd1519
fix formatting
fabiomadge Feb 10, 2026
f13f1d8
fix formatting
fabiomadge Feb 10, 2026
03d5e48
fix formatting
fabiomadge Feb 10, 2026
be726a0
Make heapTransformExpr total, simplify termination proofs
fabiomadge Feb 10, 2026
0778d16
fix formatting
fabiomadge Feb 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Strata/DDM/AST.lean
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ inductive SepFormat where
| comma -- Comma separator (CommaSepBy)
| space -- Space separator (SpaceSepBy)
| spacePrefix -- Space before each element (SpacePrefixSepBy)
| newline -- Newline separator (NewlineSepBy)
deriving Inhabited, Repr, BEq

namespace SepFormat
Expand All @@ -197,18 +198,21 @@ def toString : SepFormat → String
| .comma => "commaSepBy"
| .space => "spaceSepBy"
| .spacePrefix => "spacePrefixSepBy"
| .newline => "newlineSepBy"

def toIonName : SepFormat → String
| .none => "seq"
| .comma => "commaSepList"
| .space => "spaceSepList"
| .spacePrefix => "spacePrefixedList"
| .newline => "newlineSepList"

def fromIonName? : String → Option SepFormat
| "seq" => some .none
| "commaSepList" => some .comma
| "spaceSepList" => some .space
| "spacePrefixedList" => some .spacePrefix
| "newlineSepList" => some .newline
| _ => none

theorem fromIonName_toIonName_roundtrip (sep : SepFormat) :
Expand Down
3 changes: 3 additions & 0 deletions Strata/DDM/BuiltinDialects/Init.lean
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def SyntaxCat.mkSeq (c:SyntaxCat) : SyntaxCat := { ann := .none, name := q`Init.
def SyntaxCat.mkCommaSepBy (c:SyntaxCat) : SyntaxCat := { ann := .none, name := q`Init.CommaSepBy, args := #[c] }
def SyntaxCat.mkSpaceSepBy (c:SyntaxCat) : SyntaxCat := { ann := .none, name := q`Init.SpaceSepBy, args := #[c] }
def SyntaxCat.mkSpacePrefixSepBy (c:SyntaxCat) : SyntaxCat := { ann := .none, name := q`Init.SpacePrefixSepBy, args := #[c] }
def SyntaxCat.mkNewlineSepBy (c:SyntaxCat) : SyntaxCat := { ann := .none, name := q`Init.NewlineSepBy, args := #[c] }

def initDialect : Dialect := BuiltinM.create! "Init" #[] do
let Ident : ArgDeclKind := .cat <| .atom .none q`Init.Ident
Expand Down Expand Up @@ -56,6 +57,8 @@ def initDialect : Dialect := BuiltinM.create! "Init" #[] do

declareCat q`Init.SpacePrefixSepBy #["a"]

declareCat q`Init.NewlineSepBy #["a"]

let QualifiedIdent := q`Init.QualifiedIdent
declareCat QualifiedIdent
declareOp {
Expand Down
5 changes: 5 additions & 0 deletions Strata/DDM/Elab.lean
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ private partial def runCommand (leanEnv : Lean.Environment) (commands : Array Op
return commands
let (some tree, true) ← runChecked <| elabCommand leanEnv
| return commands
-- Prevent infinite loop if parser makes no progress
let newPos := (←get).pos
if newPos <= iniPos then
logError { start := iniPos, stop := iniPos } "Syntax error: unrecognized syntax or unexpected token"
return commands
let cmd := tree.info.asOp!.op
let dialects := (← read).loader.dialects
modify fun s => { s with
Expand Down
2 changes: 2 additions & 0 deletions Strata/DDM/Elab/Core.lean
Original file line number Diff line number Diff line change
Expand Up @@ -1208,6 +1208,8 @@ partial def catElaborator (c : SyntaxCat) : TypingContext → Syntax → ElabM T
elabSeqWith c .space "spaceSepBy" (·.getSepArgs)
| q`Init.SpacePrefixSepBy =>
elabSeqWith c .spacePrefix "spacePrefixSepBy" (·.getArgs)
| q`Init.NewlineSepBy =>
elabSeqWith c .newline "newlineSepBy" (·.getArgs)
| _ =>
assert! c.args.isEmpty
elabOperation
Expand Down
5 changes: 4 additions & 1 deletion Strata/DDM/Format.lean
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ private def SyntaxDefAtom.formatArgs (opts : FormatOptions) (args : Array PrecFo
match stx with
| .ident lvl prec _ =>
let ⟨r, innerPrec⟩ := args[lvl]!
if prec > 0 ∧ (innerPrec prec ∨ opts.alwaysParen) then
if prec > 0 ∧ (innerPrec < prec ∨ opts.alwaysParen) then
f!"({r})"
else
r
Expand Down Expand Up @@ -399,6 +399,9 @@ private partial def ArgF.mformatM {α} : ArgF α → FormatM PrecFormat
| .spacePrefix =>
.atom <$> entries.foldlM (init := .nil) fun p a =>
return (p ++ " " ++ (← a.mformatM).format)
| .newline =>
.atom <$> entries.foldlM (init := .nil) fun p a =>
return (if p.isEmpty then p else p ++ "\n") ++ (← a.mformatM).format

private partial def ppArgs (f : StrataFormat) (rargs : Array Arg) : FormatM PrecFormat :=
if rargs.isEmpty then
Expand Down
77 changes: 60 additions & 17 deletions Strata/DDM/Integration/Java/Gen.lean
Original file line number Diff line number Diff line change
Expand Up @@ -118,27 +118,38 @@ partial def syntaxCatToJavaType (cat : SyntaxCat) : JavaType :=
else if abstractCategories.contains cat.name then
.simple (abstractJavaName cat.name)
else match cat.name with
| "Init", "Option" =>
| q`Init.Option =>
match cat.args[0]? with
| some inner => .optional (syntaxCatToJavaType inner)
| none => panic! "Init.Option requires a type argument"
| "Init", "Seq" | "Init", "CommaSepBy" =>
| q`Init.Seq | q`Init.CommaSepBy | q`Init.NewlineSepBy | q`Init.SpaceSepBy | q`Init.SpacePrefixSepBy =>
match cat.args[0]? with
| some inner => .list (syntaxCatToJavaType inner)
| none => panic! "Init.Seq/CommaSepBy requires a type argument"
| none => panic! "List category requires a type argument"
| ⟨"Init", _⟩ => panic! s!"Unknown Init category: {cat.name.name}"
| ⟨_, name⟩ => .simple (escapeJavaName (toPascalCase name))

def argDeclKindToJavaType : ArgDeclKind → JavaType
| .type _ => .simple "Expr"
| .cat c => syntaxCatToJavaType c

/-- Get Ion separator name for a list category, or none if not a list. -/
def getSeparator (c : SyntaxCat) : Option String :=
match c.name with
| q`Init.Seq => some "seq"
| q`Init.CommaSepBy => some "commaSepList"
| q`Init.NewlineSepBy => some "newlineSepList"
| q`Init.SpaceSepBy => some "spaceSepList"
| q`Init.SpacePrefixSepBy => some "spacePrefixedList"
| _ => none

/-- Extract the QualifiedIdent for categories that need Java interfaces, or none for primitives. -/
partial def syntaxCatToQualifiedName (cat : SyntaxCat) : Option QualifiedIdent :=
if primitiveCategories.contains cat.name then none
else if abstractCategories.contains cat.name then some cat.name
else match cat.name with
| ⟨"Init", "Option"⟩ | ⟨"Init", "Seq"⟩ | ⟨"Init", "CommaSepBy"⟩ =>
| q`Init.Option | q`Init.Seq | q`Init.CommaSepBy
| q`Init.NewlineSepBy | q`Init.SpaceSepBy | q`Init.SpacePrefixSepBy =>
cat.args[0]?.bind syntaxCatToQualifiedName
| ⟨"Init", _⟩ => none
| qid => some qid
Expand Down Expand Up @@ -179,8 +190,7 @@ structure NameAssignments where
/-! ## Code Generation -/

def argDeclToJavaField (decl : ArgDecl) : JavaField :=
{ name := escapeJavaName decl.ident
type := argDeclKindToJavaType decl.kind }
{ name := escapeJavaName decl.ident, type := argDeclKindToJavaType decl.kind }

def JavaField.toParam (f : JavaField) : String :=
s!"{f.type.toJava} {f.name}"
Expand Down Expand Up @@ -226,8 +236,9 @@ def generateNodeInterface (package : String) (categories : List String) : String
def generateStubInterface (package : String) (name : String) : String × String :=
(s!"{name}.java", s!"package {package};\n\npublic non-sealed interface {name} extends Node \{}\n")
def generateSerializer (package : String) : String :=
def generateSerializer (package : String) (separatorMap : String) : String :=
serializerTemplate.replace templatePackage package
|>.replace "/*SEPARATOR_MAP*/" separatorMap
/-- Assign unique Java names to all generated types -/
def assignAllNames (d : Dialect) : NameAssignments :=
Expand All @@ -241,7 +252,7 @@ def assignAllNames (d : Dialect) : NameAssignments :=
let cats := if cats.contains op.category then cats else cats.push op.category
let refs := op.argDecls.toArray.foldl (init := refs) fun refs arg =>
match arg.kind with
| .type _ => refs.insert ⟨"Init", "Expr"⟩
| .type _ => refs.insert q`Init.Expr
| .cat c => match syntaxCatToQualifiedName c with
| some qid => refs.insert qid
| none => refs
Expand Down Expand Up @@ -308,17 +319,30 @@ def opDeclToJavaRecord (dialectName : String) (names : NameAssignments) (op : Op
fields := op.argDecls.toArray.map argDeclToJavaField }
def generateBuilders (package : String) (dialectName : String) (d : Dialect) (names : NameAssignments) : String :=
let method (op : OpDecl) :=
let methods (op : OpDecl) :=
let fields := op.argDecls.toArray.map argDeclToJavaField
let (ps, as) := fields.foldl (init := (#[], #[])) fun (ps, as) f =>
let (ps, as, checks) := fields.foldl (init := (#[], #[], #[])) fun (ps, as, checks) f =>
match f.type with
| .simple "java.math.BigInteger" _ => (ps.push s!"long {f.name}", as.push s!"java.math.BigInteger.valueOf({f.name})")
| .simple "java.math.BigDecimal" _ => (ps.push s!"double {f.name}", as.push s!"java.math.BigDecimal.valueOf({f.name})")
| t => (ps.push s!"{t.toJava} {f.name}", as.push f.name)
| .simple "java.math.BigInteger" _ =>
(ps.push s!"long {f.name}",
as.push s!"java.math.BigInteger.valueOf({f.name})",
checks.push s!"if ({f.name} < 0) throw new IllegalArgumentException(\"{f.name} must be non-negative\");")
| .simple "java.math.BigDecimal" _ => (ps.push s!"double {f.name}", as.push s!"java.math.BigDecimal.valueOf({f.name})", checks)
| t => (ps.push s!"{t.toJava} {f.name}", as.push f.name, checks)
let methodName := escapeJavaName op.name
s!" public static {names.categories[op.category]!} {methodName}({", ".intercalate ps.toList}) \{ return new {names.operators[(op.category, op.name)]!}(SourceRange.NONE{if as.isEmpty then "" else ", " ++ ", ".intercalate as.toList}); }"
let methods := d.declarations.filterMap fun | .op op => some (method op) | _ => none
s!"package {package};\n\npublic class {dialectName} \{\n{"\n".intercalate methods.toList}\n}\n"
let returnType := names.categories[op.category]!
let recordName := names.operators[(op.category, op.name)]!
let checksStr := if checks.isEmpty then "" else " ".intercalate checks.toList ++ " "
let argsStr := if as.isEmpty then "" else ", " ++ ", ".intercalate as.toList
let paramsStr := ", ".intercalate ps.toList
-- Overload with SourceRange parameter
let srParams := if ps.isEmpty then "SourceRange sourceRange" else s!"SourceRange sourceRange, {paramsStr}"
let withSR := s!" public static {returnType} {methodName}({srParams}) \{ {checksStr}return new {recordName}(sourceRange{argsStr}); }"
-- Convenience overload without SourceRange
let withoutSR := s!" public static {returnType} {methodName}({paramsStr}) \{ {checksStr}return new {recordName}(SourceRange.NONE{argsStr}); }"
s!"{withSR}\n{withoutSR}"
let allMethods := d.declarations.filterMap fun | .op op => some (methods op) | _ => none
s!"package {package};\n\npublic class {dialectName} \{\n{"\n\n".intercalate allMethods.toList}\n}\n"

public def generateDialect (d : Dialect) (package : String) : Except String GeneratedFiles := do
let names := assignAllNames d
Expand Down Expand Up @@ -354,13 +378,32 @@ public def generateDialect (d : Dialect) (package : String) : Except String Gene
sealedInterfaces ++ stubInterfaces
|>.map (·.1.dropEnd 5 |>.toString)

-- Generate separator map for list fields
let separatorEntries := d.declarations.toList.filterMap fun decl =>
match decl with
| .op op =>
let opName := s!"{d.name}.{op.name}"
let fieldEntries := op.argDecls.toArray.toList.filterMap fun arg =>
match arg.kind with
| .cat c => match getSeparator c with
| some sep => some s!"\"{escapeJavaName arg.ident}\", \"{sep}\""
| none => none
| _ => none
if fieldEntries.isEmpty then none
else
let inner := fieldEntries.map fun e => s!"java.util.Map.entry({e})"
some s!" java.util.Map.entry(\"{opName}\", java.util.Map.ofEntries({", ".intercalate inner}))"
| _ => none
let separatorMap := if separatorEntries.isEmpty then "java.util.Map.of()"
else s!"java.util.Map.ofEntries(\n{",\n".intercalate separatorEntries})"

return {
sourceRange := generateSourceRange package
node := generateNodeInterface package allInterfaceNames
interfaces := sealedInterfaces.toArray ++ stubInterfaces.toArray
records := records.toArray
builders := (s!"{names.builders}.java", generateBuilders package names.builders d names)
serializer := generateSerializer package
serializer := generateSerializer package separatorMap
}

/-! ## File Output -/
Expand Down
21 changes: 13 additions & 8 deletions Strata/DDM/Integration/Java/templates/IonSerializer.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
public class IonSerializer {
private final IonSystem ion;

private static final java.util.Map<String, java.util.Map<String, String>> SEPARATORS = /*SEPARATOR_MAP*/;

public IonSerializer(IonSystem ion) {
this.ion = ion;
}
Expand All @@ -22,14 +24,17 @@ public IonValue serialize(Node node) {

private IonSexp serializeNode(Node node) {
IonSexp sexp = ion.newEmptySexp();
sexp.add(ion.newSymbol(node.operationName()));
String opName = node.operationName();
sexp.add(ion.newSymbol(opName));
sexp.add(serializeSourceRange(node.sourceRange()));

var fieldSeps = SEPARATORS.getOrDefault(opName, java.util.Map.of());
for (var component : node.getClass().getRecordComponents()) {
if (component.getName().equals("sourceRange")) continue;
try {
java.lang.Object value = component.getAccessor().invoke(node);
sexp.add(serializeArg(value, component.getType(), component.getGenericType()));
String sep = fieldSeps.get(component.getName());
sexp.add(serializeArg(value, sep, component.getType()));
} catch (java.lang.Exception e) {
throw new java.lang.RuntimeException("Failed to serialize " + component.getName(), e);
}
Expand All @@ -54,7 +59,7 @@ private IonValue serializeSourceRange(SourceRange sr) {
return sexp;
}

private IonValue serializeArg(java.lang.Object value, java.lang.Class<?> type, java.lang.reflect.Type genericType) {
private IonValue serializeArg(java.lang.Object value, String sep, java.lang.Class<?> type) {
if (value == null) {
return serializeOption(java.util.Optional.empty());
}
Expand All @@ -80,7 +85,7 @@ private IonValue serializeArg(java.lang.Object value, java.lang.Class<?> type, j
return serializeOption(opt);
}
if (value instanceof java.util.List<?> list) {
return serializeSeq(list, genericType);
return serializeSeq(list, sep != null ? sep : "seq");
}
throw new java.lang.IllegalArgumentException("Unsupported type: " + type);
}
Expand Down Expand Up @@ -129,17 +134,17 @@ private IonValue serializeOption(java.util.Optional<?> opt) {
sexp.add(ion.newSymbol("option"));
sexp.add(ion.newNull());
if (opt.isPresent()) {
sexp.add(serializeArg(opt.get(), opt.get().getClass(), opt.get().getClass()));
sexp.add(serializeArg(opt.get(), null, opt.get().getClass()));
}
return sexp;
}

private IonValue serializeSeq(java.util.List<?> list, java.lang.reflect.Type genericType) {
private IonValue serializeSeq(java.util.List<?> list, String sepType) {
IonSexp sexp = ion.newEmptySexp();
sexp.add(ion.newSymbol("seq"));
sexp.add(ion.newSymbol(sepType));
sexp.add(ion.newNull());
for (java.lang.Object item : list) {
sexp.add(serializeArg(item, item.getClass(), item.getClass()));
sexp.add(serializeArg(item, null, item.getClass()));
}
return sexp;
}
Expand Down
8 changes: 8 additions & 0 deletions Strata/DDM/Integration/Lean/Gen.lean
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,9 @@ partial def genCatTypeTerm (annType : Ident) (c : SyntaxCat)
| q`Init.SpacePrefixSepBy, 1 =>
let inner := mkCApp ``Array #[args[0]]
return if addAnn then mkCApp ``Ann #[inner, annType] else inner
| q`Init.NewlineSepBy, 1 =>
let inner := mkCApp ``Array #[args[0]]
return if addAnn then mkCApp ``Ann #[inner, annType] else inner
| q`Init.Option, 1 =>
let inner := mkCApp ``Option #[args[0]]
return if addAnn then mkCApp ``Ann #[inner, annType] else inner
Expand Down Expand Up @@ -869,6 +872,8 @@ partial def toAstApplyArg (vn : Name) (cat : SyntaxCat)
toAstApplyArgSeq v cat ``SepFormat.space
| q`Init.SpacePrefixSepBy => do
toAstApplyArgSeq v cat ``SepFormat.spacePrefix
| q`Init.NewlineSepBy => do
toAstApplyArgSeq v cat ``SepFormat.newline
| q`Init.Seq => do
toAstApplyArgSeq v cat ``SepFormat.none
| q`Init.Option => do
Expand Down Expand Up @@ -1101,6 +1106,8 @@ partial def genOfAstArgTerm (varName : String) (cat : SyntaxCat)
genOfAstSeqArgTerm varName cat e ``SepFormat.space
| q`Init.SpacePrefixSepBy => do
genOfAstSeqArgTerm varName cat e ``SepFormat.spacePrefix
| q`Init.NewlineSepBy => do
genOfAstSeqArgTerm varName cat e ``SepFormat.newline
| q`Init.Seq => do
genOfAstSeqArgTerm varName cat e ``SepFormat.none
| q`Init.Option => do
Expand Down Expand Up @@ -1396,6 +1403,7 @@ def tryMakeInhabited (cat : QualifiedIdent) (ops : Array DefaultCtor)
| q`Init.CommaSepBy => true
| q`Init.SpaceSepBy => true
| q`Init.SpacePrefixSepBy => true
| q`Init.NewlineSepBy => true
| q`Init.Option => true
| c => c ∈ inhabited
if !argsInhabited then
Expand Down
1 change: 1 addition & 0 deletions Strata/DDM/Integration/Lean/ToExpr.lean
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ instance : ToExpr SepFormat where
| .comma => mkConst ``SepFormat.comma
| .space => mkConst ``SepFormat.space
| .spacePrefix => mkConst ``SepFormat.spacePrefix
| .newline => mkConst ``SepFormat.newline

end SepFormat

Expand Down
13 changes: 8 additions & 5 deletions Strata/DDM/Parser.lean
Original file line number Diff line number Diff line change
Expand Up @@ -228,16 +228,19 @@ private partial def whitespace : ParserFn := fun c s =>
let curr := c.get j
match curr with
| '/' =>
-- Treat as comment unless a token starting with "//" exists (e.g., //@pre)
match c.tokens.matchPrefix c.inputString i with
| some _ => s
| some tk => if tk.startsWith "//" then s
else andthenFn (takeUntilFn (fun c => c = '\n')) whitespace c (s.next c j)
| none =>
andthenFn (takeUntilFn (fun c => c = '\n')) whitespace c (s.next c j)
| '*' =>
-- Treat as comment unless a token starting with "/*" exists
match c.tokens.matchPrefix c.inputString i with
| some _ => s
| some tk => if tk.startsWith "/*" then s
else andthenFn (finishCommentBlock (pushMissingOnError := false)) whitespace c (s.next c (c.next j))
| none =>
let j := c.next j
andthenFn (finishCommentBlock (pushMissingOnError := false)) whitespace c (s.next c j)
andthenFn (finishCommentBlock (pushMissingOnError := false)) whitespace c (s.next c (c.next j))
| _ =>
s
else s
Expand Down Expand Up @@ -897,7 +900,7 @@ partial def catParser (ctx : ParsingContext) (cat : SyntaxCat) (metadata : Metad
assert! cat.args.size = 1
let isNonempty := q`StrataDDL.nonempty ∈ metadata
commaSepByParserHelper isNonempty <$> catParser ctx cat.args[0]!
| q`Init.SpaceSepBy | q`Init.SpacePrefixSepBy | q`Init.Seq =>
| q`Init.SpaceSepBy | q`Init.SpacePrefixSepBy | q`Init.NewlineSepBy | q`Init.Seq =>
assert! cat.args.size = 1
let isNonempty := q`StrataDDL.nonempty ∈ metadata
(if isNonempty then many1Parser else manyParser) <$> catParser ctx cat.args[0]!
Expand Down
2 changes: 1 addition & 1 deletion Strata/DL/Lambda/LExprEval.lean
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ def eval (n : Nat) (σ : LState TBase) (e : (LExpr TBase.mono))
-- At least one argument in the function call is symbolic.
new_e
| none =>
-- Not a call of a factory function.
-- Not a call of a factory function - go through evalCore
evalCore n' σ e

def evalCore (n' : Nat) (σ : LState TBase) (e : LExpr TBase.mono) : LExpr TBase.mono :=
Expand Down
Loading
Loading