-- SPDX-FileCopyrightText: Chris Pressey, the creator of this work, has dedicated it to the public domain.
-- For more information, please refer to <https://unlicense.org/>
-- SPDX-License-Identifier: Unlicense
module Language.Turmac.Parser where
import Data.Char (isSpace)
import Language.Turmac.Model
--
-- Parsing
--
-- Split string by comma, handling quoted fields
splitCSV :: String -> [String]
splitCSV = parseCells ""
where
parseCells acc [] = [reverse acc]
parseCells acc (',':cs) = reverse acc : parseCells "" cs
parseCells acc (c:cs) = parseCells (c:acc) cs
-- Trim whitespace from a string
trim :: String -> String
trim = f . f
where f = reverse . dropWhile isSpace
-- Parse a single line into a TMRule, dropping
-- any lines that start with halt states, or have
-- other than 5 columns
parseLine :: String -> Maybe TMRule
parseLine line = case map trim $ splitCSV line of
[('@':_state), _, _, _, _] -> Nothing
[state, symbol, newSym, dir, newState] -> do
d <- case dir of
"L" -> Just (-1)
"R" -> Just 1
_ -> Nothing
Just (state, symbol, newSym, newState, d)
_ -> Nothing
-- Parse the full TM description from CSV format
parseRules :: String -> [TMRule]
parseRules input = case lines $ filter (/= '\r') input of
[] -> []
(_:datelines) -> -- Skip header line
[ rule | Just rule <- map parseLine datelines ]