Created
September 3, 2020 04:56
-
-
Save jxxcarlson/5eb1e9cb0efde9abd14ec4e84a738c43 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Parse exposing (AST(..), toAST) | |
{- | |
Parse a string of Lisp text, return Just AST if it is legal, Nothing if not. | |
-} | |
import Parser exposing (..) | |
import ParserHelpers exposing (..) | |
type AST | |
= Str String | |
| Num Int | |
| LIST (List AST) | |
{-| | |
> toAST "(* 2 (+ 3 4))" | |
Just (LIST [Str "*",Num 2,LIST [Str "+",Num 3,Num 4]]) | |
-} | |
toAST : String -> Maybe AST | |
toAST str = | |
case run parse str of | |
Ok ast -> | |
Just ast | |
Err _ -> | |
Nothing | |
parse : Parser AST | |
parse = | |
oneOf [ lazy (\_ -> list), string, integer ] | |
list : Parser AST | |
list = | |
(succeed identity | |
|. symbol "(" | |
|. spaces | |
|= many parse | |
|. spaces | |
|. symbol ")" | |
|. spaces | |
) | |
|> map LIST | |
-- STRING | |
string : Parser AST | |
string = | |
oneOf [ operator, string_ ] | |
string_ : Parser AST | |
string_ = | |
getChompedString | |
(succeed () | |
|. chompIf (\c -> Char.isAlpha c) | |
|. chompWhile (\c -> Char.isAlphaNum c) | |
|. symbol " " | |
) | |
|> map (String.trim >> Str) | |
-- OPERATORS | |
operator : Parser AST | |
operator = | |
oneOf [ plus, minus, times, divide ] | |
plus : Parser AST | |
plus = | |
(succeed "+" | |
|. symbol "+" | |
) | |
|> map Str | |
minus : Parser AST | |
minus = | |
(succeed "-" | |
|. symbol "-" | |
) | |
|> map Str | |
times : Parser AST | |
times = | |
(succeed "*" | |
|. symbol "*" | |
) | |
|> map Str | |
divide : Parser AST | |
divide = | |
(succeed "/" | |
|. symbol "/" | |
) | |
|> map Str | |
-- INTEGER | |
integer : Parser AST | |
integer = | |
(succeed identity | |
|= int | |
) | |
|> map Num | |
-- HELPERS | |
many : Parser a -> Parser (List a) | |
many p = | |
loop [] (manyHelp p) | |
manyHelp : Parser a -> List a -> Parser (Step (List a) (List a)) | |
manyHelp p vs = | |
oneOf | |
[ succeed (\v -> Loop (v :: vs)) | |
|= p | |
|. spaces | |
, succeed () | |
|> map (\_ -> Done (List.reverse vs)) | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment