packages feed

keiro-dsl-0.8.0.0: src/Keiro/Dsl/Parser/Declaration.hs

-- | Shared ID, enum, and rule declarations.
module Keiro.Dsl.Parser.Declaration
  ( pIdDecl,
    pEnumDecl,
    pRuleDecl,
  )
where

import Keiro.Dsl.Frontend.Internal (FrontendContext)
import Keiro.Dsl.Grammar
import Keiro.Dsl.LanguageVersion
import Keiro.Dsl.Parser.Core
import Keiro.Dsl.Parser.Expression (pExpr)
import Keiro.Dsl.Parser.Mapped (pUsingNominalBinding)
import Keiro.Dsl.Source (Located, mapLocated)
import Keiro.Dsl.Syntax (SurfaceElement (..))
import Text.Megaparsec (many, sepBy1)

pIdDecl :: FrontendContext -> P IdDecl
pIdDecl context = do
  loc <- getLoc
  keyword "id"
  name <- ident
  _ <- symbol "prefix"
  _ <- symbol "="
  pfx <- wireWord
  binding <- optionalLanguageFeature context NominalBindingSyntax "using" pUsingNominalBinding
  pure IdDecl {idName = name, idPrefix = pfx, idBinding = binding, idLoc = loc}

pEnumDecl :: FrontendContext -> P EnumDecl
pEnumDecl context = do
  loc <- getLoc
  keyword "enum"
  name <- ident
  ctors <- braces (many pEnumCtor)
  binding <- optionalLanguageFeature context NominalBindingSyntax "using" pUsingNominalBinding
  pure EnumDecl {enumName = name, enumCtors = ctors, enumBinding = binding, enumLoc = loc}
  where
    pEnumCtor = do
      c <- ident
      _ <- symbol "="
      w <- wireWord
      pure (c, w)

pRuleDecl :: FrontendContext -> P (RuleDecl, [Located SurfaceElement])
pRuleDecl context = do
  loc <- getLoc
  keyword "rule"
  name <- ident
  _ <- symbol ":"
  dom <- ident
  _ <- symbol "->"
  cod <- ident
  keyword "ex"
  parsedCases <- sepBy1 pCase (symbol ";")
  let cases = map fst parsedCases
      elements = map snd parsedCases
  pure
    ( RuleDecl
        { ruleName = name,
          ruleDomain = dom,
          ruleCodomain = cod,
          ruleCases = cases,
          ruleLoc = loc
        },
      elements
    )
  where
    pCase = do
      c <- ident
      _ <- symbol "=>"
      expression <- withOwnedSpan (pExpr context)
      pure ((c, locatedValue expression), mapLocated SurfaceExpression expression)