Skip to content

Instantly share code, notes, and snippets.

@FMNSSun
Last active October 18, 2015 10:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FMNSSun/8fda4a039fbf4fe399b6 to your computer and use it in GitHub Desktop.
Save FMNSSun/8fda4a039fbf4fe399b6 to your computer and use it in GitHub Desktop.
Simple esolang. Full source code for http://mroman.ch/impleso.html
import Text.ParserCombinators.Parsec
import Text.ParserCombinators.Parsec.Combinator
import Text.ParserCombinators.Parsec.Expr
import Text.ParserCombinators.Parsec.Token
import Data.Maybe
data Expression =
Loop [Expression]
| Literal Integer
| Instruction Char
deriving (Show, Read)
runParserWithString p input =
case parse p "" input of
Left err -> error $ show err
Right q -> q
parseInteger :: Parser Expression
parseInteger = do
optional spaces
sign <- optionMaybe $ char '-'
digits <- many1 $ oneOf "0123456789"
optional spaces
case sign of
Just q -> return $ Literal . read $ "-" ++ digits
Nothing -> return $ Literal . read $ digits
parseInstruction :: Parser Expression
parseInstruction = do
optional spaces
ins <- oneOf "+-*/^v\\$"
optional spaces
return $ Instruction ins
parseLoop :: Parser Expression
parseLoop = do
optional spaces
char '('
optional spaces
exps <- parseExpressions
optional spaces
char ')'
optional spaces
return $ Loop exps
parseExpressions :: Parser [Expression]
parseExpressions = many $ (try parseInteger) <|> parseInstruction <|> parseLoop
eval xs = evalExps xs ([],[])
evalExps (x:xs) state = evalExps xs (evalExp x state)
evalExps [] state = state
evalExp (Literal i) (ms, ss) = (i : ms, ss)
evalExp (Instruction '+') ((b:a:ms),ss) = ((a+b) : ms, ss)
evalExp (Instruction '-') ((b:a:ms),ss) = ((a-b) : ms, ss)
evalExp (Instruction '*') ((b:a:ms),ss) = ((a*b) : ms, ss)
evalExp (Instruction '/') ((b:a:ms),ss) = ((a `div` b) : ms, ss)
evalExp (Instruction 'v') ((a:ms),ss) = (ms, a : ss)
evalExp (Instruction '$') (ms,(a:ss)) = (a : ms, ss)
evalExp (Instruction '^') ((a:ms),ss) = (a : a : ms, ss)
evalExp (Instruction '\\') ((a:b:ms),ss) = (b : a : ms, ss)
evalExp (Loop exps) (0 : ms, ss) = (0 : ms, ss)
evalExp l@(Loop exps) (a : ms, ss) = evalExp l (evalExps exps (a : ms, ss))
evalExp q s = error $ show q
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment