diff --git a/src/Datalog.elm b/src/Datalog.elm index 3ee19b5..37c23a7 100644 --- a/src/Datalog.elm +++ b/src/Datalog.elm @@ -871,6 +871,7 @@ type Token | GreaterThanOrEquals | Equals | OrToken + | NotToken type alias Parser a = @@ -936,7 +937,16 @@ ruleBodyParser = bodyAtomParser : Parser (Rule -> Rule) bodyAtomParser = - Parser.succeed with + Parser.succeed + (\negative name body -> + if negative then + without name body + + else + with name body + ) + |= notParser + |. Parser.spaces |= nameParser |. Parser.spaces |= Parser.sequence @@ -949,6 +959,15 @@ bodyAtomParser = } +notParser : Parser Bool +notParser = + Parser.oneOf + [ Parser.succeed True + |. Parser.token notToken + , Parser.succeed False + ] + + filterParser : Parser (Rule -> Rule) filterParser = Parser.andThen @@ -1143,6 +1162,11 @@ orToken = Parser.Token "||" (ExpectedToken OrToken) +notToken : Parser.Token ParsingProblem +notToken = + Parser.Token "not" (ExpectedToken NotToken) + + {-| This is down here because my editor's highlighting is busted and it thinks everything after '"' is a string. -} diff --git a/tests/DatalogTests.elm b/tests/DatalogTests.elm index 6e50998..da216b6 100644 --- a/tests/DatalogTests.elm +++ b/tests/DatalogTests.elm @@ -534,7 +534,20 @@ datalogTests = ) ] ] - , todo "rule with negation" + , test "rule with negation" <| + \_ -> + expectParses + """ + unreachable(a, b) :- + node(a), + node(b), + not reachable(a, b). + """ + [ rule "unreachable" [ "a", "b" ] + |> with "node" [ var "a" ] + |> with "node" [ var "b" ] + |> without "reachable" [ var "a", var "b" ] + ] ] , describe "errors" [ todo "errors!" ]