Skip to content

Instantly share code, notes, and snippets.

@314maro
Created March 13, 2014 09:07
Show Gist options
  • Select an option

  • Save 314maro/9524814 to your computer and use it in GitHub Desktop.

Select an option

Save 314maro/9524814 to your computer and use it in GitHub Desktop.
### ใƒฉใƒ ใƒ€
๐Ÿซ ๅค‰ๆ•ฐ๐Ÿ‘‰ ๅผ
### ๆ‹ฌๅผง
๐ŸŒœ ๅผ๐ŸŒ›
### ใ‚ณใƒกใƒณใƒˆ
๐ŸŒ ใ‚ณใƒก๐ŸŒ ใƒใ‚นใƒˆใงใใ‚‹๐ŸŒž ใƒณใƒˆ๐ŸŒž
### ไพ‹
๐Ÿซ ๐Ÿญ ๐Ÿ‘‰ ๐Ÿซ ๐Ÿฎ ๐Ÿ‘‰ ๐Ÿซ ๐Ÿฏ ๐Ÿ‘‰ ๐Ÿญ ๐Ÿฏ ๐ŸŒœ ๐Ÿฎ ๐Ÿฏ ๐ŸŒ› ๐ŸŒ Sใ‚ณใƒณใƒ“ใƒใƒผใ‚ฟ๐ŸŒž
### ใƒใ‚ฐ
ๅค‰ๆ•ฐใพใ‚ใ‚Šใซใƒใ‚ฐใŒใ‚ใ‚‹
ใƒ‰ใƒปใƒ–ใƒฉใƒณ ใ‚คใƒณใƒ‡ใƒƒใ‚ฏใ‚น ใ‚’ไฝฟใ†ใฎใ‹ใช
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
import Control.Applicative
import qualified Text.Trifecta as T
import qualified Text.Parser.Token.Style as TS
import qualified Data.HashSet as H
import Data.Monoid (mempty)
import Data.Char
main = getLine >>= run
run code = case T.parseString (runComment expr) mempty code of
T.Failure d -> print d
T.Success s -> print $ eval s
data Expr = Fun String Expr
| Var String
| App Expr Expr
showParen' True s = ("๐ŸŒœ " ++) . s . ("๐ŸŒ› " ++)
showParen' False s = s
instance Show Expr where
showsPrec n (Fun v e) = showParen' (n > 9) $ \s -> "๐Ÿซ " ++ v ++ " ๐Ÿ‘‰ " ++ shows e s
showsPrec n (Var v) = (v ++) . (' ' :)
showsPrec n (App e1 e2) = showParen' (n > 10) $ showsPrec 10 e1 . showsPrec 11 e2
{-
elem' :: String -> Expr -> Bool
elem' v (Fun u e) = v /= u && elem' v e
elem' v (Var u) = v == u
elem' v (App e1 e2) = elem' v e1 || elem' v e2
-}
subst :: String -> Expr -> Expr -> Expr
subst name v e = go e
where
go (Fun u e)
| name == u = Fun u e
-- | u `elem'` v =
| otherwise = Fun u (go e)
go (Var u)
| name == u = v
| otherwise = Var u
go (App e1 e2) = App (go e1) (go e2)
eval :: Expr -> Expr
eval (App f x) = case (eval f, eval x) of
(Fun name e, x) -> eval $ subst name x e
(f, x) -> App f x
eval e = e
newtype Comment a = Comment { runComment :: T.Parser a }
deriving (Functor,Applicative,Alternative,Monad,T.Parsing,T.CharParsing)
instance T.TokenParsing Comment where
nesting (Comment m) = Comment (T.nesting m)
someSpace = TS.buildSomeSpaceParser (Comment T.someSpace) style
where
style = TS.emptyCommentStyle
{ TS._commentStart = "๐ŸŒ" , TS._commentEnd = "๐ŸŒž" }
semi = Comment T.semi
highlight h (Comment m) = Comment (T.highlight h m)
var :: Comment String
var = T.ident style
where
char = T.satisfy $ \c -> generalCategory c == OtherSymbol && not (c `elem` reserved)
style = (TS.emptyIdents :: T.IdentifierStyle Comment)
{ T._styleStart = char
, T._styleLetter = char
, T._styleReserved = H.fromList $ map (:[]) reserved
}
reserved = ['๐Ÿซ','๐Ÿ‘‰','๐ŸŒœ','๐ŸŒ›','๐ŸŒ','๐ŸŒž']
expr' :: Comment Expr
expr' = T.chainl1 fact (pure App)
fact :: Comment Expr
fact = T.between (T.symbolic '๐ŸŒœ') (T.symbolic '๐ŸŒ›') expr
<|> (Var <$> var)
expr :: Comment Expr
expr = (Fun <$ T.symbolic '๐Ÿซ' <*> var <* T.symbolic '๐Ÿ‘‰' <*> expr)
<|> expr'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment