module Main where
import Data.Map as Map
data Runnable
| Add Runnable Runnable
| Block
(Map
String Runnable
) Runnable
-- Instances
-- Integers resolve to Right Integer
run (I v) _ = Right v
-- For Names
-- look up their expression in the scope, then evaluate
-- if name is out of scope, raise an error
run
(Name n
) s
= which
(Map
.lookup n s
) where which Nothing = Left ["Variable not in scope: " ++ n]
which (Just v) = run v s
-- For Addition
-- Run a, Run b, Add their results
-- Raise appropriate errors where necessary
run (Add a b) s = geta (run a s) where
geta
(Left es
) = Left
(es
++ ["In lhs of expression: " ++ show (Add a b
)]) geta (Right a') = getb a' (run b s)
getb
_ (Left es
) = Left
(es
++ ["In rhs of expression: " ++ show (Add a b
)]) getb a' (Right b') = Right (a' + b')
-- For Blocks
-- Run the block's expression under a new scope
-- (merging the current with the block's scope definition)
run (Block s' e) s = result $ run e (Map.union s' s) where
result
(Left es
) = Left
(es
++ ["In block: " ++ show (Block s
' e)]) result (Right v) = Right v
instance Num Runnable where
(+) = undefined
(-) = undefined
(*) = undefined
negate = undefined
signum = undefined
fromInteger = I
main = mapM_ print
[ run 5 Map.empty
, run (Name "a") Map.empty
, run (Name "a") (fromList [("a", 6)])
, run (Add 6 3) Map.empty
, run (Add (Name "a") 7) (fromList [("a", 10)])
, run (Block (fromList [("a", 10)]) (Name "a")) Map.empty
]
bW9kdWxlIE1haW4gd2hlcmUKaW1wb3J0IERhdGEuTWFwIGFzIE1hcAoKZGF0YSBSdW5uYWJsZQogID0gTmFtZSBTdHJpbmcKICB8IEFkZCBSdW5uYWJsZSBSdW5uYWJsZQogIHwgQmxvY2sgKE1hcCBTdHJpbmcgUnVubmFibGUpIFJ1bm5hYmxlCiAgfCBJIEludGVnZXIKICBkZXJpdmluZyAoRXEsIE9yZCwgU2hvdykKCnJ1biA6OiBSdW5uYWJsZSAtPiBNYXAgU3RyaW5nIFJ1bm5hYmxlIC0+IEVpdGhlciBbU3RyaW5nXSBJbnRlZ2VyCi0tICBJbnN0YW5jZXMKLS0gIEludGVnZXJzIHJlc29sdmUgdG8gUmlnaHQgSW50ZWdlcgpydW4gKEkgdikgXyA9IFJpZ2h0IHYKLS0gIEZvciBOYW1lcwotLSAgICBsb29rIHVwIHRoZWlyIGV4cHJlc3Npb24gaW4gdGhlIHNjb3BlLCB0aGVuIGV2YWx1YXRlCi0tICAgIGlmIG5hbWUgaXMgb3V0IG9mIHNjb3BlLCByYWlzZSBhbiBlcnJvcgpydW4gKE5hbWUgbikgcyA9IHdoaWNoIChNYXAubG9va3VwIG4gcykgd2hlcmUKICB3aGljaCBOb3RoaW5nID0gTGVmdCBbIlZhcmlhYmxlIG5vdCBpbiBzY29wZTogIiArKyBuXQogIHdoaWNoIChKdXN0IHYpID0gcnVuIHYgcwotLSAgRm9yIEFkZGl0aW9uCi0tICAgIFJ1biBhLCBSdW4gYiwgQWRkIHRoZWlyIHJlc3VsdHMKLS0gICAgUmFpc2UgYXBwcm9wcmlhdGUgZXJyb3JzIHdoZXJlIG5lY2Vzc2FyeQpydW4gKEFkZCBhIGIpIHMgPSBnZXRhIChydW4gYSBzKSB3aGVyZQogIGdldGEgKExlZnQgZXMpID0gTGVmdCAoZXMgKysgWyJJbiBsaHMgb2YgZXhwcmVzc2lvbjogIiArKyBzaG93IChBZGQgYSBiKV0pCiAgZ2V0YSAoUmlnaHQgYScpID0gZ2V0YiBhJyAocnVuIGIgcykKICBnZXRiIF8gKExlZnQgZXMpID0gTGVmdCAoZXMgKysgWyJJbiByaHMgb2YgZXhwcmVzc2lvbjogIiArKyBzaG93IChBZGQgYSBiKV0pCiAgZ2V0YiBhJyAoUmlnaHQgYicpID0gUmlnaHQgKGEnICsgYicpCi0tICBGb3IgQmxvY2tzCi0tICAgIFJ1biB0aGUgYmxvY2sncyBleHByZXNzaW9uIHVuZGVyIGEgbmV3IHNjb3BlCi0tICAgICAgKG1lcmdpbmcgdGhlIGN1cnJlbnQgd2l0aCB0aGUgYmxvY2sncyBzY29wZSBkZWZpbml0aW9uKQpydW4gKEJsb2NrIHMnIGUpIHMgPSByZXN1bHQgJCBydW4gZSAoTWFwLnVuaW9uIHMnIHMpIHdoZXJlCiAgcmVzdWx0IChMZWZ0IGVzKSA9IExlZnQgKGVzICsrIFsiSW4gYmxvY2s6ICIgKysgc2hvdyAoQmxvY2sgcycgZSldKQogIHJlc3VsdCAoUmlnaHQgdikgPSBSaWdodCB2CgppbnN0YW5jZSBOdW0gUnVubmFibGUgd2hlcmUKICAoKykgPSB1bmRlZmluZWQKICAoLSkgPSB1bmRlZmluZWQKICAoKikgPSB1bmRlZmluZWQKICBuZWdhdGUgPSB1bmRlZmluZWQKICBzaWdudW0gPSB1bmRlZmluZWQKICBmcm9tSW50ZWdlciA9IEkKCm1haW4gPSBtYXBNXyBwcmludAogIFsgcnVuIDUgTWFwLmVtcHR5CiAgLCBydW4gKE5hbWUgImEiKSBNYXAuZW1wdHkKICAsIHJ1biAoTmFtZSAiYSIpIChmcm9tTGlzdCBbKCJhIiwgNildKQogICwgcnVuIChBZGQgNiAzKSBNYXAuZW1wdHkKICAsIHJ1biAoQWRkIChOYW1lICJhIikgNykgKGZyb21MaXN0IFsoImEiLCAxMCldKQogICwgcnVuIChCbG9jayAoZnJvbUxpc3QgWygiYSIsIDEwKV0pIChOYW1lICJhIikpIE1hcC5lbXB0eQogIF0=