diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2024-09-22 00:26:39 -0600 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2024-09-22 00:26:39 -0600 |
commit | 0d2095b5d42989639c1861d7213c182abd064672 (patch) | |
tree | e7d43320521f6bfb57d214cb949db8c8674c18c5 /src/Language/Fiddle/Parser.hs | |
parent | f0c4da33e9576d2509b8c6330b1663e044e2dff3 (diff) | |
download | fiddle-0d2095b5d42989639c1861d7213c182abd064672.tar.gz fiddle-0d2095b5d42989639c1861d7213c182abd064672.tar.bz2 fiddle-0d2095b5d42989639c1861d7213c182abd064672.zip |
More major changes to the grammer.
Added annotation sublanguage for defining compiler directives. Also
added the syntax for import statements. Imports are not implemented, but
I'm currently working on that.
Diffstat (limited to 'src/Language/Fiddle/Parser.hs')
-rw-r--r-- | src/Language/Fiddle/Parser.hs | 89 |
1 files changed, 81 insertions, 8 deletions
diff --git a/src/Language/Fiddle/Parser.hs b/src/Language/Fiddle/Parser.hs index 7eed0f2..f3ad744 100644 --- a/src/Language/Fiddle/Parser.hs +++ b/src/Language/Fiddle/Parser.hs @@ -7,6 +7,7 @@ module Language.Fiddle.Parser ) where +import Control.Monad (void) import Data.Functor.Identity import Data.Kind (Type) import Data.Text (Text) @@ -50,25 +51,89 @@ isComment (Token t _) = stripTrailingComments :: [Token s] -> [Token s] stripTrailingComments = reverse . dropWhile isComment . reverse +directed :: Pa t -> PaS (Directed (t 'Stage1)) +directed subparser = withMeta $ do + Directed <$> many directive <*> subparser + +directive :: PaS Directive +directive = + withMeta $ + Directive <$> defer directiveBodyTokens directiveBody + +directiveBody :: PaS DirectiveBody +directiveBody = withMeta $ do + DirectiveBody <$> many (directiveElement <* (void (tok TokComma) <|> eof)) + +directiveElement :: PaS DirectiveElement +directiveElement = withMeta $ do + identifier1 <- nextText + choice + [ do + tok TokColon + let backend = identifier1 + key <- nextText + choice + [ do + tok TokEq + DirectiveElementKeyValue (Just backend) key <$> directiveExpression, + do + return (DirectiveElementKey (Just backend) key) + ], + do + tok TokEq + let key = identifier1 + DirectiveElementKeyValue Nothing key <$> directiveExpression, + return $ DirectiveElementKey Nothing identifier1 + ] + +nextText :: PaS Identifier +nextText = withMeta $ Identifier <$> token textOf + +directiveExpression :: PaS DirectiveExpression +directiveExpression = withMeta $ do + choice + [ do + token $ \case + (TokString str) -> Just $ DirectiveString str + (TokLitNum num) -> Just $ DirectiveNumber num + _ -> Nothing + ] + fiddleUnit :: Pa FiddleUnit fiddleUnit = do withMeta - ( FiddleUnit <$> many1 (fiddleDecl <* tok TokSemi) + ( FiddleUnit <$> many1 (directed fiddleDecl <* tok TokSemi) ) <* many comment +stringToken :: P Text +stringToken = token (\case + (TokString str) -> Just str + _ -> Nothing) + +importList :: PaS ImportList +importList = withMeta $ do + tok TokLParen + ImportList <$> many (ident <* (tok TokComma <|> lookAhead (tok TokRParen))) + <* tok TokRParen + +importStatement :: PaS ImportStatement +importStatement = withMeta $ + ImportStatement <$> stringToken <*> optionMaybe importList + fiddleDecl :: Pa FiddleDecl fiddleDecl = do withMeta $ do t <- tokenType <$> anyToken case t of - KWOption -> OptionDecl <$> ident <*> ident + KWOption -> OptionDecl <$> nextText <*> nextText KWPackage -> PackageDecl <$> ident <*> defer body packageBody KWLocation -> LocationDecl <$> ident <*> (tok TokEq >> expression) KWBits -> BitsDecl <$> ident <*> (tok TokColon >> bitType) + KWImport -> ImportDecl <$> importStatement KWType -> ObjTypeDecl <$> ident @@ -132,7 +197,7 @@ exprInParen = tok TokLParen *> expression <* tok TokRParen objTypeBody :: BodyType F (Commented SourceSpan) -> Pa ObjTypeBody objTypeBody bt = withMeta $ - ObjTypeBody bt <$> many (objTypeDecl <* tok TokSemi) + ObjTypeBody bt <$> many (directed objTypeDecl <* tok TokSemi) objTypeDecl :: Pa ObjTypeDecl objTypeDecl = @@ -185,7 +250,7 @@ registerBody = withMeta $ RegisterBody <$> bitBodyType <*> defer body deferredRe deferredRegisterBody :: Pa DeferredRegisterBody deferredRegisterBody = withMeta $ - DeferredRegisterBody <$> many (registerBitsDecl <* tok TokSemi) + DeferredRegisterBody <$> many (directed registerBitsDecl <* tok TokSemi) registerBitsDecl :: Pa RegisterBitsDecl registerBitsDecl = @@ -239,7 +304,7 @@ bitType = withMeta $ rawBits <|> enumType enumBody :: Pa EnumBody enumBody = withMeta $ - EnumBody <$> many (enumConstantDecl <* tok TokComma) + EnumBody <$> many (directed enumConstantDecl <* tok TokComma) enumConstantDecl :: Pa EnumConstantDecl enumConstantDecl = @@ -260,6 +325,13 @@ body = do (_, b, _) <- body' return b +directiveBodyTokens :: P [Token SourceSpan] +directiveBodyTokens = do + tokKeepComment TokDirectiveStart + ret <- concat <$> manyTill ((: []) <$> anyToken) (lookAhead $ tokKeepComment TokDirectiveEnd) + tokKeepComment TokDirectiveEnd + return ret + body' :: P (Token SourceSpan, [Token SourceSpan], Token SourceSpan) body' = do l <- tokKeepComment TokLBrace @@ -299,9 +371,10 @@ packageBody = withMeta $ PackageBody <$> many - ( fiddleDecl - <* ( tok TokSemi <|> fail "Expected ';'" - ) + ( directed $ + fiddleDecl + <* ( tok TokSemi <|> fail "Expected ';'" + ) ) printNext :: P () |