module SeqSim.Parser exposing (parse, valid, vars, varsValid, Prog, Source(..)) import Parser exposing (Parser, Step(..), Trailing(..), run, end, succeed, loop, sequence, (|=), (|.), spaces, symbol, int, map, oneOf, variable, sequence) import Char exposing (isAlpha, isAlphaNum) import Set exposing (empty) import Tuple type alias Prog = List (String, Source) type Source = Var String | Const Int parseVar : Parser String parseVar = variable { start = isAlpha , inner = isAlphaNum , reserved = Set.empty } parseSource : Parser Source parseSource = oneOf [ Parser.map Const int , Parser.map Var parseVar ] parseCmd : Parser (String, Source) parseCmd = succeed Tuple.pair |= parseVar |. spaces |. symbol "=" |. spaces |= parseSource parseProg : Parser Prog parseProg = let step s = oneOf [ succeed (\cmd -> Loop (cmd::s)) |= parseCmd |. spaces , spaces |> Parser.map (\_ -> Done (List.reverse s)) ] in loop [] step parseVars : Parser (List String) parseVars = sequence { start = "" , separator = "," , end = "" , spaces = spaces , item = parseVar , trailing = Optional } vars : String -> Maybe (List String) vars s = case run (succeed (\x -> x) |. spaces |= parseVars |. spaces |. end) s of Ok p -> Just p Err _ -> Nothing varsValid : String -> Bool varsValid s = case vars s of Just _ -> True Nothing -> False parse : String -> Maybe Prog parse s = case run (succeed (\x->x) |. spaces |= parseProg |. end) s of Ok p -> Just p Err _ -> Nothing valid : String -> Bool valid s = case parse s of Just _ -> True Nothing -> False