module Axel.Parse.AST where
import Data.IORef (IORef, modifyIORef, newIORef, readIORef)
import System.IO.Unsafe (unsafePerformIO)
data Expression
= LiteralChar Char
| LiteralInt Int
| LiteralString String
| SExpression [Expression]
| Symbol String
deriving (Eq, Show)
toAxel :: Expression -> String
toAxel (LiteralChar x) = ['\\', x]
toAxel (LiteralInt x) = show x
toAxel (LiteralString xs) = "\"" ++ xs ++ "\""
toAxel (SExpression xs) = "(" ++ unwords (map toAxel xs) ++ ")"
toAxel (Symbol x) = x
{-# NOINLINE gensymCounter #-}
gensymCounter :: IORef Int
gensymCounter = unsafePerformIO $ newIORef 0
gensym :: IO Expression
gensym = do
suffix <- readIORef gensymCounter
let identifier = "aXEL_AUTOGENERATED_IDENTIFIER_" ++ show suffix
modifyIORef gensymCounter succ
pure $ Symbol identifier