Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
71 changes: 54 additions & 17 deletions Applib/Surface/Program/Syntax.lean
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,68 @@ namespace Applib
open Lean

declare_syntax_cat program
declare_syntax_cat branch_body

syntax withPosition("create " ident ident term) optSemicolon(program) : program
syntax withPosition(ident " := " " create " ident ident term) optSemicolon(program) : program
syntax withPosition("destroy " ident term) optSemicolon(program) : program
syntax withPosition("call " ident term) optSemicolon(program) : program
syntax withPosition("invoke " term) optSemicolon(program) : program
syntax withPosition(ident " := " " invoke " term) optSemicolon(program) : program
syntax withPosition(ident " := " " fetch " term) optSemicolon(program) : program
syntax "return " term : program
syntax "⟪" program "⟫" : term
def matchAltsParser : Parser.Parser :=
Lean.Parser.Term.matchAlts (Lean.Parser.withPosition (Lean.Parser.categoryParser `branch_body 0))

syntax program : branch_body
syntax colGe withPosition("match " term,+ " with " ppLine colGe matchAltsParser) : program
syntax colGe withPosition("match " term,+ " with " ppLine colGe matchAltsParser) optSemicolon(program) : program
syntax colGe withPosition("if " term " then " colGt withPosition(program)) withPosition(" else " colGt withPosition(program)) : program
syntax colGe withPosition("if " term " then " colGt withPosition(program)) withPosition(" else " colGt withPosition(program)) optSemicolon(program) : program
syntax colGe withPosition("if " term " then " colGt withPosition(program)) : program
syntax colGe withPosition("if " term " then " colGt withPosition(program)) optSemicolon(program) : program
syntax colGe "create " ident ident term : program
syntax colGe withPosition("create " ident ident term) optSemicolon(program) : program
syntax colGe withPosition(ident " := " " create " ident ident term) optSemicolon(program) : program
syntax colGe "destroy " ident term : program
syntax colGe withPosition("destroy " ident term) optSemicolon(program) : program
syntax colGe "call " ident term : program
syntax colGe withPosition("call " ident term) optSemicolon(program) : program
syntax colGe "invoke " term : program
syntax colGe withPosition("invoke " term) optSemicolon(program) : program
syntax colGe withPosition(ident " := " " invoke " term) optSemicolon(program) : program
syntax colGe withPosition(ident " := " " fetch " term) optSemicolon(program) : program
syntax colGe "return " term : program
syntax "⟪" withPosition(program) "⟫" : term

macro_rules
| `(⟪create $c:ident $m:ident $e:term ; $p:program⟫) => do
| `(branch_body| $p:program) =>
`(⟪$p⟫)
| `(⟪match $es:term with $alts⟫) =>
`(match $es:term with $alts)
| `(⟪match $es:term with $alts ; $p:program⟫) =>
`(Program.invoke (match $es:term with $alts) (fun _ => ⟪$p⟫))
| `(⟪if $cond:term then $thenProg:program else $elseProg:program⟫) =>
`(if $cond then ⟪$thenProg⟫ else ⟪$elseProg⟫)
| `(⟪if $cond:term then $thenProg:program else $elseProg:program ; $p:program⟫) =>
`(let next := fun _ => ⟪$p⟫; if $cond then Program.invoke ⟪$thenProg⟫ next else Program.invoke ⟪$elseProg⟫ next)
| `(⟪if $cond:term then $thenProg:program⟫) =>
`(if $cond then ⟪$thenProg⟫ else Program.return ())
| `(⟪if $cond:term then $thenProg:program ; $p:program⟫) =>
`(let next := fun () => ⟪$p⟫; if $cond then Program.invoke ⟪$thenProg⟫ next else next ())
| `(⟪create $c:ident $m:ident $e:term⟫) =>
`(Program.create' $c $m $e Program.return)
| `(⟪create $c:ident $m:ident $e:term ; $p:program⟫) =>
`(Program.create' $c $m $e (fun _ => ⟪$p⟫))
| `(⟪$x:ident := create $c:ident $m:ident $e:term ; $p:program⟫) => do
| `(⟪$x:ident := create $c:ident $m:ident $e:term ; $p:program⟫) =>
`(Program.create' $c $m $e (fun $x => ⟪$p⟫))
| `(⟪destroy $m:ident $e:term $args:term ; $p:program⟫) => do
| `(⟪destroy $m:ident $e:term $args:term⟫) =>
`(Program.destroy' $e $m $args (Program.return ()))
| `(⟪destroy $m:ident $e:term $args:term ; $p:program⟫) =>
`(Program.destroy' $e $m $args (⟪$p⟫))
| `(⟪call $m:ident $e:term $args:term ; $p:program⟫) => do
| `(⟪call $m:ident $e:term $args:term⟫) =>
`(Program.call' $e $m $args (Program.return ()))
| `(⟪call $m:ident $e:term $args:term ; $p:program⟫) =>
`(Program.call' $e $m $args (⟪$p⟫))
| `(⟪invoke $e:term ; $p:program⟫) => do
| `(⟪invoke $e:term⟫) =>
`(Program.invoke $e Program.return)
| `(⟪invoke $e:term ; $p:program⟫) =>
`(Program.invoke $e (fun _ => ⟪$p⟫))
| `(⟪$x:ident := invoke $e:term ; $p:program⟫) => do
| `(⟪$x:ident := invoke $e:term ; $p:program⟫) =>
`(Program.invoke $e (fun $x => ⟪$p⟫))
| `(⟪$x:ident := fetch $e:term ; $p:program⟫) => do
| `(⟪$x:ident := fetch $e:term ; $p:program⟫) =>
`(Program.fetch' $e (fun $x => ⟪$p⟫))
| `(⟪return $e:term⟫) => do
| `(⟪return $e:term⟫) =>
`(Program.return $e)
96 changes: 96 additions & 0 deletions Tests/Applib/Surface/Program/Syntax.lean
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,53 @@ def mutualIncrement (rx ry : Reference Counter) (n : Nat) : Program Eco.lab Unit
example (self : TwoCounter) (n : Nat) : Program Eco.lab TwoCounter := ⟪
invoke mutualIncrement self.c1 self.c2 n
invoke mutualIncrement self.c2 self.c1 n
c1 := fetch self.c1
c2 := fetch self.c2
if c1.count > c2.count then
call Counter.Methods.Incr self.c1 (2 : Nat)
else
call Counter.Methods.Incr self.c2 (2 : Nat)
return self

example (self : TwoCounter) (n : Nat) : Program Eco.lab TwoCounter := ⟪
invoke mutualIncrement self.c1 self.c2 n
invoke mutualIncrement self.c2 self.c1 n
c1 := fetch self.c1
c2 := fetch self.c2
if c1.count > c2.count then
call Counter.Methods.Incr self.c1 (2 : Nat)
call Counter.Methods.Incr self.c2 (1 : Nat)
else
call Counter.Methods.Incr self.c2 (2 : Nat)
invoke mutualIncrement self.c2 self.c1 n
invoke mutualIncrement self.c1 self.c1 n
return self

example (self : TwoCounter) (n : Nat) : Program Eco.lab TwoCounter := ⟪
invoke mutualIncrement self.c1 self.c2 n
invoke mutualIncrement self.c2 self.c1 n
c1 := fetch self.c1
c2 := fetch self.c2
if c1.count > c2.count then
call Counter.Methods.Incr self.c1 (2 : Nat)
call Counter.Methods.Incr self.c2 (1 : Nat)
invoke mutualIncrement self.c1 self.c1 n
return self

example (self : TwoCounter) (n : Nat) : Program Eco.lab Counter := ⟪
invoke mutualIncrement self.c1 self.c2 n
invoke mutualIncrement self.c2 self.c1 n
c1 := fetch self.c1
c2 := fetch self.c2
if c1.count > c2.count then
return c1
else
return c2

example : Program Eco.lab (Reference TwoCounter) := ⟪
rx := create Counter Counter.Constructors.Zero ()
ry := create Counter Counter.Constructors.Zero ()
Expand All @@ -45,6 +89,58 @@ example (self : TwoCounter) (n : Nat) : Program Eco.lab TwoCounter := ⟪
return self

example (self : TwoCounter) (n : Nat) : Program Eco.lab Counter := ⟪
invoke mutualIncrement self.c1 self.c2 n
invoke mutualIncrement self.c2 self.c1 n
c1 := fetch self.c1
c2 := fetch self.c2
match c1.count with
| 0 => return c2
| Nat.succ n' =>
if c1.count > c2.count then
invoke mutualIncrement self.c2 self.c1 n'
return c1
else
invoke mutualIncrement self.c1 self.c2 n'
return c2

example (self : TwoCounter) (n : Nat) : Program Eco.lab Unit := ⟪
invoke mutualIncrement self.c1 self.c2 n
invoke mutualIncrement self.c2 self.c1 n
c1 := fetch self.c1
c2 := fetch self.c2
match c1.count with
| 0 => return ()
| Nat.succ n' =>
if c1.count > c2.count then
invoke mutualIncrement self.c2 self.c1 n'
else
invoke mutualIncrement self.c1 self.c2 n'
call Counter.Methods.Incr self.c2 n'
call Counter.Methods.Incr self.c1 n
call Counter.Methods.Incr self.c2 n

example (self : TwoCounter) (n : Nat) : Program Eco.lab Counter := ⟪
invoke mutualIncrement self.c1 self.c2 n
invoke mutualIncrement self.c2 self.c1 n
c1 := fetch self.c1
c2 := fetch self.c2
match c1.count with
| 0 => return c2
| Nat.succ n' =>
if c1.count > c2.count then
invoke mutualIncrement self.c2 self.c1 n'
return c1
else
if c1.count < c2.count then
invoke mutualIncrement self.c1 self.c2 n'
return c2
else
return c1

end TwoCounterApp

namespace OwnedCounter
Expand Down