From d472ec32938aef061058826cbc330485e095a1a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Sun, 25 Dec 2016 23:26:55 +0100 Subject: [PATCH 01/10] make it compile under elm 0.18 --- elm-package.json | 10 +-- example/Main.elm | 8 +-- example/elm-package.json | 14 ++-- src/Ast.elm | 19 +++--- src/Ast/Expression.elm | 137 +++++++++++++++++++-------------------- src/Ast/Helpers.elm | 87 +++++++++---------------- src/Ast/Statement.elm | 125 ++++++++++++++++++----------------- tests/Expression.elm | 72 ++++++++++---------- tests/Main.elm | 2 +- tests/Statement.elm | 72 ++++++++++---------- tests/elm-package.json | 16 ++--- 11 files changed, 268 insertions(+), 294 deletions(-) diff --git a/elm-package.json b/elm-package.json index 2534410..3d170f6 100644 --- a/elm-package.json +++ b/elm-package.json @@ -1,5 +1,5 @@ { - "version": "1.0.0", + "version": "2.0.0", "summary": "A parser for Elm code", "repository": "https://github.com/Bogdanp/elm-ast.git", "license": "BSD3", @@ -14,9 +14,9 @@ "Ast.Statement" ], "dependencies": { - "elm-lang/core": "4.0.0 <= v < 5.0.0", - "Bogdanp/elm-combine": "2.2.1 <= v < 3.0.0", - "elm-community/list-extra": "3.1.0 <= v < 4.0.0" + "elm-lang/core": "5.0.0 <= v < 6.0.0", + "Bogdanp/elm-combine": "3.1.1 <= v < 4.0.0", + "elm-community/list-extra": "5.0.0 <= v < 6.0.0" }, - "elm-version": "0.17.1 <= v < 0.18.0" + "elm-version": "0.18.0 <= v < 0.19.0" } diff --git a/example/Main.elm b/example/Main.elm index 8000ed3..30c97c2 100644 --- a/example/Main.elm +++ b/example/Main.elm @@ -4,7 +4,7 @@ import Ast import Ast.Expression exposing (..) import Ast.Statement exposing (..) import Html exposing (..) -import Html.App as App +import Html import Html.Events exposing (..) import Json.Decode as JD @@ -77,7 +77,7 @@ statement s = tree : String -> Html Msg tree m = case Ast.parse m of - ( Ok statements, _ ) -> + ( Ok (_, _, statements)) -> ul [] (List.map statement statements) err -> @@ -92,9 +92,9 @@ view model = ] -main : Program Never +main : Program Never String Msg main = - App.beginnerProgram + Html.beginnerProgram { model = init , update = update , view = view diff --git a/example/elm-package.json b/example/elm-package.json index 474d7e0..8a2686d 100644 --- a/example/elm-package.json +++ b/example/elm-package.json @@ -1,6 +1,6 @@ { - "version": "1.0.0", - "summary": "an example", + "version": "2.0.0", + "summary": "example for elm-ast", "repository": "https://github.com/Bogdanp/elm-ast.git", "license": "BSD3", "source-directories": [ @@ -9,10 +9,10 @@ ], "exposed-modules": [], "dependencies": { - "elm-lang/core": "4.0.0 <= v < 5.0.0", - "elm-lang/html": "1.0.0 <= v < 2.0.0", - "Bogdanp/elm-combine": "2.1.0 <= v < 3.0.0", - "elm-community/list-extra": "3.1.0 <= v < 4.0.0" + "elm-lang/core": "5.0.0 <= v < 6.0.0", + "elm-lang/html": "2.0.0 <= v < 3.0.0", + "Bogdanp/elm-combine": "3.1.0 <= v < 4.0.0", + "elm-community/list-extra": "5.0.0 <= v < 6.0.0" }, - "elm-version": "0.17.0 <= v < 0.18.0" + "elm-version": "0.18.0 <= v < 0.19.0" } diff --git a/src/Ast.elm b/src/Ast.elm index be47741..d83e449 100644 --- a/src/Ast.elm +++ b/src/Ast.elm @@ -12,8 +12,7 @@ module Ast exposing -} -import Combine exposing (Context, end) -import Combine.Infix exposing ((<*)) +import Combine exposing (end, (<*)) import Ast.BinOp exposing (OpTable, operators) import Ast.Expression exposing (Expression, expression) @@ -21,31 +20,31 @@ import Ast.Statement exposing (Statement, statement, statements, opTable) {-| Parse an Elm expression. -} -parseExpression : OpTable -> String -> (Result (List String) Expression, Context) +parseExpression : OpTable -> String -> Result (Combine.ParseErr ()) (Combine.ParseOk () Expression) parseExpression ops = Combine.parse (expression ops <* end) {-| Parse an Elm statement. -} -parseStatement : OpTable -> String -> (Result (List String) Statement, Context) +parseStatement : OpTable -> String -> Result (Combine.ParseErr ()) (Combine.ParseOk () Statement) parseStatement ops = Combine.parse (statement ops <* end) {-| Parse an OpTable from a module. -} -parseOpTable : OpTable -> String -> (Result (List String) OpTable, Context) +parseOpTable : OpTable -> String -> Result (Combine.ParseErr ()) (Combine.ParseOk () OpTable) parseOpTable ops = Combine.parse (opTable ops) {-| Parse an Elm module. -} -parseModule : OpTable -> String -> (Result (List String) (List Statement), Context) +parseModule : OpTable -> String -> Result (Combine.ParseErr ()) (Combine.ParseOk () (List Statement)) parseModule ops = Combine.parse (statements ops) {-| Parse an Elm module, scanning for infix declarations first. -} -parse : String -> (Result (List String) (List Statement), Context) +parse : String -> Result (Combine.ParseErr ()) (Combine.ParseOk () (List Statement)) parse input = case parseOpTable operators input of - (Ok ops, _) -> + (Ok (state, stream, ops)) -> parseModule ops input - (Err ms, cx) -> - (Err ms, cx) + (Err e) -> + (Err e) diff --git a/src/Ast/Expression.elm b/src/Ast/Expression.elm index c0dc823..62f25fb 100644 --- a/src/Ast/Expression.elm +++ b/src/Ast/Expression.elm @@ -14,7 +14,6 @@ module Ast.Expression exposing import Combine exposing (..) import Combine.Char exposing (..) -import Combine.Infix exposing (..) import Combine.Num import Dict exposing (Dict) import List.Extra exposing (break, singleton) @@ -46,11 +45,11 @@ type Expression | Application Expression Expression | BinOp Expression Expression Expression -character : Parser Expression +character : Parser s Expression character = - Character <$> between' (char '\'') anyChar + Character <$> between_ (char '\'') anyChar -string : Parser Expression +string : Parser s Expression string = let singleString = @@ -63,119 +62,119 @@ string = in multiString <|> singleString -integer : Parser Expression +integer : Parser s Expression integer = Integer <$> Combine.Num.int -float : Parser Expression +float : Parser s Expression float = Float <$> Combine.Num.float -access : Parser Expression +access : Parser s Expression access = Access <$> variable <*> many1 (Combine.string "." *> loName) -variable : Parser Expression +variable : Parser s Expression variable = Variable <$> choice [ singleton <$> loName , sepBy1 (Combine.string "." ) upName ] -range : OpTable -> Parser Expression +range : OpTable -> Parser s Expression range ops = - rec <| \() -> + lazy <| \() -> brackets <| Range <$> (expression ops) <*> (symbol ".." *> expression ops) -list : OpTable -> Parser Expression +list : OpTable -> Parser s Expression list ops = - rec <| \() -> - List <$> brackets (commaSeparated' (expression ops)) + lazy <| \() -> + List <$> brackets (commaSeparated_ (expression ops)) -record : OpTable -> Parser Expression +record : OpTable -> Parser s Expression record ops = - rec <| \() -> - Record <$> braces (commaSeparated' ((,) <$> loName <*> (symbol "=" *> expression ops))) + lazy <| \() -> + Record <$> braces (commaSeparated_ ((,) <$> loName <*> (symbol "=" *> expression ops))) -letExpression : OpTable -> Parser Expression +letExpression : OpTable -> Parser s Expression letExpression ops = let binding = - rec <| \() -> + lazy <| \() -> (,) - <$> (between' whitespace loName) + <$> (between_ whitespace loName) <*> (symbol "=" *> expression ops) in - rec <| \() -> + lazy <| \() -> Let <$> (symbol "let" *> many1 binding) <*> (symbol "in" *> expression ops) -ifExpression : OpTable -> Parser Expression +ifExpression : OpTable -> Parser s Expression ifExpression ops = - rec <| \() -> + lazy <| \() -> If <$> (symbol "if" *> expression ops) <*> (symbol "then" *> expression ops) <*> (symbol "else" *> expression ops) -caseExpression : OpTable -> Parser Expression +caseExpression : OpTable -> Parser s Expression caseExpression ops = let binding = - rec <| \() -> + lazy <| \() -> (,) <$> (whitespace *> expression ops) <*> (symbol "->" *> expression ops) in - rec <| \() -> + lazy <| \() -> Case <$> (symbol "case" *> expression ops) <*> (symbol "of" *> many1 binding) -lambda : OpTable -> Parser Expression +lambda : OpTable -> Parser s Expression lambda ops = - rec <| \() -> + lazy <| \() -> Lambda - <$> (symbol "\\" *> many (between' spaces loName)) + <$> (symbol "\\" *> many (between_ spaces loName)) <*> (symbol "->" *> expression ops) -application : OpTable -> Parser Expression +application : OpTable -> Parser s Expression application ops = - rec <| \() -> - term ops `chainl` (Application <$ spaces') + lazy <| \() -> + term ops |> chainl (Application <$ spaces_) -binary : OpTable -> Parser Expression +binary : OpTable -> Parser s Expression binary ops = - rec <| \() -> + lazy <| \() -> let next = - between' whitespace operator `andThen` \op -> - choice [ Cont <$> application ops, Stop <$> expression ops ] `andThen` \e -> + between_ whitespace operator |> andThen (\op -> + choice [ Cont <$> application ops, Stop <$> expression ops ] |> andThen (\e -> case e of Cont t -> ((::) (op, t)) <$> collect - Stop e -> succeed [(op, e)] + Stop e -> succeed [(op, e)])) collect = next <|> succeed [] in - application ops `andThen` \e -> - collect `andThen` \eops -> - split ops 0 e eops + application ops |> andThen (\e -> + collect |> andThen (\eops -> + split ops 0 e eops)) -term : OpTable -> Parser Expression +term : OpTable -> Parser s Expression term ops = - rec <| \() -> + lazy <| \() -> choice [ character, string, float, integer, access, variable , range ops, list ops, record ops , parens (expression ops) ] {-| A parser for Elm expressions. -} -expression : OpTable -> Parser Expression +expression : OpTable -> Parser s Expression expression ops = - rec <| \() -> + lazy <| \() -> choice [ letExpression ops , caseExpression ops , ifExpression ops @@ -189,40 +188,40 @@ op ops n = |> Maybe.withDefault (L, 9) assoc : OpTable -> String -> Assoc -assoc ops n = fst <| op ops n +assoc ops n = Tuple.first <| op ops n level : OpTable -> String -> Int -level ops n = snd <| op ops n +level ops n = Tuple.second <| op ops n hasLevel : OpTable -> Int -> (String, Expression) -> Bool hasLevel ops l (n, _) = level ops n == l -split : OpTable -> Int -> Expression -> List (String, Expression) -> Parser Expression +split : OpTable -> Int -> Expression -> List (String, Expression) -> Parser s Expression split ops l e eops = case eops of [] -> succeed e _ -> - findAssoc ops l eops `andThen` \assoc -> - Ast.Helpers.sequence (splitLevel ops l e eops) `andThen` \es -> - let ops' = List.filterMap (\x -> if hasLevel ops l x - then Just (fst x) - else Nothing) eops in - case assoc of - R -> joinR es ops' - _ -> joinL es ops' - -splitLevel : OpTable -> Int -> Expression -> List (String, Expression) -> List (Parser Expression) + findAssoc ops l eops |> andThen (\assoc -> + sequence (splitLevel ops l e eops) |> andThen (\es -> + let ops_ = List.filterMap (\x -> if hasLevel ops l x + then Just (Tuple.first x) + else Nothing) eops + in case assoc of + R -> joinR es ops_ + _ -> joinL es ops_)) + +splitLevel : OpTable -> Int -> Expression -> List (String, Expression) -> List (Parser s Expression) splitLevel ops l e eops = case break (hasLevel ops l) eops of - (lops, (_, e')::rops) -> - split ops (l + 1) e lops :: splitLevel ops l e' rops + (lops, (_, e_)::rops) -> + split ops (l + 1) e lops :: splitLevel ops l e_ rops (lops, []) -> [ split ops (l + 1) e lops ] -joinL : List Expression -> List String -> Parser Expression +joinL : List Expression -> List String -> Parser s Expression joinL es ops = case (es, ops) of ([e], []) -> @@ -232,28 +231,28 @@ joinL es ops = joinL ((BinOp (Variable [op]) a b) :: remE) remO _ -> - fail [] + fail "" -joinR : List Expression -> List String -> Parser Expression +joinR : List Expression -> List String -> Parser s Expression joinR es ops = case (es, ops) of ([e], []) -> succeed e (a::b::remE, op::remO) -> - joinR (b::remE) remO `andThen` \e -> - succeed (BinOp (Variable [op]) a e) + joinR (b::remE) remO |> andThen (\e -> + succeed (BinOp (Variable [op]) a e)) _ -> - fail [] + fail "" -findAssoc : OpTable -> Int -> List (String, Expression) -> Parser Assoc +findAssoc : OpTable -> Int -> List (String, Expression) -> Parser s Assoc findAssoc ops l eops = let lops = List.filter (hasLevel ops l) eops - assocs = List.map (assoc ops << fst) lops + assocs = List.map (assoc ops << Tuple.first) lops error issue = - let operators = List.map fst lops |> String.join " and " in + let operators = List.map Tuple.first lops |> String.join " and " in "conflicting " ++ issue ++ " for operators " ++ operators in if List.all ((==) L) assocs then @@ -263,6 +262,6 @@ findAssoc ops l eops = else if List.all ((==) N) assocs then case assocs of [_] -> succeed N - _ -> fail [ error "precedence" ] + _ -> fail <| error "precedence" else - fail [ error "associativity" ] + fail <| error "associativity" diff --git a/src/Ast/Helpers.elm b/src/Ast/Helpers.elm index 0aa5807..c19a6ce 100644 --- a/src/Ast/Helpers.elm +++ b/src/Ast/Helpers.elm @@ -2,7 +2,6 @@ module Ast.Helpers exposing (..) import Combine exposing (..) import Combine.Char exposing (..) -import Combine.Infix exposing (..) import String type alias Name = String @@ -10,25 +9,6 @@ type alias QualifiedType = List Name type alias ModuleName = List String type alias Alias = String -sequence : List (Parser res) -> Parser (List res) -sequence ps = - let - accumulate acc ps cx = - case ps of - [] -> - (Ok (List.reverse acc), cx) - - p::ps -> - case app p cx of - (Ok res, rcx) -> - accumulate (res :: acc) ps rcx - - (Err ms, ecx) -> - (Err ms, ecx) - in - primitive <| \cx -> - accumulate [] ps cx - reserved : List Name reserved = [ "module", "where" , "import", "as", "exposing" @@ -40,68 +20,65 @@ reserved = [ "module", "where" reservedOperators : List Name reservedOperators = [ "=", ".", "..", "->", "--", "|", ":" ] -between' : Parser a -> Parser res -> Parser res -between' p = between p p - -whitespace : Parser String -whitespace = regex "[ \r\t\n]*" +between_ : Parser s a -> Parser s res -> Parser s res +between_ p = between p p -spaces : Parser String +spaces : Parser s String spaces = regex "[ \t]*" -spaces' : Parser String -spaces' = regex "[ \t]+" +spaces_ : Parser s String +spaces_ = regex "[ \t]+" -symbol : String -> Parser String +symbol : String -> Parser s String symbol k = - between' whitespace (string k) + between_ whitespace (string k) -initialSymbol : String -> Parser String +initialSymbol : String -> Parser s String initialSymbol k = string k <* spaces -commaSeparated : Parser res -> Parser (List res) +commaSeparated : Parser s res -> Parser s (List res) commaSeparated p = - sepBy1 (string ",") (between' whitespace p) + sepBy1 (string ",") (between_ whitespace p) -commaSeparated' : Parser res -> Parser (List res) -commaSeparated' p = - sepBy (string ",") (between' whitespace p) +commaSeparated_ : Parser s res -> Parser s (List res) +commaSeparated_ p = + sepBy (string ",") (between_ whitespace p) -name : Parser Char -> Parser String +name : Parser s Char -> Parser s String name p = String.cons <$> p <*> regex "[a-zA-Z0-9-_']*" -loName : Parser String +loName : Parser s String loName = let - loName' = - name lower - `andThen` \n -> + loName_ = + name lower |> + andThen (\n -> if List.member n reserved - then fail [ "name '" ++ n ++ "' is reserved" ] - else succeed n + then fail <| "name '" ++ n ++ "' is reserved" + else succeed n) in - string "_" <|> loName' + string "_" <|> loName_ -upName : Parser String +upName : Parser s String upName = name upper -operator : Parser String +operator : Parser s String operator = - between' (string "`") loName <|> symbolicOperator + between_ (string "`") loName <|> symbolicOperator -symbolicOperator : Parser String +symbolicOperator : Parser s String symbolicOperator = - regex "[+-/*=.$<>:&|^?%#@~!]+" - `andThen` \n -> + regex "[+-/*=.$<>:&|^?%#@~!]+" |> + andThen (\n -> if List.member n reservedOperators - then fail [ "operator '" ++ n ++ "' is reserved" ] - else succeed n + then fail <| "operator '" ++ n ++ "' is reserved" + else succeed n) -functionName : Parser String +functionName : Parser s String functionName = loName -moduleName : Parser ModuleName +moduleName : Parser s ModuleName moduleName = - between' spaces <| sepBy1 (string ".") upName + between_ spaces <| sepBy1 (string ".") upName diff --git a/src/Ast/Statement.elm b/src/Ast/Statement.elm index 1210e9e..601cc8a 100644 --- a/src/Ast/Statement.elm +++ b/src/Ast/Statement.elm @@ -19,7 +19,6 @@ module Ast.Statement exposing import Combine exposing (..) import Combine.Char exposing (..) -import Combine.Infix exposing (..) import Combine.Num import Dict import String @@ -61,85 +60,85 @@ type Statement -- Exports -- ------- -allExport : Parser ExportSet +allExport : Parser s ExportSet allExport = AllExport <$ symbol ".." -functionExport : Parser ExportSet +functionExport : Parser s ExportSet functionExport = FunctionExport <$> functionName -constructorSubsetExports : Parser ExportSet +constructorSubsetExports : Parser s ExportSet constructorSubsetExports = SubsetExport <$> commaSeparated (FunctionExport <$> upName) -constructorExports : Parser (Maybe ExportSet) +constructorExports : Parser s (Maybe ExportSet) constructorExports = maybe <| parens <| choice [ allExport , constructorSubsetExports ] -typeExport : Parser ExportSet +typeExport : Parser s ExportSet typeExport = TypeExport <$> (upName <* spaces) <*> constructorExports -subsetExport : Parser ExportSet +subsetExport : Parser s ExportSet subsetExport = SubsetExport - <$> commaSeparated (functionExport `or` typeExport) + <$> commaSeparated (functionExport |> or typeExport) -exports : Parser ExportSet +exports : Parser s ExportSet exports = parens <| choice [ allExport, subsetExport ] -- Types -- ----- -typeVariable : Parser Type +typeVariable : Parser s Type typeVariable = TypeVariable <$> regex "[a-z]+" -typeConstant : Parser Type +typeConstant : Parser s Type typeConstant = TypeConstructor <$> sepBy1 (string ".") upName <*> succeed [] -typeApplication : Parser (Type -> Type -> Type) +typeApplication : Parser s (Type -> Type -> Type) typeApplication = TypeApplication <$ symbol "->" -typeTuple : Parser Type +typeTuple : Parser s Type typeTuple = - rec <| \() -> - TypeTuple <$> parens (commaSeparated' type') + lazy <| \() -> + TypeTuple <$> parens (commaSeparated_ type_) -typeRecordPair : Parser (Name, Type) +typeRecordPair : Parser s (Name, Type) typeRecordPair = - rec <| \() -> + lazy <| \() -> (,) <$> (loName <* symbol ":") <*> typeAnnotation -typeRecordPairs : Parser (List (Name, Type)) +typeRecordPairs : Parser s (List (Name, Type)) typeRecordPairs = - rec <| \() -> - commaSeparated' typeRecordPair + lazy <| \() -> + commaSeparated_ typeRecordPair -typeRecordConstructor : Parser Type +typeRecordConstructor : Parser s Type typeRecordConstructor = - rec <| \() -> + lazy <| \() -> braces <| TypeRecordConstructor - <$> (between' spaces typeVariable) + <$> (between_ spaces typeVariable) <*> (symbol "|" *> typeRecordPairs) -typeRecord : Parser Type +typeRecord : Parser s Type typeRecord = - rec <| \() -> + lazy <| \() -> braces <| TypeRecord <$> typeRecordPairs -typeParameter : Parser Type +typeParameter : Parser s Type typeParameter = - rec <| \() -> - between' spaces <| choice [ typeVariable + lazy <| \() -> + between_ spaces <| choice [ typeVariable , typeConstant , typeRecordConstructor , typeRecord @@ -147,15 +146,15 @@ typeParameter = , parens typeAnnotation ] -typeConstructor : Parser Type +typeConstructor : Parser s Type typeConstructor = - rec <| \() -> + lazy <| \() -> TypeConstructor <$> sepBy1 (string ".") upName <*> many typeParameter -type' : Parser Type -type' = - rec <| \() -> - between' spaces <| choice [ typeConstructor +type_ : Parser s Type +type_ = + lazy <| \() -> + between_ spaces <| choice [ typeConstructor , typeVariable , typeRecordConstructor , typeRecord @@ -163,21 +162,21 @@ type' = , parens typeAnnotation ] -typeAnnotation : Parser Type +typeAnnotation : Parser s Type typeAnnotation = - rec <| \() -> - type' `chainr` typeApplication + lazy <| \() -> + type_ |> chainr typeApplication -- Modules -- ------- -portModuleDeclaration : Parser Statement +portModuleDeclaration : Parser s Statement portModuleDeclaration = PortModuleDeclaration <$> (initialSymbol "port" *> symbol "module" *> moduleName) <*> (symbol "exposing" *> exports) -moduleDeclaration : Parser Statement +moduleDeclaration : Parser s Statement moduleDeclaration = ModuleDeclaration <$> (initialSymbol "module" *> moduleName) @@ -186,7 +185,7 @@ moduleDeclaration = -- Imports -- ------- -importStatement : Parser Statement +importStatement : Parser s Statement importStatement = ImportStatement <$> (initialSymbol "import" *> moduleName) @@ -196,53 +195,53 @@ importStatement = -- Type declarations -- ----------------- -typeAliasDeclaration : Parser Statement +typeAliasDeclaration : Parser s Statement typeAliasDeclaration = TypeAliasDeclaration - <$> (initialSymbol "type" *> symbol "alias" *> type') + <$> (initialSymbol "type" *> symbol "alias" *> type_) <*> (whitespace *> symbol "=" *> typeAnnotation) -typeDeclaration : Parser Statement +typeDeclaration : Parser s Statement typeDeclaration = TypeDeclaration - <$> (initialSymbol "type" *> type') - <*> (whitespace *> symbol "=" *> (sepBy1 (symbol "|") (between' whitespace typeConstructor))) + <$> (initialSymbol "type" *> type_) + <*> (whitespace *> symbol "=" *> (sepBy1 (symbol "|") (between_ whitespace typeConstructor))) -- Ports -- ----- -portTypeDeclaration : Parser Statement +portTypeDeclaration : Parser s Statement portTypeDeclaration = PortTypeDeclaration <$> (initialSymbol "port" *> loName) <*> (symbol ":" *> typeAnnotation) -portDeclaration : OpTable -> Parser Statement +portDeclaration : OpTable -> Parser s Statement portDeclaration ops = PortDeclaration <$> (initialSymbol "port" *> loName) - <*> (many <| between' spaces loName) + <*> (many <| between_ spaces loName) <*> (symbol "=" *> expression ops) -- Functions -- --------- -functionTypeDeclaration : Parser Statement +functionTypeDeclaration : Parser s Statement functionTypeDeclaration = FunctionTypeDeclaration <$> (loName <* symbol ":") <*> typeAnnotation -functionDeclaration : OpTable -> Parser Statement +functionDeclaration : OpTable -> Parser s Statement functionDeclaration ops = FunctionDeclaration <$> loName - <*> (many (between' whitespace loName)) + <*> (many (between_ whitespace loName)) <*> (symbol "=" *> whitespace *> expression ops) -- Infix declarations -- ------------------ -infixDeclaration : Parser Statement +infixDeclaration : Parser s Statement infixDeclaration = InfixDeclaration <$> choice [ L <$ initialSymbol "infixl" @@ -255,21 +254,21 @@ infixDeclaration = -- Comments -- -------- -singleLineComment : Parser Statement +singleLineComment : Parser s Statement singleLineComment = Comment <$> (string "--" *> regex ".*" <* whitespace) -multiLineComment : Parser Statement +multiLineComment : Parser s Statement multiLineComment = (Comment << String.fromList) <$> (string "{-" *> manyTill anyChar (string "-}")) -comment : Parser Statement +comment : Parser s Statement comment = singleLineComment <|> multiLineComment {-| A parser for stand-alone Elm statements. -} -statement : OpTable -> Parser Statement +statement : OpTable -> Parser s Statement statement ops = choice [ portModuleDeclaration , moduleDeclaration @@ -285,14 +284,14 @@ statement ops = ] {-| A parser for a series of Elm statements. -} -statements : OpTable -> Parser (List Statement) +statements : OpTable -> Parser s (List Statement) statements ops = manyTill (whitespace *> statement ops <* whitespace) end {-| A scanner for infix statements. This is useful for performing a first pass over a module to find all of the infix declarations in it. -} -infixStatements : Parser (List Statement) +infixStatements : Parser s (List Statement) infixStatements = let statements = @@ -300,12 +299,12 @@ infixStatements = , Nothing <$ regex ".*" ] <* whitespace ) <* end in - statements `andThen` \xs -> - succeed <| List.filterMap identity xs + statements |> andThen (\xs -> + succeed <| List.filterMap identity xs) {-| A scanner that returns an updated OpTable based on the infix declarations in the input. -} -opTable : OpTable -> Parser OpTable +opTable : OpTable -> Parser s OpTable opTable ops = let collect s d = @@ -316,5 +315,5 @@ opTable ops = _ -> Debug.crash "impossible" in - infixStatements `andThen` \xs -> - succeed <| List.foldr collect ops xs + infixStatements |> andThen (\xs -> + succeed <| List.foldr collect ops xs) diff --git a/tests/Expression.elm b/tests/Expression.elm index ed04965..edf220d 100644 --- a/tests/Expression.elm +++ b/tests/Expression.elm @@ -8,19 +8,19 @@ import String import Test exposing (describe, test, Test) -is : String -> Expression -> Expectation -is s e = - case parseExpression operators (String.trim s) of - (Ok r, _) -> +is : Expression -> String -> Expectation +is e i = + case parseExpression operators (String.trim i) of + (Ok (_, _, r)) -> Expect.equal e r - (Err es, {position}) -> - Expect.fail ("failed to parse: " ++ s ++ " at position " ++ toString position ++ " with errors: " ++ toString es) + (Err (_, { position }, es)) -> + Expect.fail ("failed to parse: " ++ i ++ " at position " ++ toString position ++ " with errors: " ++ toString es) fails : String -> Expectation fails s = case parseExpression operators s of - (Err _, _) -> + (Err _) -> Expect.pass _ -> @@ -30,10 +30,10 @@ characterLiterals : Test characterLiterals = describe "Character literals" [ test "character literal" <| - \() -> "'a'" `is` Character 'a' + \() -> "'a'" |> is (Character 'a') , test "newline literal" <| - \() -> "'\n'" `is` Character '\n' + \() -> "'\n'" |> is (Character '\n') , test "character literals must contain one character" <| \() -> fails "''" @@ -43,45 +43,45 @@ intLiterals : Test intLiterals = describe "Integer literals" [ test "integer literal" <| - \() -> "0" `is` Integer 0 + \() -> "0" |> is (Integer 0) , test "positive literal" <| - \() -> "+12" `is` Integer 12 + \() -> "+12" |> is (Integer 12) , test "negative literal" <| - \() -> "-12" `is` Integer -12 + \() -> "-12" |> is (Integer -12) ] floatLiterals : Test floatLiterals = describe "Float literals" [ test "float literal" <| - \() -> "0.5" `is` Float 0.5 + \() -> "0.5" |> is (Float 0.5) , test "positive literal" <| - \() -> "+12.5" `is` Float 12.5 + \() -> "+12.5" |> is (Float 12.5) , test "negative literal" <| - \() -> "-12.5" `is` Float -12.5 + \() -> "-12.5" |> is (Float -12.5) ] stringLiterals : Test stringLiterals = describe "String literals" [ test "empty string" <| - \() -> "\"\"" `is` String "" + \() -> "\"\"" |> is (String "") , test "simple string" <| - \() -> "\"hello\"" `is` String "hello" + \() -> "\"hello\"" |> is (String "hello") , test "escaped string" <| - \() -> "\"hello, \\\"world\\\"\"" `is` String "hello, \\\"world\\\"" + \() -> "\"hello, \\\"world\\\"\"" |> is (String "hello, \\\"world\\\"") , test "triple-quoted string" <| - \() -> "\"\"\"\"\"\"" `is` String "" + \() -> "\"\"\"\"\"\"" |> is (String "") , test "multi-line strings" <| - \() -> "\"\"\"hello\nworld\"\"\"" `is` String "hello\nworld" + \() -> "\"\"\"hello\nworld\"\"\"" |> is (String "hello\nworld") ] literals : Test @@ -97,14 +97,14 @@ letExpressions : Test letExpressions = describe "Let" [ test "single binding" <| - \() -> "let a = 42 in a" `is` (Let + \() -> "let a = 42 in a" |> is ((Let [("a", Integer 42)] - (Variable ["a"])) + (Variable ["a"]))) , test "bind to _" <| - \() -> "let _ = 42 in 24" `is` (Let + \() -> "let _ = 42 in 24" |> is ((Let [("_", Integer 42)] - (Integer 24)) + (Integer 24))) , test "multiple bindings" <| \() -> """ @@ -114,11 +114,11 @@ let b = a + 1 in b - """ `is` (Let + """ |> is ((Let [ ("a", Integer 42) , ("b", (BinOp (Variable ["+"]) (Variable ["a"]) (Integer 1))) ] - (Variable ["b"])) + (Variable ["b"]))) ] caseExpressions : Test @@ -133,11 +133,11 @@ case x of Just y -> y - """ `is` (Case + """ |> is ((Case (Variable ["x"]) [ (Variable ["Nothing"], Integer 0) , (Application (Variable ["Just"]) (Variable ["y"]), (Variable ["y"])) - ]) + ])) , test "binding to underscore" <| \() -> @@ -145,32 +145,32 @@ case x of case x of _ -> 42 - """ `is` (Case + """ |> is ((Case (Variable ["x"]) - [(Variable ["_"], Integer 42)]) + [(Variable ["_"], Integer 42)])) ] application : Test application = describe "Application" [ test "simple application" <| - \() -> "f a" `is` (Application + \() -> "f a" |> is ((Application (Variable ["f"]) - (Variable ["a"])) + (Variable ["a"]))) , test "curried application" <| - \() -> "f a b" `is` (Application + \() -> "f a b" |> is ((Application (Application (Variable ["f"]) (Variable ["a"])) - (Variable ["b"])) + (Variable ["b"]))) , test "constructor application" <| - \() -> "Cons a Nil" `is` (Application + \() -> "Cons a Nil" |> is ((Application (Application (Variable ["Cons"]) (Variable ["a"])) - (Variable ["Nil"])) + (Variable ["Nil"]))) ] diff --git a/tests/Main.elm b/tests/Main.elm index 9732939..4347d17 100644 --- a/tests/Main.elm +++ b/tests/Main.elm @@ -7,7 +7,7 @@ import Json.Encode exposing (Value) import Expression import Statement -main : Program Value +main : Test.Runner.Node.TestProgram main = run emit all diff --git a/tests/Statement.elm b/tests/Statement.elm index 611d161..7a9b302 100644 --- a/tests/Statement.elm +++ b/tests/Statement.elm @@ -7,19 +7,19 @@ import Ast.Statement exposing (ExportSet(..), Type(..), Statement(..)) import Expect exposing (..) import Test exposing (describe, test, Test) -is : String -> Statement -> Expectation -is i s = +is : Statement -> String -> Expectation +is s i = case parseStatement operators i of - (Ok r, _) -> + (Ok (_, _, r)) -> Expect.equal r s _ -> Expect.fail ("failed to parse: \"" ++ i ++ "\" " ++ toString s) -are : String -> List Statement -> Expectation -are i s = +are : List Statement -> String -> Expectation +are s i = case parse i of - (Ok r, _) -> + (Ok (_, _, r)) -> Expect.equal r s _ -> @@ -29,28 +29,28 @@ moduleDeclaration : Test moduleDeclaration = describe "Module declaration statements" [ test "simple declaration exposing all" <| - \() -> "module A exposing (..)" `is` (ModuleDeclaration ["A"] AllExport) + \() -> "module A exposing (..)" |> is (ModuleDeclaration ["A"] AllExport) , test "declaration exposing particular things" <| \() -> "module A exposing (A, b)" - `is` (ModuleDeclaration ["A"] + |> is (ModuleDeclaration ["A"] <| SubsetExport [ TypeExport "A" Nothing , FunctionExport "b" ]) , test "declaration exposing union" <| \() -> "module A exposing (A(..))" - `is` (ModuleDeclaration ["A"] + |> is (ModuleDeclaration ["A"] <| SubsetExport [ TypeExport "A" (Just AllExport) ]) , test "declaration exposing constructor subset" <| \() -> "module A exposing (A(A))" - `is` (ModuleDeclaration ["A"] + |> is (ModuleDeclaration ["A"] <| SubsetExport [ TypeExport "A" (Just <| SubsetExport [ FunctionExport "A" ]) ]) , test "multiline declaration" <| \() -> "module A exposing (A, B,\nc)" - `is` (ModuleDeclaration ["A"] + |> is (ModuleDeclaration ["A"] <| SubsetExport [ TypeExport "A" Nothing , TypeExport "B" Nothing , FunctionExport "c" @@ -58,7 +58,7 @@ moduleDeclaration = , test "declaration using a port" <| \() -> "port module A exposing (A(..))" - `is` (PortModuleDeclaration ["A"] + |> is (PortModuleDeclaration ["A"] <| SubsetExport [ TypeExport "A" (Just AllExport) ]) ] @@ -67,35 +67,35 @@ importStatements : Test importStatements = describe "Import statements" [ test "simple import" <| - \() -> "import A" `is` (ImportStatement ["A"] Nothing Nothing) + \() -> "import A" |> is (ImportStatement ["A"] Nothing Nothing) , test "import as" <| - \() -> "import A as B" `is` (ImportStatement ["A"] (Just "B") Nothing) + \() -> "import A as B" |> is (ImportStatement ["A"] (Just "B") Nothing) , test "import exposing all" <| \() -> "import A exposing (..)" - `is` (ImportStatement ["A"] Nothing (Just AllExport)) + |> is (ImportStatement ["A"] Nothing (Just AllExport)) , test "import exposing" <| \() -> "import A exposing (A, b)" - `is` (ImportStatement ["A"] Nothing + |> is (ImportStatement ["A"] Nothing <| Just <| SubsetExport [ TypeExport "A" Nothing , FunctionExport "b" ]) , test "import exposing union" <| \() -> "import A exposing (A(..))" - `is` (ImportStatement ["A"] Nothing + |> is (ImportStatement ["A"] Nothing <| Just <| SubsetExport [ TypeExport "A" (Just AllExport) ]) , test "import exposing constructor subset" <| \() -> "import A exposing (A(A))" - `is` (ImportStatement ["A"] Nothing + |> is (ImportStatement ["A"] Nothing <| Just <| SubsetExport [ TypeExport "A" (Just <| SubsetExport [ FunctionExport "A" ]) ]) , test "import multiline" <| \() -> "import A as B exposing (A, B,\nc)" - `is` (ImportStatement ["A"] (Just "B") + |> is (ImportStatement ["A"] (Just "B") <| Just <| SubsetExport [ TypeExport "A" Nothing , TypeExport "B" Nothing , FunctionExport "c" @@ -107,21 +107,21 @@ typeAnnotations = describe "Type annotations" [ test "constant" <| \() -> "x : Int" - `is` (FunctionTypeDeclaration "x" (TypeConstructor ["Int"] [])) + |> is (FunctionTypeDeclaration "x" (TypeConstructor ["Int"] [])) , test "variables" <| \() -> "x : a" - `is` (FunctionTypeDeclaration "x" (TypeVariable "a")) + |> is (FunctionTypeDeclaration "x" (TypeVariable "a")) , test "application" <| \() -> "x : a -> b" - `is` (FunctionTypeDeclaration "x" (TypeApplication + |> is (FunctionTypeDeclaration "x" (TypeApplication (TypeVariable "a") (TypeVariable "b"))) , test "application associativity" <| \() -> "x : a -> b -> c" - `is` (FunctionTypeDeclaration "x" (TypeApplication + |> is (FunctionTypeDeclaration "x" (TypeApplication (TypeVariable "a") (TypeApplication (TypeVariable "b") @@ -129,7 +129,7 @@ typeAnnotations = , test "application parens" <| \() -> "x : (a -> b) -> c" - `is` (FunctionTypeDeclaration "x" (TypeApplication + |> is (FunctionTypeDeclaration "x" (TypeApplication (TypeApplication (TypeVariable "a") (TypeVariable "b")) @@ -137,7 +137,7 @@ typeAnnotations = , test "qualified types" <| \() -> "m : Html.App Msg" - `is` (FunctionTypeDeclaration "m" (TypeConstructor + |> is (FunctionTypeDeclaration "m" (TypeConstructor ["Html", "App"] [(TypeConstructor ["Msg"] [])])) ] @@ -147,14 +147,14 @@ portStatements = describe "port type declaration" [ test "constant" <| \() -> "port focus : String -> Cmd msg" - `is` (PortTypeDeclaration "focus" (TypeApplication + |> is (PortTypeDeclaration "focus" (TypeApplication (TypeConstructor ["String"] []) (TypeConstructor ["Cmd"] ([TypeVariable "msg"])))) , test "another port type declaration" <| \() -> "port users : (User -> msg) -> Sub msg" - `is` (PortTypeDeclaration "users" (TypeApplication + |> is (PortTypeDeclaration "users" (TypeApplication (TypeApplication (TypeConstructor ["User"] []) (TypeVariable "msg")) @@ -163,7 +163,7 @@ portStatements = , test "port definition" <| \() -> "port focus = Cmd.none" - `is` (PortDeclaration "focus" [] (Access + |> is (PortDeclaration "focus" [] (Access (Variable ["Cmd"]) ["none"])) ] @@ -173,15 +173,15 @@ infixDeclarations = describe "Infix declarations" [ test "non" <| \() -> "infix 9 :-" - `is` (InfixDeclaration N 9 ":-") + |> is (InfixDeclaration N 9 ":-") , test "left" <| \() -> "infixl 9 :-" - `is` (InfixDeclaration L 9 ":-") + |> is (InfixDeclaration L 9 ":-") , test "right" <| \() -> "infixr 9 :-" - `is` (InfixDeclaration R 9 ":-") + |> is (InfixDeclaration R 9 ":-") ] singleDeclarationInput : String @@ -194,7 +194,7 @@ f x = singleDeclaration : Test singleDeclaration = test "simple function" <| - \() -> singleDeclarationInput `are` + \() -> singleDeclarationInput |> are [ FunctionTypeDeclaration "f" (TypeApplication (TypeConstructor ["Int"] []) (TypeConstructor ["Int"] [])) @@ -218,7 +218,7 @@ g x = multipleDeclarations : Test multipleDeclarations = test "multiple functions" <| - \() -> multipleDeclarationsInput `are` + \() -> multipleDeclarationsInput |> are [ FunctionTypeDeclaration "f" (TypeApplication (TypeConstructor ["Int"] []) (TypeConstructor ["Int"] [])) @@ -251,7 +251,7 @@ infixr 1 ** moduleFixityDeclarations : Test moduleFixityDeclarations = test "module fixity scanning" <| - \() -> moduleFixityInput `are` + \() -> moduleFixityInput |> are [ FunctionDeclaration "f" [] (BinOp (Variable ["++"]) (BinOp @@ -286,11 +286,11 @@ typeDeclarations = describe "type declarations" [ test "can parse empty record aliases" <| \() -> - emptyRecordAliasInput `are` [TypeAliasDeclaration (TypeConstructor ["A"] []) (TypeRecord [])] + emptyRecordAliasInput |> are [TypeAliasDeclaration (TypeConstructor ["A"] []) (TypeRecord [])] , test "can parse aliases of unit" <| \() -> - emptyTupleAliasInput `are` [TypeAliasDeclaration (TypeConstructor ["A"] []) (TypeTuple [])] + emptyTupleAliasInput |> are [TypeAliasDeclaration (TypeConstructor ["A"] []) (TypeTuple [])] ] diff --git a/tests/elm-package.json b/tests/elm-package.json index b8d4c0c..b2cbe55 100644 --- a/tests/elm-package.json +++ b/tests/elm-package.json @@ -1,6 +1,6 @@ { - "version": "1.0.0", - "summary": "helpful summary of your project, less than 80 characters", + "version": "2.0.0", + "summary": "test suite for elm-ast", "repository": "https://github.com/user/project.git", "license": "BSD3", "source-directories": [ @@ -9,11 +9,11 @@ ], "exposed-modules": [], "dependencies": { - "elm-lang/core": "4.0.5 <= v < 5.0.0", - "elm-community/elm-test": "2.1.0 <= v < 3.0.0", - "rtfeldman/node-test-runner": "2.0.0 <= v < 3.0.0", - "Bogdanp/elm-combine": "2.1.0 <= v < 3.0.0", - "elm-community/list-extra": "3.1.0 <= v < 4.0.0" + "elm-lang/core": "5.0.0 <= v < 6.0.0", + "elm-community/elm-test": "3.1.0 <= v < 4.0.0", + "rtfeldman/node-test-runner": "3.0.0 <= v < 4.0.0", + "Bogdanp/elm-combine": "3.1.0 <= v < 4.0.0", + "elm-community/list-extra": "5.0.0 <= v < 6.0.0" }, - "elm-version": "0.17.1 <= v < 0.18.0" + "elm-version": "0.18.0 <= v < 0.19.0" } From af087c86e4376b81fa34c316633ead8353ee02ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Sun, 25 Dec 2016 23:50:29 +0100 Subject: [PATCH 02/10] update parser with 0.18 language changes --- src/Ast/Expression.elm | 11 +---------- src/Ast/Helpers.elm | 6 +----- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/src/Ast/Expression.elm b/src/Ast/Expression.elm index 62f25fb..abf57b4 100644 --- a/src/Ast/Expression.elm +++ b/src/Ast/Expression.elm @@ -33,7 +33,6 @@ type Expression | Integer Int | Float Float | Variable (List Name) - | Range Expression Expression | List (List Expression) | Access Expression (List Name) | Record (List (Name, Expression)) @@ -80,14 +79,6 @@ variable = , sepBy1 (Combine.string "." ) upName ] -range : OpTable -> Parser s Expression -range ops = - lazy <| \() -> - brackets - <| Range - <$> (expression ops) - <*> (symbol ".." *> expression ops) - list : OpTable -> Parser s Expression list ops = lazy <| \() -> @@ -167,7 +158,7 @@ term : OpTable -> Parser s Expression term ops = lazy <| \() -> choice [ character, string, float, integer, access, variable - , range ops, list ops, record ops + , list ops, record ops , parens (expression ops) ] diff --git a/src/Ast/Helpers.elm b/src/Ast/Helpers.elm index c19a6ce..f62ab02 100644 --- a/src/Ast/Helpers.elm +++ b/src/Ast/Helpers.elm @@ -47,7 +47,7 @@ commaSeparated_ p = name : Parser s Char -> Parser s String name p = - String.cons <$> p <*> regex "[a-zA-Z0-9-_']*" + String.cons <$> p <*> regex "[a-zA-Z0-9-_]*" loName : Parser s String loName = @@ -66,10 +66,6 @@ upName = name upper operator : Parser s String operator = - between_ (string "`") loName <|> symbolicOperator - -symbolicOperator : Parser s String -symbolicOperator = regex "[+-/*=.$<>:&|^?%#@~!]+" |> andThen (\n -> if List.member n reservedOperators From 3a2fdc8fd4fcb332179bf84cd86b4d15316b1169 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Mon, 26 Dec 2016 00:05:43 +0100 Subject: [PATCH 03/10] fix example --- example/Main.elm | 6 ------ 1 file changed, 6 deletions(-) diff --git a/example/Main.elm b/example/Main.elm index 30c97c2..78231d0 100644 --- a/example/Main.elm +++ b/example/Main.elm @@ -45,12 +45,6 @@ withChild title children = expression : Expression -> Html Msg expression e = case e of - Range e1 e2 -> - withChild e - [ expression e1 - , expression e2 - ] - List es -> withChild e (List.map expression es) From 93eaf4aa8a7d93b188ddbc9d43a04dd7fe10bea8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Tue, 3 Jan 2017 00:27:56 +0100 Subject: [PATCH 04/10] publish v1.0.0 --- elm-package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/elm-package.json b/elm-package.json index 3d170f6..f69db74 100644 --- a/elm-package.json +++ b/elm-package.json @@ -1,7 +1,7 @@ { - "version": "2.0.0", + "version": "1.0.0", "summary": "A parser for Elm code", - "repository": "https://github.com/Bogdanp/elm-ast.git", + "repository": "https://github.com/brainrape/elm-ast.git", "license": "BSD3", "source-directories": [ "src", @@ -14,9 +14,9 @@ "Ast.Statement" ], "dependencies": { - "elm-lang/core": "5.0.0 <= v < 6.0.0", "Bogdanp/elm-combine": "3.1.1 <= v < 4.0.0", - "elm-community/list-extra": "5.0.0 <= v < 6.0.0" + "elm-community/list-extra": "5.0.0 <= v < 6.0.0", + "elm-lang/core": "5.0.0 <= v < 6.0.0" }, "elm-version": "0.18.0 <= v < 0.19.0" } From ce653fb3c249d35ea2552229608777381441317d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Tue, 3 Jan 2017 00:30:04 +0100 Subject: [PATCH 05/10] release 1.0.1 --- elm-package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elm-package.json b/elm-package.json index f69db74..1ace7eb 100644 --- a/elm-package.json +++ b/elm-package.json @@ -1,5 +1,5 @@ { - "version": "1.0.0", + "version": "1.0.1", "summary": "A parser for Elm code", "repository": "https://github.com/brainrape/elm-ast.git", "license": "BSD3", From f770c2e2c47c8e75845e6d6ea565428a26e5d170 Mon Sep 17 00:00:00 2001 From: Krzysztof Wende Date: Sun, 16 Apr 2017 02:43:13 +0200 Subject: [PATCH 06/10] formatted tuple works --- src/Ast/Expression.elm | 9 ++++++++- tests/Expression.elm | 26 ++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/Ast/Expression.elm b/src/Ast/Expression.elm index abf57b4..1d33194 100644 --- a/src/Ast/Expression.elm +++ b/src/Ast/Expression.elm @@ -36,6 +36,7 @@ type Expression | List (List Expression) | Access Expression (List Name) | Record (List (Name, Expression)) + | Tuple (List (Expression)) | RecordUpdate Name (List (Name, Expression)) | If Expression Expression Expression | Let (List (Name, Expression)) Expression @@ -89,6 +90,12 @@ record ops = lazy <| \() -> Record <$> braces (commaSeparated_ ((,) <$> loName <*> (symbol "=" *> expression ops))) +tuple : OpTable -> Parser s Expression +tuple ops = + lazy <| \() -> + Tuple <$> parens (commaSeparated (expression ops)) + + letExpression : OpTable -> Parser s Expression letExpression ops = let @@ -159,7 +166,7 @@ term ops = lazy <| \() -> choice [ character, string, float, integer, access, variable , list ops, record ops - , parens (expression ops) + , parens ( between_ whitespace (expression ops)) ] {-| A parser for Elm expressions. -} diff --git a/tests/Expression.elm b/tests/Expression.elm index edf220d..7ff2291 100644 --- a/tests/Expression.elm +++ b/tests/Expression.elm @@ -165,6 +165,13 @@ application = (Variable ["a"])) (Variable ["b"]))) + , test "curried application with parens" <| + \() -> "(f a) b" |> is ((Application + (Application + (Variable ["f"]) + (Variable ["a"])) + (Variable ["b"]))) + , test "constructor application" <| \() -> "Cons a Nil" |> is ((Application (Application @@ -173,6 +180,24 @@ application = (Variable ["Nil"]))) ] +tuple : Test +tuple = + describe "Tuples" + [ test "Simple tuple" <| + \() -> "(a, b)" |> is (BinOp + (Variable [","]) + (Variable ["a"]) + (Variable ["b"]) + ) + , test "Simple tuple with format" <| + \() -> "( a, b )" |> is (BinOp + (Variable [","]) + (Variable ["a"]) + (Variable ["b"]) + ) + + ] + all : Test all = @@ -181,4 +206,5 @@ all = , letExpressions , caseExpressions , application + , tuple ] From 46b62be09ad1ecf0f4c137167d0e33e8ce1c1f2e Mon Sep 17 00:00:00 2001 From: Krzysztof Wende Date: Sun, 16 Apr 2017 02:45:10 +0200 Subject: [PATCH 07/10] no tuple special ast --- src/Ast/Expression.elm | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/Ast/Expression.elm b/src/Ast/Expression.elm index 1d33194..f2307a6 100644 --- a/src/Ast/Expression.elm +++ b/src/Ast/Expression.elm @@ -36,7 +36,6 @@ type Expression | List (List Expression) | Access Expression (List Name) | Record (List (Name, Expression)) - | Tuple (List (Expression)) | RecordUpdate Name (List (Name, Expression)) | If Expression Expression Expression | Let (List (Name, Expression)) Expression @@ -90,12 +89,6 @@ record ops = lazy <| \() -> Record <$> braces (commaSeparated_ ((,) <$> loName <*> (symbol "=" *> expression ops))) -tuple : OpTable -> Parser s Expression -tuple ops = - lazy <| \() -> - Tuple <$> parens (commaSeparated (expression ops)) - - letExpression : OpTable -> Parser s Expression letExpression ops = let From d417c1178d96b292d660d346e5fecc2c649bb4a8 Mon Sep 17 00:00:00 2001 From: Krzysztof Wende Date: Sun, 16 Apr 2017 03:52:40 +0200 Subject: [PATCH 08/10] multi field records and record update --- src/Ast/Expression.elm | 14 ++++++++++++-- tests/Expression.elm | 22 ++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/Ast/Expression.elm b/src/Ast/Expression.elm index f2307a6..4982b39 100644 --- a/src/Ast/Expression.elm +++ b/src/Ast/Expression.elm @@ -87,7 +87,17 @@ list ops = record : OpTable -> Parser s Expression record ops = lazy <| \() -> - Record <$> braces (commaSeparated_ ((,) <$> loName <*> (symbol "=" *> expression ops))) + Record <$> braces (commaSeparated_ ((,) <$> loName <*> (symbol "=" *> term ops))) + +recordUpdate : OpTable -> Parser s Expression +recordUpdate ops = + lazy <| \() -> + RecordUpdate + <$> (symbol "{" *> loName) + <*> (symbol "|" *> (commaSeparated_ ((,) <$> loName <*> (symbol "=" *> term ops))) + <* symbol "}") + + letExpression : OpTable -> Parser s Expression letExpression ops = @@ -158,7 +168,7 @@ term : OpTable -> Parser s Expression term ops = lazy <| \() -> choice [ character, string, float, integer, access, variable - , list ops, record ops + , list ops, recordUpdate ops, record ops , parens ( between_ whitespace (expression ops)) ] diff --git a/tests/Expression.elm b/tests/Expression.elm index 7ff2291..c3a8463 100644 --- a/tests/Expression.elm +++ b/tests/Expression.elm @@ -195,6 +195,27 @@ tuple = (Variable ["a"]) (Variable ["b"]) ) + ] +record : Test +record = + describe "Tuples" + [ test "Simple record" <| + \() -> "{a = b}" |> is (Record [ + ("a" , (Variable ["b"])) + ] + ) + , test "Simple record with many fields" <| + \() -> "{a = b, b = 2}" |> is (Record + [("a" , (Variable ["b"])) + , ("b" , (Integer 2)) + ] + ) + , test "Simple record with updated field" <| + \() -> "{a | b = 2}" |> is (RecordUpdate + "a" + [("b" , (Integer 2))] + ) + ] @@ -207,4 +228,5 @@ all = , caseExpressions , application , tuple + , record ] From 91d8884ac5f083ddd6256b3972281354969f3d6d Mon Sep 17 00:00:00 2001 From: Krzysztof Wende Date: Sun, 16 Apr 2017 04:00:48 +0200 Subject: [PATCH 09/10] version upgrade --- elm-package.json | 4 ++-- tests/Expression.elm | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/elm-package.json b/elm-package.json index 1ace7eb..9b8667e 100644 --- a/elm-package.json +++ b/elm-package.json @@ -1,7 +1,7 @@ { - "version": "1.0.1", + "version": "1.0.2", "summary": "A parser for Elm code", - "repository": "https://github.com/brainrape/elm-ast.git", + "repository": "https://github.com/wende/elm-ast.git", "license": "BSD3", "source-directories": [ "src", diff --git a/tests/Expression.elm b/tests/Expression.elm index c3a8463..2a674d4 100644 --- a/tests/Expression.elm +++ b/tests/Expression.elm @@ -211,10 +211,12 @@ record = ] ) , test "Simple record with updated field" <| - \() -> "{a | b = 2}" |> is (RecordUpdate - "a" - [("b" , (Integer 2))] - ) + \() -> "{a | b = 2, c = 3}" |> is (RecordUpdate + "a" + [ ("b" , (Integer 2)) + , ("c" , (Integer 3)) + ] + ) ] From 8d44631f1c0b23c909d1b2d7fe716bd45011977d Mon Sep 17 00:00:00 2001 From: Krzysztof Wende Date: Tue, 18 Apr 2017 13:54:38 +0200 Subject: [PATCH 10/10] Update elm-package.json --- elm-package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elm-package.json b/elm-package.json index 9b8667e..9ba0025 100644 --- a/elm-package.json +++ b/elm-package.json @@ -1,7 +1,7 @@ { "version": "1.0.2", "summary": "A parser for Elm code", - "repository": "https://github.com/wende/elm-ast.git", + "repository": "https://github.com/Bogdanp/elm-ast.git", "license": "BSD3", "source-directories": [ "src",