module VirtualMachine where
open import Syntax
open import Infinite
open import Data.List
open import Data.Nat
open import Data.Star
open import Data.Product
open import Relation.Unary hiding (U)
mutual
data Inst : Set where
push : (n : ℕ) → Inst
throw : Inst
loop : (x : Expr partial) → Inst
add : Inst
pop : Inst
mark : (ops : Code) → Inst
unmark : Inst
set : (i : Status) → Inst
reset : Inst
Code : Set
Code = List Inst
data Item : Set where
nat : (n : ℕ) → Item
han : (ops : Code) → Item
int : (i : Status) → Item
Stack : Set
Stack = List Item
data State : Set where
⟨_,_,_⟩ : (ops : Code) (i : Status) (s : Stack) → State
⟪_,_⟫ : (i : Status) (s : Stack) → State
mutual
data _⟶_ : State → State → Set where
push : ∀ {n ops i s} → ⟨ push n ∷ ops , i , s ⟩ ⟶ ⟨ ops , i , nat n ∷ s ⟩
add : ∀ {ops i m n s} → ⟨ add ∷ ops , i , nat n ∷ nat m ∷ s ⟩ ⟶ ⟨ ops , i , nat (m + n) ∷ s ⟩
pop : ∀ {ops i n s} → ⟨ pop ∷ ops , i , nat n ∷ s ⟩ ⟶ ⟨ ops , i , s ⟩
mark : ∀ {ops' ops i s} → ⟨ mark ops' ∷ ops , i , s ⟩ ⟶ ⟨ ops , i , han ops' ∷ s ⟩
unmark : ∀ {ops i x c s} → ⟨ unmark ∷ ops , i , x ∷ han c ∷ s ⟩ ⟶ ⟨ ops , i , x ∷ s ⟩
set : ∀ {i' ops i s} → ⟨ set i' ∷ ops , i , s ⟩ ⟶ ⟨ ops , i' , int i ∷ s ⟩
reset : ∀ {ops i x i' s} → ⟨ reset ∷ ops , i , x ∷ int i' ∷ s ⟩ ⟶ ⟨ ops , i' , x ∷ s ⟩
loop : ∀ {x ops i s} → ⟨ loop x ∷ ops , i , s ⟩ ⟶ ⟨ comp x (pop ∷ loop x ∷ ops) , i , s ⟩
throw : ∀ {ops i s} → ⟨ throw ∷ ops , i , s ⟩ ⟶ ⟪ i , s ⟫
interrupt : ∀ {op ops s} → ⟨ op ∷ ops , U , s ⟩ ⟶ ⟪ U , s ⟫
nat : ∀ {i n s} → ⟪ i , nat n ∷ s ⟫ ⟶ ⟪ i , s ⟫
int : ∀ {i i' s} → ⟪ i , int i' ∷ s ⟫ ⟶ ⟪ i' , s ⟫
han : ∀ {i ops s} → ⟪ i , han ops ∷ s ⟫ ⟶ ⟨ ops , B , int i ∷ s ⟩
comp : ∀ {t} → Expr t → Code → Code
comp ⌜ nat n ⌝ ops = push n ∷ ops
comp ⌜ throw ⌝ ops = throw ∷ ops
comp (loop x) ops = loop x ∷ ops
comp (x ⊕ y) ops = comp x (comp y (add ∷ ops))
comp (x >> y) ops = comp x (pop ∷ comp y ops)
comp (x catch y) ops = mark (comp y (reset ∷ ops)) ∷ comp x (unmark ∷ ops)
comp (block x) ops = set B ∷ comp x (reset ∷ ops)
comp (unblock x) ops = set U ∷ comp x (reset ∷ ops)
infix 4 _⟶⋆_
_⟶⋆_ : State → State → Set
_⟶⋆_ = Star _⟶_
_⟶∞ : State → Set
_⟶∞ = Infinite _⟶_
start : ∀ {t} → Expr t → Status → State
start e i = ⟨ comp e [] , i , [] ⟩
_↛ : State → Set
s₁ ↛ = ∄ λ s₂ → s₁ ⟶ s₂