aboutsummaryrefslogtreecommitdiff
path: root/Smurf.icl
diff options
context:
space:
mode:
Diffstat (limited to 'Smurf.icl')
-rw-r--r--Smurf.icl94
1 files changed, 68 insertions, 26 deletions
diff --git a/Smurf.icl b/Smurf.icl
index 4c7e0c2..7223ce7 100644
--- a/Smurf.icl
+++ b/Smurf.icl
@@ -11,12 +11,19 @@ from Data.Func import $
import Control.Applicative
import Control.Monad
import Data.Maybe
+import Data.List
+from Text import class Text(concat), instance Text String
import GenEq
+import GenPrint
import SmurfParse
derive gEq Stm
+derive gPrint (,)
+
+(<+) infixr 5 :: a b -> String | toString a & toString b
+(<+) a b = toString a +++ toString b
instance == Stm where == a b = a === b
@@ -52,55 +59,67 @@ where
instance zero State where zero = { stack = zero, store = zero }
+instance zero ListIO where zero = {input=[], output=[]}
+
instance toString State
where
- toString {stack, store}
- = "Stack:\n"
- +++ foldl (+++) "" [" " +++ val +++ "\n" \\ val <- stack]
- +++ "Store:\n"
- +++ foldl (+++) "" [" " +++ var +++ " : " +++ val +++ "\n"
- \\ (var, val) <- store]
-
-run :: !Program State *File -> *(Maybe State, *File)
-run prog st io
- # (mbProgSt, io) = step prog st io
+ toString {stack,store} = "(" <+ printToString stack <+ "," <+ printToString store <+ ")"
+
+instance toString Transition
+where
+ toString ((p1, ip1, st1) --> (ip2, op, st2))
+ = "<" <+ simple 2 p1 <+ "," <+ st1 <+ "," <+ printToString ip1 <+ "> -> ("
+ <+ printToString ip2 <+ "," <+ printToString op <+ "," <+ st2 <+ ")"
+ where
+ simple :: !Int !Program -> String
+ simple _ [] = "λ"
+ simple i pgm
+ | i <= length pgm = concat $ intersperse ":" $ map toString pgm
+ = concat $ intersperse ":" $ map toString (take i pgm)
+
+instance toString DerivationTree
+where
+ toString ts = concat $ intersperse "\n" $ map toString $ reverse ts
+
+run :: !Program State io (IO io) -> (Maybe State, io)
+run prog st io iofuncs
+ # (mbProgSt, io) = step prog st io iofuncs
| isNothing mbProgSt = (Nothing, io)
# (prog, st) = fromJust mbProgSt
- = if (isEmpty prog) (Just st, io) (run prog st io)
+ = if (isEmpty prog) (Just st, io) (run prog st io iofuncs)
-step :: !Program State !*File -> *(Maybe (!Program, State), *File)
-step [] st io
+step :: !Program State u:io u:(IO u:io) -> u:(Maybe (!Program, State), u:io)
+step [] st io _
= (pure ([], st), io)
-step [Push s:p] st io
+step [Push s:p] st io _
= (pure (p, { st & stack = push s st.stack }), io)
-step [Input:p] st io
- # (ip, io) = freadline io
- # ip = ip % (0, size ip - 2)
+step [Input:p] st io (IO input _)
+ # (ip, io) = input io
= (pure (p, { st & stack = push ip st.stack }), io)
-step [Output:p] st io
+step [Output:p] st io (IO _ output)
# mbSStk = pop st.stack
| isNothing mbSStk = (empty, io)
# (s, stk) = fromJust mbSStk
- = (pure (p, { st & stack = stk }), io <<< s)
-step [Cat:p] st io
+ = (pure (p, { st & stack = stk }), output s io)
+step [Cat:p] st io _
= (pop st.stack >>= \(x,stk) -> pop stk >>= \(y,stk`) ->
pure (p, { st & stack = push (y +++ x) stk` }), io)
-step [Head:p] st io
+step [Head:p] st io _
= (pop st.stack >>= \(x,stk) -> head x >>= \x` ->
pure (p, { st & stack = push x` stk }), io)
-step [Tail:p] st io
+step [Tail:p] st io _
= (pop st.stack >>= \(x,stk) -> tail x >>= \x` ->
pure (p, { st & stack = push x` stk }), io)
-step [Quotify:p] st io
+step [Quotify:p] st io _
= (pop st.stack >>= \(x,stk) ->
pure (p, { st & stack = push (quotify x) stk }), io)
-step [Put:p] st io
+step [Put:p] st io _
= (pop st.stack >>= \(var,stk) -> pop stk >>= \(val,stk`) ->
pure (p, { st & stack = stk`, store = put var val st.store }), io)
-step [Get:p] st io
+step [Get:p] st io _
= (pop st.stack >>= \(var,stk) ->
pure (p, { st & stack = push (get var st.store) stk }), io)
-step [Exec:p] st io
+step [Exec:p] st io _
= (pop st.stack >>= parse o fromString o fst >>= \p ->
pure (p, zero), io)
@@ -137,3 +156,26 @@ where
quot ['"':cs] = ['\\':'"':quot cs]
quot [c:cs] = [c:quot cs]
+listIO :: IO ListIO
+listIO = IO read write
+where
+ read :: ListIO -> (String, ListIO)
+ read io=:{input} = (hd input, { io & input=tl input })
+
+ write :: String ListIO -> ListIO
+ write s io=:{output} = { io & output=output ++ [s] }
+
+tree :: !Program !State !ListIO (IO ListIO) -> Maybe DerivationTree
+tree pgm st io iof
+ # init = (pgm, io.input, st)
+ # (mbPgmSt, io) = step pgm st io iof
+ | isNothing mbPgmSt = empty
+ # (pgm, st) = fromJust mbPgmSt
+ | isEmpty pgm = pure [ init --> (io.input, io.output, st)
+ , ([],io.input,st) --> (io.input,[],st)
+ ]
+ # mbTree = tree pgm st io iof
+ | isNothing mbTree = empty
+ # tree = fromJust mbTree
+ # [child=:(_ --> final):children] = fromJust mbTree
+ = pure [init --> final:child:children]