refactor repo to datalog/datalog-lsp
This commit is contained in:
parent
a42a546586
commit
be5e487e31
@ -35,7 +35,7 @@ handlers =
|
|||||||
, _tokenModifiers = []
|
, _tokenModifiers = []
|
||||||
}
|
}
|
||||||
tokens = fromRight (error "failed") $ makeSemanticTokens defaultSemanticTokensLegend [token]
|
tokens = fromRight (error "failed") $ makeSemanticTokens defaultSemanticTokensLegend [token]
|
||||||
|
c <- fromJust <$> getVirtualFile docUri
|
||||||
responder (Right $ InL tokens)
|
responder (Right $ InL tokens)
|
||||||
]
|
]
|
||||||
|
|
||||||
71
datalog/src/Datalog/Parser.hs
Normal file
71
datalog/src/Datalog/Parser.hs
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
module Datalog.Parser
|
||||||
|
( parseTerm
|
||||||
|
, parseAtom
|
||||||
|
, parseRule
|
||||||
|
, parseQuery
|
||||||
|
, parseProgram
|
||||||
|
)
|
||||||
|
where
|
||||||
|
|
||||||
|
import Datalog.Syntax
|
||||||
|
import Data.Text (Text)
|
||||||
|
import Data.Text qualified as T
|
||||||
|
import Data.Void (Void)
|
||||||
|
import Text.Megaparsec
|
||||||
|
import Text.Megaparsec.Char
|
||||||
|
import Text.Megaparsec.Char.Lexer qualified as L
|
||||||
|
|
||||||
|
type Parser = Parsec Void Text
|
||||||
|
|
||||||
|
lexeme :: (MonadParsec e Text m) => m a -> m a
|
||||||
|
lexeme = L.lexeme whitespace
|
||||||
|
|
||||||
|
symbol :: (MonadParsec e Text m) => Text -> m Text
|
||||||
|
symbol = L.symbol whitespace
|
||||||
|
|
||||||
|
whitespace :: (MonadParsec e Text m) => m ()
|
||||||
|
whitespace = L.space
|
||||||
|
space1
|
||||||
|
(L.skipLineComment "--")
|
||||||
|
(L.skipBlockComment "{-" "-}")
|
||||||
|
|
||||||
|
parens :: (MonadParsec e Text m) => m a -> m a
|
||||||
|
parens = between (symbol "(") (symbol ")")
|
||||||
|
|
||||||
|
comma, period :: (MonadParsec e Text m) => m ()
|
||||||
|
comma = () <$ symbol ","
|
||||||
|
period = () <$ symbol "."
|
||||||
|
|
||||||
|
parseCon :: (MonadParsec e Text m) => m Term
|
||||||
|
parseCon = Con . ConId . T.pack <$> lexeme (liftA2 (:) (numberChar <|> lowerChar) (many alphaNumChar))
|
||||||
|
|
||||||
|
parseVar :: (MonadParsec e Text m) => m Term
|
||||||
|
parseVar = Var . VarId . T.pack <$> lexeme (liftA2 (:) upperChar (many alphaNumChar))
|
||||||
|
|
||||||
|
parseTerm :: Parser Term
|
||||||
|
parseTerm = parseVar <|> parseCon
|
||||||
|
|
||||||
|
parseAtom :: Parser Atom
|
||||||
|
parseAtom = do
|
||||||
|
rel <- RelId . T.pack <$> lexeme (liftA2 (:) lowerChar (many alphaNumChar))
|
||||||
|
args <- parens (parseTerm `sepBy` comma)
|
||||||
|
return (Atom rel args)
|
||||||
|
|
||||||
|
parseQuery :: Parser [Atom]
|
||||||
|
parseQuery = parseAtom `sepBy` comma
|
||||||
|
|
||||||
|
parseFact :: Parser Rule
|
||||||
|
parseFact = do
|
||||||
|
headAtom <- parseAtom
|
||||||
|
period
|
||||||
|
return (headAtom :- [])
|
||||||
|
|
||||||
|
parseRule :: Parser Rule
|
||||||
|
parseRule = try parseFact <|> do
|
||||||
|
headAtom <- parseAtom <* symbol ":-"
|
||||||
|
bodyAtoms <- parseQuery
|
||||||
|
period
|
||||||
|
return (headAtom :- bodyAtoms)
|
||||||
|
|
||||||
|
parseProgram :: Parser Program
|
||||||
|
parseProgram = Program <$> many parseRule
|
||||||
86
datalog/src/Datalog/Syntax.hs
Normal file
86
datalog/src/Datalog/Syntax.hs
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
module Datalog.Syntax where
|
||||||
|
|
||||||
|
import Data.Char (isUpper)
|
||||||
|
import Data.Text (Text)
|
||||||
|
import Data.Text qualified as T
|
||||||
|
import Data.Set qualified as Set
|
||||||
|
import Data.Set (Set)
|
||||||
|
|
||||||
|
newtype ConId = ConId Text
|
||||||
|
deriving (Eq, Ord, Show)
|
||||||
|
|
||||||
|
newtype VarId = VarId Text
|
||||||
|
deriving (Eq, Ord, Show)
|
||||||
|
|
||||||
|
newtype RelId = RelId Text
|
||||||
|
deriving (Eq, Ord, Show)
|
||||||
|
|
||||||
|
data Term = Con ConId | Var VarId
|
||||||
|
deriving (Eq, Ord, Show)
|
||||||
|
|
||||||
|
con :: Text -> Term
|
||||||
|
con = Con . ConId
|
||||||
|
|
||||||
|
var :: Text -> Term
|
||||||
|
var = Var . VarId
|
||||||
|
|
||||||
|
term :: Text -> Term
|
||||||
|
term t = if not (T.null t) && isUpper (T.head t) then var t else con t
|
||||||
|
|
||||||
|
data Atom = Atom RelId [Term]
|
||||||
|
deriving (Eq, Ord, Show)
|
||||||
|
|
||||||
|
atom :: Text -> [Text] -> Atom
|
||||||
|
atom relName args = Atom (RelId relName) (map term args)
|
||||||
|
|
||||||
|
data Rule = Atom :- [Atom]
|
||||||
|
deriving (Eq, Ord, Show)
|
||||||
|
|
||||||
|
data Program = Program [Rule]
|
||||||
|
deriving (Eq, Ord, Show)
|
||||||
|
|
||||||
|
class HasConstants a where
|
||||||
|
constants :: a -> Set ConId
|
||||||
|
|
||||||
|
instance HasConstants Term where
|
||||||
|
constants t = case t of
|
||||||
|
Con x -> Set.singleton x
|
||||||
|
Var _ -> Set.empty
|
||||||
|
|
||||||
|
instance HasConstants a => HasConstants [a] where
|
||||||
|
constants xs = Set.unions (map constants xs)
|
||||||
|
|
||||||
|
instance HasConstants Atom where
|
||||||
|
constants (Atom _ ts) = constants ts
|
||||||
|
|
||||||
|
instance HasConstants Rule where
|
||||||
|
constants (h :- b) = Set.union (constants h) (constants b)
|
||||||
|
|
||||||
|
instance HasConstants Program where
|
||||||
|
constants (Program rs) = constants rs
|
||||||
|
|
||||||
|
class Pretty t where
|
||||||
|
pretty :: t -> Text
|
||||||
|
|
||||||
|
instance Pretty ConId where
|
||||||
|
pretty (ConId t) = t
|
||||||
|
|
||||||
|
instance Pretty VarId where
|
||||||
|
pretty (VarId t) = t
|
||||||
|
|
||||||
|
instance Pretty RelId where
|
||||||
|
pretty (RelId t) = t
|
||||||
|
|
||||||
|
instance Pretty Term where
|
||||||
|
pretty (Con conId) = pretty conId
|
||||||
|
pretty (Var varId) = pretty varId
|
||||||
|
|
||||||
|
instance Pretty Atom where
|
||||||
|
pretty (Atom relId terms) = pretty relId <> "(" <> T.intercalate "," (map pretty terms) <> ")"
|
||||||
|
|
||||||
|
instance Pretty Rule where
|
||||||
|
pretty (h :- []) = pretty h <> "."
|
||||||
|
pretty (h :- ts) = pretty h <> " :- " <> T.intercalate ", " (map pretty ts) <> "."
|
||||||
|
|
||||||
|
instance Pretty Program where
|
||||||
|
pretty (Program rs) = T.unlines (map pretty rs)
|
||||||
@ -18,17 +18,29 @@ common warnings
|
|||||||
common extensions
|
common extensions
|
||||||
default-extensions:
|
default-extensions:
|
||||||
OverloadedRecordDot
|
OverloadedRecordDot
|
||||||
|
OverloadedStrings
|
||||||
|
|
||||||
executable geolog-lsp
|
library datalog-parser
|
||||||
|
import: warnings, extensions
|
||||||
|
build-depends:
|
||||||
|
base,
|
||||||
|
text,
|
||||||
|
containers,
|
||||||
|
megaparsec
|
||||||
|
exposed-modules:
|
||||||
|
Datalog.Parser,
|
||||||
|
Datalog.Syntax
|
||||||
|
hs-source-dirs: datalog/src
|
||||||
|
default-language: GHC2024
|
||||||
|
|
||||||
|
executable datalog-lsp
|
||||||
import: warnings, extensions
|
import: warnings, extensions
|
||||||
main-is: Main.hs
|
main-is: Main.hs
|
||||||
-- other-modules:
|
|
||||||
-- other-extensions:
|
|
||||||
build-depends:
|
build-depends:
|
||||||
base,
|
base,
|
||||||
lsp,
|
lsp,
|
||||||
text,
|
text,
|
||||||
containers,
|
containers,
|
||||||
lens
|
lens
|
||||||
hs-source-dirs: src
|
hs-source-dirs: datalog-lsp/src
|
||||||
default-language: GHC2024
|
default-language: GHC2024
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user