Skip to content

Instantly share code, notes, and snippets.

@nevrome
Last active May 5, 2025 18:59
Show Gist options
  • Select an option

  • Save nevrome/1c32832e8967bc98a523f184b763c49f to your computer and use it in GitHub Desktop.

Select an option

Save nevrome/1c32832e8967bc98a523f184b763c49f to your computer and use it in GitHub Desktop.
A minimal Haskell interpreter for a tiny DSL
#!/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
(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