diff options
| author | Jan Tuomi <jans.tuomi@gmail.com> | 2022-02-06 19:05:46 +0200 |
|---|---|---|
| committer | Jan Tuomi <jans.tuomi@gmail.com> | 2022-02-06 20:03:27 +0200 |
| commit | d5fe35bb8a75a74c7b3616b864c4d35bafecaadd (patch) | |
| tree | 410325cafa976dfa0596872d8c0582e1b36772c0 /src/parser.hs | |
| parent | c2053ee0585280229375b10283cb9e8dbb903734 (diff) | |
Add proper cabal setup
Diffstat (limited to 'src/parser.hs')
| -rw-r--r-- | src/parser.hs | 76 |
1 files changed, 0 insertions, 76 deletions
diff --git a/src/parser.hs b/src/parser.hs deleted file mode 100644 index 679f318..0000000 --- a/src/parser.hs +++ /dev/null @@ -1,76 +0,0 @@ -module Parser where - -import Control.Monad.Except -import qualified Data.Bifunctor as B -import qualified Data.Hashable as DH -import Data.List (intercalate, isInfixOf, 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 = - lines .> map (T.pack .> T.splitOn (T.pack "--") .> head .> T.unpack) .> unlines - -processStringLiterals :: Maybe String -> Map String [LWord] -> String -> ExceptT LException IO (String, Map String [LWord]) -processStringLiterals currentM refMap [] = case currentM of - Just _ -> throwError $ LException "nonterminated string literal" - Nothing -> pure ([], refMap) -processStringLiterals currentM refMap (c : source) = case c of - '"' -> case currentM of - Just str -> do - -- string literal ends - let hash = DH.hash str $> show - let strP = str $> map LChar .> LPhrase - interpolated <- processSLInterpolations strP - let newRefMap = M.insert hash interpolated refMap - (resSource, resRefMap) <- processStringLiterals Nothing newRefMap source - pure ("##" ++ hash ++ resSource, resRefMap) - Nothing -> - -- string literal starts - processStringLiterals (Just "") refMap source - other -> case currentM of - Just str -> - -- add char to current string literal - processStringLiterals (Just $ str ++ [c]) refMap source - Nothing -> - -- proceed normally - processStringLiterals Nothing refMap source $> fmap (B.first (c :)) - -internalNVar n = LLabel $ fmt "$__%%" [show n] - -processSLInterpolations :: LWord -> ExceptT LException IO [LWord] -processSLInterpolations strP@(LPhrase lChars) - | "%%" `isInfixOf` chars = pure [LPhrase interpolated, LSymbol "unphrase"] - | otherwise = pure [strP] - where - chars = lChars $> map (\(LChar c) -> c) - -- split string on the %% marker into n substrings - separatedByMarker = T.pack chars $> T.splitOn (T.pack "%%") .> map (T.unpack .> map LChar) - labelIndices = [0 .. length separatedByMarker - 1 - 1] - -- store n - 1 variables from stack - varStores = labelIndices $> map (\n -> [internalNVar n, LSymbol "!"]) .> reverse - part1 = concat varStores - -- interleave the n substrings and n - 1 variable reads - symbolLookups = labelIndices $> map (\n -> [internalNVar n, LSymbol "@", LSymbol "unphrase"]) - part2 = LSymbol "'[" : concat (mix separatedByMarker symbolLookups) ++ [LSymbol "']", LSymbol "phrase"] - -- forget the temp variables used - varForgets = labelIndices $> map (\n -> [internalNVar n, LSymbol "forget"]) - part3 = concat varForgets - -- combine everything into one phrase - interpolated = part1 ++ part2 ++ part3 -processSLInterpolations p = throwError $ LException $ fmt "non-phrase in processSLInterpolations: %%" [show p] - -parseSource source = do - let woComments = source $> removeComments - (woStringLiterals, stringLiteralRefMap) <- processStringLiterals Nothing M.empty woComments - pure (woStringLiterals $> words .> map parseWord, stringLiteralRefMap)
\ No newline at end of file |
