|
0 |
-- Interpreter for Aubergine http://esolangs.org/wiki/Aubergine/aubergine.hs
|
|
1 |
-- does not handle input at all
|
|
2 |
|
|
3 |
import qualified Data.Char as Char
|
|
4 |
|
|
5 |
-- a b i program
|
|
6 |
data State = State Integer Integer Integer [Integer]
|
|
7 |
deriving (Ord, Eq, Show)
|
|
8 |
|
|
9 |
getAt 0 (head:_) = head
|
|
10 |
getAt n (head:tail) = getAt (n-1) tail
|
|
11 |
|
|
12 |
getCharAt n l = Char.chr $ fromIntegral $ getAt n l
|
|
13 |
|
|
14 |
setAt 0 v (_:tail) = v:tail
|
|
15 |
setAt n v (head:tail) = head:setAt (n-1) v tail
|
|
16 |
|
|
17 |
getCmd (State _ _ i p) =
|
|
18 |
(getCharAt i p, getCharAt (i+1) p, getCharAt (i+2) p)
|
|
19 |
|
|
20 |
get '1' _ = 1
|
|
21 |
get 'a' (State a _ _ _) = a
|
|
22 |
get 'b' (State _ b _ _) = b
|
|
23 |
get 'i' (State _ _ i _) = i
|
|
24 |
get 'A' (State a _ _ p) = getAt a p
|
|
25 |
get 'B' (State _ b _ p) = getAt b p
|
|
26 |
|
|
27 |
set 'a' a (State _ b i p) = State a b i p
|
|
28 |
set 'b' b (State a _ i p) = State a b i p
|
|
29 |
set 'i' i (State a b _ p) = State a b i p
|
|
30 |
set 'A' x (State a b i p) = State a b i $ setAt a x p
|
|
31 |
set 'B' x (State a b i p) = State a b i $ setAt b x p
|
|
32 |
|
|
33 |
advance (State a b i p) = State a b (i+3) p
|
|
34 |
|
|
35 |
step :: State -> IO State
|
|
36 |
step s@(State a b i p) = do
|
|
37 |
s' <- case getCmd s of
|
|
38 |
('=', 'o', src) -> do
|
|
39 |
putChar $ Char.chr $ fromIntegral $ get src s
|
|
40 |
return s
|
|
41 |
('=', dest, src) -> do
|
|
42 |
return $ set dest (get src s) s
|
|
43 |
('+', dest, src) -> do
|
|
44 |
return $ set dest (get dest s + get src s) s
|
|
45 |
('-', dest, src) -> do
|
|
46 |
return $ set dest (get dest s - get src s) s
|
|
47 |
(':', dest, src) ->
|
|
48 |
case get src s of
|
|
49 |
0 -> do return s
|
|
50 |
_ -> do return $ State a b (get dest s) p
|
|
51 |
return $ advance s'
|
|
52 |
|
|
53 |
run :: State -> IO State
|
|
54 |
run s = do
|
|
55 |
s'@(State _ _ i p) <- step s
|
|
56 |
let size = fromIntegral $ length p
|
|
57 |
if i >= size then return s' else run s'
|
|
58 |
|
|
59 |
parse string =
|
|
60 |
State 0 0 0 $ map (fromIntegral . Char.ord) string
|
|
61 |
|
|
62 |
runString string = run $ parse string
|
|
63 |
|