Last active
May 5, 2025 18:59
-
-
Save nevrome/1c32832e8967bc98a523f184b763c49f to your computer and use it in GitHub Desktop.
A minimal Haskell interpreter for a tiny DSL
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env stack | |
| {- stack script | |
| --resolver lts-22.43 | |
| --package parsec | |
| -} | |
| -- haskell stack (https://docs.haskellstack.org/en/stable/) script, | |
| -- works if stack is on the PATH and the code.txt file is in the same directory | |
| -- run with ./c14script.hs | |
| import Text.Parsec ((<|>)) | |
| import qualified Text.Parsec as P | |
| import qualified Text.Parsec.Error as P | |
| import qualified Text.Parsec.String as P | |
| main :: IO () | |
| main = do | |
| code <- readFile "code.txt" | |
| ast <- case P.runParser (parseExpr <* P.eof) () "" code of | |
| Left err -> fail $ show err | |
| Right x -> return x | |
| let calRes = eval ast | |
| putStrLn calRes | |
| data Expr = | |
| C14 Int Int | |
| | Sum Expr Expr | |
| | Product Expr Expr | |
| deriving Show | |
| eval :: Expr -> String | |
| eval (C14 bp sd) = show bp ++ "±" ++ show sd | |
| eval (Sum e1 e2) = "(" ++ eval e1 ++ " + " ++ eval e2 ++ ")" | |
| eval (Product e1 e2) = "(" ++ eval e1 ++ " * " ++ eval e2 ++ ")" | |
| parseExpr :: P.Parser Expr | |
| parseExpr = P.try parseSum <|> parseTerm | |
| parseTerm :: P.Parser Expr | |
| parseTerm = P.try parseProduct <|> parseFactor | |
| parseFactor :: P.Parser Expr | |
| parseFactor = parseInParens <|> parseC14 | |
| parseInParens :: P.Parser Expr | |
| parseInParens = P.between (P.char '(') (P.char ')') parseExpr | |
| parseC14 :: P.Parser Expr | |
| parseC14 = do | |
| _ <- P.string "c14(" | |
| bp <- read <$> P.many1 P.digit | |
| _ <- P.char ',' | |
| sd <- read <$> P.many1 P.digit | |
| _ <- P.char ')' | |
| return $ C14 bp sd | |
| parseSum :: P.Parser Expr | |
| parseSum = do | |
| expr1 <- parseTerm | |
| _ <- P.spaces | |
| _ <- P.char '+' | |
| _ <- P.spaces | |
| expr2 <- parseExpr | |
| return $ Sum expr1 expr2 | |
| parseProduct :: P.Parser Expr | |
| parseProduct = do | |
| expr1 <- parseFactor | |
| _ <- P.spaces | |
| _ <- P.char '*' | |
| _ <- P.spaces | |
| expr2 <- parseTerm | |
| return $ Product expr1 expr2 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (c14(3000,30) + c14(3500,25)) * c14(3550,100) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment