55 lines
1.2 KiB
Text
55 lines
1.2 KiB
Text
structure Loop where
|
|
|
|
@[inline]
|
|
partial def Loop.forIn {β : Type u} {m : Type u → Type v} [Monad m] (loop : Loop) (init : β) (f : Unit → β → m (ForInStep β)) : m β :=
|
|
let rec @[specialize] loop (b : β) : m β := do
|
|
match ← f () b with
|
|
| ForInStep.done b => pure b
|
|
| ForInStep.yield b => loop b
|
|
loop init
|
|
|
|
syntax "repeat " doSeq : doElem
|
|
|
|
macro_rules
|
|
| `(doElem| repeat $seq) => `(doElem| for _ in Loop.mk do $seq)
|
|
|
|
syntax "while " termBeforeDo " do " doSeq : doElem
|
|
|
|
macro_rules
|
|
| `(doElem| while $cond do $seq) =>
|
|
`(doElem| repeat if $cond then $seq else break)
|
|
|
|
def test1 : IO Unit := do
|
|
let mut i := 0
|
|
while i < 10 do
|
|
println! "{i}"
|
|
i := i + 1
|
|
println! "test1 done {i}"
|
|
|
|
#eval test1
|
|
|
|
syntax "repeat " doSeq " until " term : doElem
|
|
|
|
macro_rules
|
|
| `(doElem| repeat $seq until $cond) =>
|
|
`(doElem| repeat do $seq; if $cond then break)
|
|
|
|
def test2 : IO Unit := do
|
|
let mut i := 0
|
|
repeat
|
|
println! "{i}"
|
|
i := i + 1
|
|
until i >= 10
|
|
println! "test2 done {i}"
|
|
|
|
#eval test2
|
|
|
|
def test3 : IO Unit := do
|
|
let mut i := 0
|
|
repeat
|
|
println! "{i}"
|
|
if i > 10 && i % 3 == 0 then break
|
|
i := i + 1
|
|
println! "test3 done {i}"
|
|
|
|
#eval test3
|