diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2022-12-18 12:18:34 -0700 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2022-12-18 12:18:34 -0700 |
commit | 0c45ef8884ec82d26c47e952132d54d4bb8a9238 (patch) | |
tree | 76842fb093c4ff2acaee1137b9c9efc255e9c6c9 | |
parent | 01685ab88228fb602cb0e408d93560e76e1371a1 (diff) | |
download | fiddle-0c45ef8884ec82d26c47e952132d54d4bb8a9238.tar.gz fiddle-0c45ef8884ec82d26c47e952132d54d4bb8a9238.tar.bz2 fiddle-0c45ef8884ec82d26c47e952132d54d4bb8a9238.zip |
Some more fleshing-out of the parser and better AST utils.
-rw-r--r-- | goal.fiddle | 8 | ||||
-rw-r--r-- | package.yaml | 1 | ||||
-rw-r--r-- | src/Language/Fiddle/Ast.hs | 283 | ||||
-rw-r--r-- | src/Language/Fiddle/Compiler.hs | 3 | ||||
-rw-r--r-- | src/Language/Fiddle/Parser.hs | 35 | ||||
-rw-r--r-- | src/Language/Fiddle/Types.hs | 1 | ||||
-rw-r--r-- | src/Main.hs | 8 | ||||
-rw-r--r-- | vim/syntax/fiddle.vim | 2 |
8 files changed, 281 insertions, 60 deletions
diff --git a/goal.fiddle b/goal.fiddle index 811719c..312c580 100644 --- a/goal.fiddle +++ b/goal.fiddle @@ -8,15 +8,15 @@ package gpio { location gpio_c_base = 0x4800_0800; /** IO Data. This is just an expressive boolean. */ - bittype data_t : enum(1) { - low =stream 0, + bits data_t : enum(1) { + low = 0, high = 1, - } + }; /** * Structure of the GPIO port on an stm32l432 */ - objtype gpio_t { + objtype gpio_t : { assert_pos(0); reg (32) : { /** The mode for each pin. */ diff --git a/package.yaml b/package.yaml index 0055d35..7eb5de2 100644 --- a/package.yaml +++ b/package.yaml @@ -28,3 +28,4 @@ dependencies: - base >= 4.0.0 - parsec - text + - mtl diff --git a/src/Language/Fiddle/Ast.hs b/src/Language/Fiddle/Ast.hs index 23fb05f..03cf527 100644 --- a/src/Language/Fiddle/Ast.hs +++ b/src/Language/Fiddle/Ast.hs @@ -1,24 +1,50 @@ +{-# LANGUAGE DefaultSignatures #-} +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE IncoherentInstances #-} +{-# LANGUAGE TypeOperators #-} +{-# LANGUAGE UndecidableInstances #-} + module Language.Fiddle.Ast where +import Data.Functor.Identity +import Data.Proxy import Data.Text (Text) +import Data.Traversable +import GHC.Generics -- Stage of compilation. Parts of the AST maybe un unavailable with other stages -- as compilation simplifies the AST. data Stage = Stage1 | Stage2 | Stage3 -- Just an identifier. -data Identifier a = Identifier !Text a +data Identifier stage f a = Identifier !Text a + deriving (Generic, Annotated, Alter) -- Expression. -data Expression stage a where +data Expression stage f a where -- Just a string. Parsing the number comes in stage2. - LitNum :: Text -> a -> Expression 'Stage1 a - RealNum :: Integer -> a -> Expression 'Stage2 a - Var :: Identifier a -> a -> Expression stage a + LitNum :: Text -> a -> Expression 'Stage1 f a + RealNum :: Integer -> a -> Expression 'Stage2 f a + Var :: Identifier stage f a -> a -> Expression stage f a + +instance Alter (Expression stage) where + alter ffn fn = \case + LitNum t a -> LitNum t <$> fn a + RealNum i a -> RealNum i <$> fn a + Var i a -> Var <$> alter ffn fn i <*> fn a + +instance Annotated (Expression stage) where + annot = \case + LitNum _ a -> a + RealNum _ a -> a + Var _ a -> a -- Root of the parse tree. Just contains a list of declarations. data FiddleUnit (stage :: Stage) (f :: * -> *) a where FiddleUnit :: [FiddleDecl stage f a] -> a -> FiddleUnit stage f a + deriving (Generic, Annotated, Alter) -- Top-level declarations. data FiddleDecl (stage :: Stage) (f :: * -> *) a where @@ -26,66 +52,92 @@ data FiddleDecl (stage :: Stage) (f :: * -> *) a where - An option is a key/value pair. - option <ident> <ident>; -} - OptionDecl :: Identifier a -> Identifier a -> a -> FiddleDecl stage f a + OptionDecl :: + Identifier stage f a -> + Identifier stage f a -> + a -> + FiddleDecl stage f a {- Package Statement. Package Name, Package body -} PackageDecl :: - Identifier a -> + Identifier stage f a -> f (PackageBody stage f a) -> a -> FiddleDecl stage f a {- location <identifier> = <expr>. -} LocationDecl :: - Identifier a -> - Expression stage a -> + Identifier stage f a -> + Expression stage f a -> a -> FiddleDecl stage f a {- bits <identifier> : <type> -} BitsDecl :: - Identifier a -> + Identifier stage f a -> BitType stage f a -> a -> FiddleDecl stage f a {- objtype <identifier> : <type> -} ObjTypeDecl :: - Identifier a -> + Identifier stage f a -> f (ObjTypeBody stage f a) -> a -> FiddleDecl stage f a {- object <ident> at <expr> : <type> -} ObjectDecl :: - Identifier a -> - Expression stage a -> + Identifier stage f a -> + Expression stage f a -> ObjType stage f a -> a -> FiddleDecl stage f a + deriving (Generic, Annotated, Alter) + data ObjType stage f a where -- { <body> } -- Anonymous types are only allowed in stage1. Stage2 should have them be -- de-anonymized. AnonymousObjType :: f (ObjTypeBody 'Stage1 f a) -> a -> ObjType 'Stage1 f a -- <type>[<expr>] - ArrayObjType :: ObjType stage f a -> Expression stage a -> a -> ObjType stage f a + ArrayObjType :: ObjType stage f a -> Expression stage f a -> a -> ObjType stage f a -- <identifier> - ReferencedObjType :: Identifier a -> a -> ObjType stage f a + ReferencedObjType :: Identifier stage f a -> a -> ObjType stage f a + +instance Alter (ObjType stage) where + alter ffn fn = \case + (AnonymousObjType b a) -> + AnonymousObjType <$> (ffn =<< mapM (alter ffn fn) b) <*> fn a + (ArrayObjType t e a) -> + ArrayObjType <$> alter ffn fn t <*> alter ffn fn e <*> fn a + (ReferencedObjType i a) -> + ReferencedObjType <$> alter ffn fn i <*> fn a + +instance Annotated (ObjType stage) where + annot = \case + (AnonymousObjType _ a) -> a + (ArrayObjType _ _ a) -> a + (ReferencedObjType _ a) -> a + data ObjTypeBody (stage :: Stage) (f :: * -> *) a where ObjTypeBody :: [ObjTypeDecl stage f a] -> a -> ObjTypeBody stage f a + deriving (Generic, Annotated, Alter) data ObjTypeDecl stage f a where {- assert_pos(<expr>) -} - AssertPosStatement :: Expression stage a -> a -> ObjTypeDecl stage f a + AssertPosStatement :: Expression stage f a -> a -> ObjTypeDecl stage f a {- reg <ident>(<expr>) : <regtype> -} RegisterDecl :: - Maybe (Modifier a) -> - Maybe (Identifier a) -> - Expression stage a -> + Maybe (Modifier stage f a) -> + Maybe (Identifier stage f a) -> + Expression stage f a -> Maybe (RegisterBody stage f a) -> a -> ObjTypeDecl stage f a -data Modifier a where - ModifierKeyword :: ModifierKeyword -> a -> Modifier a + deriving (Generic, Annotated, Alter) + +data Modifier stage f a where + ModifierKeyword :: ModifierKeyword -> a -> Modifier stage f a + deriving (Generic, Annotated, Alter) data ModifierKeyword = Rw | Ro | Wo @@ -94,58 +146,219 @@ data DeferredRegisterBody stage f a where [RegisterBitsDecl stage f a] -> a -> DeferredRegisterBody stage f a + deriving (Generic, Annotated, Alter) data RegisterBody stage f a where RegisterBody :: f (DeferredRegisterBody stage f a) -> a -> RegisterBody stage f a + deriving (Generic, Annotated, Alter) data RegisterBitsDecl stage f a where -- reserved(<expr>) - ReservedBits :: Expression stage a -> a -> RegisterBitsDecl stage f a + ReservedBits :: Expression stage f a -> a -> RegisterBitsDecl stage f a -- <modifer> <ident> : <type> DefinedBits :: - Maybe (Modifier a) -> - Identifier a -> + Maybe (Modifier stage f a) -> + Identifier stage f a -> RegisterBitsTypeRef stage f a -> a -> RegisterBitsDecl stage f a + deriving (Generic, Annotated, Alter) + data RegisterBitsTypeRef stage f a where -- <type>[<expr>] RegisterBitsArray :: RegisterBitsTypeRef stage f a -> - Expression stage a -> + Expression stage f a -> a -> RegisterBitsTypeRef stage f a {- Reference to a type. -} - RegisterBitsReference :: Identifier a -> a -> RegisterBitsTypeRef stage f a + RegisterBitsReference :: Identifier stage f a -> a -> RegisterBitsTypeRef stage f a {- enum(<expr>) { <body> } Anonymous types are only allowed in stage1. Stage2 should de-anonymize these type. -} RegisterBitsAnonymousType :: - AnonymousBitsType f a -> + AnonymousBitsType stage f a -> a -> RegisterBitsTypeRef 'Stage1 f a -data AnonymousBitsType f a where +instance Alter (RegisterBitsTypeRef stage) where + alter ffn fn = \case + (RegisterBitsArray ref exp a) -> + RegisterBitsArray <$> alter ffn fn ref <*> alter ffn fn exp <*> fn a + (RegisterBitsReference i a) -> + RegisterBitsReference <$> alter ffn fn i <*> fn a + (RegisterBitsAnonymousType t a) -> + RegisterBitsAnonymousType <$> alter ffn fn t <*> fn a + +instance Annotated (RegisterBitsTypeRef stage) where + annot = \case + (RegisterBitsArray _ _ a) -> a + (RegisterBitsReference _ a) -> a + (RegisterBitsAnonymousType _ a) -> a + +data AnonymousBitsType stage f a where -- enum(<expr>) { <body> } - AnonymousEnumBody :: Expression 'Stage1 a -> f (EnumBody stage f a) -> a -> AnonymousBitsType f a + AnonymousEnumBody :: Expression 'Stage1 f a -> f (EnumBody stage f a) -> a -> AnonymousBitsType stage f a + deriving (Generic, Annotated, Alter) data BitType (stage :: Stage) (f :: * -> *) a where -- enum(<expr>) { <body> } - EnumBitType :: Expression stage a -> f (EnumBody stage f a) -> a -> BitType stage f a + EnumBitType :: + Expression stage f a -> f (EnumBody stage f a) -> a -> BitType stage f a -- (<expr>) - RawBits :: Expression stage a -> a -> BitType stage f a + RawBits :: Expression stage f a -> a -> BitType stage f a + deriving (Generic, Annotated, Alter) data EnumBody (stage :: Stage) (f :: * -> *) a where -- <decl>, - EnumBody :: [EnumConstantDecl stage a] -> a -> EnumBody stage f a + EnumBody :: [EnumConstantDecl stage f a] -> a -> EnumBody stage f a + deriving (Generic, Annotated, Alter) -data EnumConstantDecl stage a where +data EnumConstantDecl stage f a where -- <ident> = <expr> - EnumConstantDecl :: Identifier a -> Expression stage a -> a -> EnumConstantDecl stage a + EnumConstantDecl :: Identifier stage f a -> Expression stage f a -> a -> EnumConstantDecl stage f a -- reserved = <expr> - EnumConstantReserved :: Expression stage a -> a -> EnumConstantDecl stage a + EnumConstantReserved :: Expression stage f a -> a -> EnumConstantDecl stage f a + deriving (Generic, Annotated, Alter) data PackageBody (stage :: Stage) (f :: * -> *) a where {- The body of a package -} PackageBody :: [FiddleDecl stage f a] -> a -> PackageBody stage f a + deriving (Generic, Annotated, Alter) + +-- instance Alter (Modifier stage) where +-- alter _ fn (ModifierKeyword m a) = ModifierKeyword m (fn a) +-- +-- instance Alter (Identifier stage) where +-- alter _ fn (Identifier i a) = Identifier i $ fn a +-- +-- instance Alter (Expression stage) where +-- alter ffn fn = \case +-- (LitNum t a) -> LitNum t $ fn a +-- (RealNum t a) -> RealNum t $ fn a +-- (Var i a) -> Var (alter ffn fn i) $ fn a + +proxyOf :: t f a -> Proxy t +proxyOf _ = Proxy + +class Annotated (t :: (* -> *) -> * -> *) where + annot :: t f a -> a + + default annot :: (Generic (t f a), GAnnot a (Rep (t f a))) => t f a -> a + annot t = gannot (from t) + +class GAnnot a r where + gannot :: r x -> a + +instance GAnnot a (Rec0 a) where + gannot k1 = unK1 k1 + +instance (GAnnot a r) => GAnnot a (l :*: r) where + gannot (_ :*: r) = gannot r + +instance (GAnnot a r, GAnnot a l) => GAnnot a (l :+: r) where + gannot (R1 r) = gannot r + gannot (L1 l) = gannot l + +instance (GAnnot a r) => GAnnot a (M1 i c r) where + gannot (M1 a) = gannot a + +class Alter (t :: (* -> *) -> * -> *) where + alter :: + forall f1 f2 a1 a2 m. + (Monad m, Traversable f1) => + (forall z. f1 z -> m (f2 z)) -> + (a1 -> m a2) -> + t f1 a1 -> + m (t f2 a2) + default alter :: + forall f1 f2 a1 a2 m. + ( Generic (t f1 a1), + Generic (t f2 a2), + Traversable f1, + GAlter t f1 f2 a1 a2 (Rep (t f1 a1)) (Rep (t f2 a2)), + Monad m + ) => + ( forall z. + f1 z -> + m (f2 z) + ) -> + (a1 -> m a2) -> + t f1 a1 -> + m (t f2 a2) + alter ffn fn t = to <$> galter (proxyOf t) ffn fn (from t) + +class GAlter t f1 f2 a1 a2 r1 r2 where + galter :: + forall proxy x m. + (Monad m, Traversable f1) => + proxy t -> + (forall z. f1 z -> m (f2 z)) -> + (a1 -> m a2) -> + r1 x -> + m (r2 x) + +{- Altering a record with type a1 will apply the mapping function and produce a + record with type a2 -} +instance GAlter t f1 f2 a1 a2 (Rec0 a1) (Rec0 a2) where + galter _ _ fn k1 = K1 <$> fn (unK1 k1) + +{- Base-Case. Altering unrelated leaf types will do nothing. -} +instance GAlter t f1 f2 a1 a2 (Rec0 u1) (Rec0 u1) where + galter _ _ _ = return + +{- Recursive case. Call alter on sub-structures. -} +instance (Alter u) => GAlter t f1 f2 a1 a2 (Rec0 (u f1 a1)) (Rec0 (u f2 a2)) where + galter _ ffn fn k1 = + K1 <$> alter ffn fn (unK1 k1) + +{- Recursive case. Called when there are list of substructures that need to be + recused. -} +instance (Alter u, Traversable l) => GAlter t f1 f2 a1 a2 (Rec0 (l (u f1 a1))) (Rec0 (l (u f2 a2))) where + galter _ ffn fn k1 = + K1 <$> mapM (alter ffn fn) (unK1 k1) + +-- instance GAlter t f1 f2 a1 a2 (Rec0 (f1 z)) (Rec0 (f2 z)) where +-- galter _ ffn _ k1 = K1 <$> ffn (unK1 k1) + +{- Generic altering. Descends into the function and alters whatever is inside + the functor and then transforms the functor using the ffn function. -} +instance + (Traversable f1, Alter u) => + GAlter t f1 f2 a1 a2 (Rec0 (f1 (u f1 a1))) (Rec0 (f2 (u f2 a2))) + where + galter proxy ffn fn k1 = do + newK <- mapM (alter ffn fn) (unK1 k1) + K1 <$> ffn newK + +instance + ( GAlter t f1 f2 a1 a2 l1 l2, + GAlter t f1 f2 a1 a2 r1 r2 + ) => + GAlter t f1 f2 a1 a2 (l1 :*: r1) (l2 :*: r2) + where + galter proxy ffn fn (a :*: b) = do + a' <- galter proxy ffn fn a + b' <- galter proxy ffn fn b + return (a' :*: b') + +instance + ( GAlter t f1 f2 a1 a2 l1 l2, + GAlter t f1 f2 a1 a2 r1 r2 + ) => + GAlter t f1 f2 a1 a2 (l1 :+: r1) (l2 :+: r2) + where + galter proxy ffn fn (R1 r) = R1 <$> galter proxy ffn fn r + galter proxy ffn fn (L1 l) = L1 <$> galter proxy ffn fn l + +instance + (GAlter t f1 f2 a1 a2 r1 r2) => + GAlter t f1 f2 a1 a2 (M1 i c r1) (M1 i c r2) + where + galter proxy ffn fn (M1 a) = M1 <$> galter proxy ffn fn a + + +{--} +squeeze :: (Alter t, Traversable f, Monad f) => t f a -> f (t Identity a) +squeeze = alter (fmap Identity) return diff --git a/src/Language/Fiddle/Compiler.hs b/src/Language/Fiddle/Compiler.hs index 9bc9eb9..af4e4d8 100644 --- a/src/Language/Fiddle/Compiler.hs +++ b/src/Language/Fiddle/Compiler.hs @@ -3,6 +3,3 @@ module Language.Fiddle.Compiler where import Language.Fiddle.Ast -- Converts a Stage1 AST to a Stage2 AST. -compileStage2 :: - FiddleUnit 'Stage1 Identity Metadata -> FiddleUnit 'Stage2 Identity Metadata -compileStage2 = undefined diff --git a/src/Language/Fiddle/Parser.hs b/src/Language/Fiddle/Parser.hs index 16489c1..59faeda 100644 --- a/src/Language/Fiddle/Parser.hs +++ b/src/Language/Fiddle/Parser.hs @@ -7,6 +7,7 @@ module Language.Fiddle.Parser ) where +import Debug.Trace import Data.Functor.Identity import Data.Text (Text) import qualified Data.Text @@ -25,9 +26,9 @@ type P = ParsecT S () Identity type Pa (a :: Stage -> (* -> *) -> * -> *) = P (a 'Stage1 F (Commented SourceSpan)) fiddleUnit :: Pa FiddleUnit -fiddleUnit = +fiddleUnit = do withMeta $ - FiddleUnit <$> many (fiddleDecl <* tok TokSemi) + FiddleUnit <$> many1 (fiddleDecl <* tok TokSemi) fiddleDecl :: Pa FiddleDecl fiddleDecl = @@ -66,7 +67,7 @@ objType = recur objType' (ReferencedObjType <$> ident) <|> (AnonymousObjType <$> defer body objTypeBody) -exprInParen :: P (Expression Stage1 (Commented SourceSpan)) +exprInParen :: Pa Expression exprInParen = tok TokLParen *> expression <* tok TokRParen objTypeBody :: Pa ObjTypeBody @@ -91,7 +92,7 @@ objTypeDecl = <*> optionMaybe (tok TokColon *> registerBody) ) -modifier :: P (Modifier (Commented SourceSpan)) +modifier :: Pa Modifier modifier = withMeta $ ModifierKeyword @@ -139,7 +140,7 @@ registerBitsTypeRef = recur typeRef (tok KWEnum >> RegisterBitsAnonymousType <$> anonymousBitsType) <|> (RegisterBitsReference <$> ident) -anonymousBitsType :: P (AnonymousBitsType F (Commented SourceSpan)) +anonymousBitsType :: Pa AnonymousBitsType anonymousBitsType = withMeta $ do tok KWEnum AnonymousEnumBody <$> exprInParen <*> defer body enumBody @@ -157,15 +158,15 @@ enumBody :: Pa EnumBody enumBody = withMeta $ withinBody $ - EnumBody <$> many enumConstantDecl + EnumBody <$> many (enumConstantDecl <* tok TokComma) -enumConstantDecl :: P (EnumConstantDecl Stage1 (Commented SourceSpan)) +enumConstantDecl :: Pa EnumConstantDecl enumConstantDecl = withMeta $ (tok KWReserved >> EnumConstantReserved <$> exprInParen) <|> (EnumConstantDecl <$> ident <*> (tok TokEq >> expression)) -expression :: P (Expression 'Stage1 (Commented SourceSpan)) +expression :: Pa Expression expression = withMeta $ token $ \case (TokLitNum num) -> Just (LitNum num) @@ -182,7 +183,8 @@ body = do ( body <|> fmap (: []) anyToken ) (lookAhead $ tok TokRBrace) - return $ t0 : ret + t1 <- tok TokRBrace + return $ t0 : ret ++ [t1] -- Parses something within braces. withinBody :: P a -> P a @@ -197,8 +199,11 @@ withinBody p = tok TokLBrace *> p <* tok TokRBrace defer :: P [Token SourceSpan] -> P b -> P (F b) defer p0 pb = do contents <- p0 + sourcePos <- getPosition + traceM $ "Contents: " ++ show contents + return $ Text.Parsec.runParser ( do @@ -215,7 +220,7 @@ packageBody = withinBody $ PackageBody <$> many (fiddleDecl <* tok TokSemi) -ident :: P (Identifier (Commented SourceSpan)) +ident :: Pa Identifier ident = withMeta $ token $ \case @@ -227,10 +232,9 @@ ident = withMeta :: P (Commented SourceSpan -> b) -> P b withMeta p = try $ do comments <- many comment - (Token _ (SourceSpan start _)) <- lookAhead anyToken + start <- getPosition fn <- p - (Token _ (SourceSpan end _)) <- lookAhead anyToken - + end <- getPosition return $ fn (Commented comments (SourceSpan start end)) where comment :: P Comment @@ -255,5 +259,6 @@ tok t' = (\tok@(Token t _) -> if t == t' then Just tok else Nothing) parseFiddleText :: String -> Text -> F (FiddleUnit 'Stage1 F (Commented SourceSpan)) -parseFiddleText sourceName txt = runIdentity $ do - Text.Parsec.runParserT fiddleUnit () sourceName [] +parseFiddleText sourceName txt = runIdentity . + Text.Parsec.runParserT + (fiddleUnit <* eof) () sourceName =<< tokenize sourceName txt diff --git a/src/Language/Fiddle/Types.hs b/src/Language/Fiddle/Types.hs index b712c7a..8d0c941 100644 --- a/src/Language/Fiddle/Types.hs +++ b/src/Language/Fiddle/Types.hs @@ -4,6 +4,7 @@ import Text.Parsec (SourcePos) import Data.Text (Text) data Comment = NormalComment Text | DocComment Text + deriving(Show) data SourceSpan = SourceSpan { sourceStart :: !SourcePos, diff --git a/src/Main.hs b/src/Main.hs index 226182a..d59181a 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -1,9 +1,13 @@ module Main where import qualified Language.Fiddle.Tokenizer +import qualified Language.Fiddle.Parser +import Language.Fiddle.Ast import qualified Data.Text.IO import qualified System.Environment as System import Control.Monad (forM_) +import Control.Monad.Writer +import qualified Language.Fiddle.Parser main :: IO () main = do @@ -12,8 +16,8 @@ main = do case argv of [filePath] -> do text <- Data.Text.IO.readFile filePath - case Language.Fiddle.Tokenizer.tokenize filePath text of + case squeeze =<< Language.Fiddle.Parser.parseFiddleText filePath text of Left pe -> putStrLn $ "Parse Error: " ++ show pe - Right lst -> forM_ lst $ \(Language.Fiddle.Tokenizer.Token t _) -> print t + Right ast -> putStrLn "Parsing Okay" _ -> putStrLn "Wrong Args" diff --git a/vim/syntax/fiddle.vim b/vim/syntax/fiddle.vim index e2a3fe8..01e9d04 100644 --- a/vim/syntax/fiddle.vim +++ b/vim/syntax/fiddle.vim @@ -1,6 +1,6 @@ syn keyword FiddlePackage option package nextgroup=FiddleIdent skipwhite syn keyword FiddleDecl reg object at location reserved nextgroup=FiddleIdent skipwhite -syn keyword FiddleTypeDecl objtype regtype bittype nextgroup=FiddleIdent skipwhite +syn keyword FiddleTypeDecl objtype regtype bits nextgroup=FiddleIdent skipwhite syn keyword FiddleEnum enum syn keyword FiddleBuiltin assert_pos syn keyword FiddleModifier wo ro rw |