diff options
Diffstat (limited to 'src/parser.hs')
| -rw-r--r-- | src/parser.hs | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/parser.hs b/src/parser.hs new file mode 100644 index 0000000..79c30be --- /dev/null +++ b/src/parser.hs @@ -0,0 +1,48 @@ +module Parser where + +import qualified Data.Bifunctor as B +import qualified Data.Hashable as DH +import Data.List (isPrefixOf) +import Data.Map (Map, (!)) +import qualified Data.Map as M +import qualified Data.Text as T +import LTypes +import Utils + +parseWord rawStr + | isIntStr rawStr = LInteger (read rawStr) + | isFloatStr rawStr = LFloat $ read rawStr + | isCharStr rawStr = LChar $ rawStr !! 1 + | "##" `isPrefixOf` rawStr = LStringLitRef $ drop 2 rawStr + | "$" `isPrefixOf` rawStr = LLabel $ tail rawStr + | otherwise = LSymbol rawStr + +removeComments source = + let lines_ = lines source $> map (T.pack .> T.splitOn (T.pack "--") .> head .> T.unpack) + in unlines lines_ + +processStringLiterals source = + let refMap = M.empty + in processStringLiterals' Nothing refMap source + +processStringLiterals' :: Maybe String -> Map String String -> String -> (String, Map String String) +processStringLiterals' currentM refMap [] = case currentM of + Just _ -> error "[error] nonterminated string literal" + Nothing -> ([], refMap) +processStringLiterals' currentM refMap (c : source) = case c of + '"' -> case currentM of + Just str -> + let hash = DH.hash str $> show + newRefMap = M.insert hash str refMap + (resSource, resRefMap) = processStringLiterals' Nothing newRefMap source + in ("##" ++ hash ++ resSource, resRefMap) + Nothing -> + processStringLiterals' (Just "") refMap source + other -> case currentM of + Just str -> processStringLiterals' (Just $ str ++ [c]) refMap source + Nothing -> processStringLiterals' Nothing refMap source $> B.first (c :) + +parseSource source = + let woComments = source $> removeComments + (woStringLiterals, stringLiteralRefMap) = processStringLiterals woComments + in (woStringLiterals $> words .> map parseWord, stringLiteralRefMap) |
