summaryrefslogtreecommitdiff
path: root/src/Thue/Interpreter.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Thue/Interpreter.hs')
-rw-r--r--src/Thue/Interpreter.hs77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/Thue/Interpreter.hs b/src/Thue/Interpreter.hs
new file mode 100644
index 0000000..c53bff9
--- /dev/null
+++ b/src/Thue/Interpreter.hs
@@ -0,0 +1,77 @@
+module Thue.Interpreter (
+ thue,
+ extractInfix,
+ nextInRange
+ ) where
+
+
+import System.Random
+import Data.Maybe
+import Data.List
+import Thue.Parser
+
+
+
+
+thue :: ThueProgram -> IO ThueState
+thue program =
+ let rules = thueRules program
+ state = thueInitialState program
+ gen = mkStdGen 4 --chosen by fair dice roll, guaranteed to be random
+
+ in interpret state rules gen
+
+
+
+interpret :: ThueState -> [ThueRule] -> StdGen -> IO ThueState
+interpret state rules gen = do
+ let possibleRules = rules `applicableTo` state
+ ruleToApply = if (possibleRules == []) then (ThueRule "" "") else possibleRules !! num
+ -- ^ dummy rule if no possible rules apply
+
+ (num, gen') = nextInRange 0 (length possibleRules - 1) gen
+
+ (before, after) = fromJust (extractInfix (original ruleToApply) state)
+
+ state' <- case (replacement ruleToApply) of
+ ":::" -> getLine >>= (\x -> return (before ++ x ++ after))
+
+ '~':xs -> putStr xs >> return (before ++ after)
+
+ x -> return (before ++ x ++ after)
+
+ if (possibleRules == []) then return state else interpret state' rules gen'
+
+
+
+extractInfix :: Eq a => [a] -> [a] -> Maybe ([a], [a])
+extractInfix subList list =
+ let f = (\pre cur -> case (stripPrefix subList cur) of
+ Nothing -> f ((head cur):pre) (tail cur)
+ Just x -> (reverse pre, x))
+
+ in if (subList `isInfixOf` list) then Just (f [] list) else Nothing
+
+
+
+nextInRange :: Int -> Int -> StdGen -> (Int, StdGen)
+nextInRange low high random =
+ let (genLow, genHigh) = genRange random
+ (rawNext, random') = next random
+
+ irawNext = fromIntegral rawNext
+ igenLow = fromIntegral genLow
+ igenHigh = fromIntegral genHigh
+ ilow = fromIntegral low
+ ihigh = fromIntegral high
+
+ n' = ((irawNext - igenLow) / (igenHigh - igenLow)) * (ihigh - ilow) + ilow
+
+ in (round n', random')
+
+
+
+applicableTo :: [ThueRule] -> ThueState -> [ThueRule]
+applicableTo ruleList state =
+ filter (\r -> (original r) `isInfixOf` state) ruleList
+