Plan 9 from Bell Labs’s /usr/web/sources/contrib/fernan/nhc98/src/greencard/HandParse.hs

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


module HandParse
  ( gcParse
  ) where

--import Data
import Name (Name)
import Type (Type(..), typeApply)
import DIS  (DIS(..), apply)
import Casm (BaseTy(..), lookupBaseTy)
import Decl
import HandLex
import ParseLib

gcParse :: [Token] -> [Decl]
gcParse = fst . head . papply decls

#define PARSEARG(tok)  P (\inp -> case inp of { \
                                      ((p,tok n):ts) -> [(n,ts)]; \
                                      ts -> [] } )

name, disname, baseTy, haskell, cexp, c :: Parser Name
name =    PARSEARG(TokName)
disname = PARSEARG(TokDisName)
baseTy =  PARSEARG(TokBaseTy)
haskell = PARSEARG(TokHaskell)
cexp =    PARSEARG(TokCExp)
c =       PARSEARG(TokC)

ccode :: Parser [String]
ccode =   PARSEARG(TokCCode)

----
decls :: Parser [Decl]
decls = many decl

decl :: Parser Decl
decl =
    procspec +++
    ( haskell >>= return . Haskell) +++
    ( c >>= return . C) +++
    ( tok TokDis `cut` (do
         n <- disname `elserror` "expected <disname> after %dis"
         v <- vars    `elserror` ("expected <vars> after %dis "++show n)
         tok TokEqual `elserror` "expected = in %dis definition"
         d <- dis     `elserror` "invalid rhs of %dis definition"
         return (DisDef n v d))) +++
    ( tok TokConst `cut` (do
         t <- tType   `elserror` "expected <type> after %const"
         cs <- bracket (tok TokSqOpen) constnames (tok TokSqClose)
         return (Constant t cs))) +++
    ( tok TokPrefix `cut` (do
         n <- nName   `elserror` "expected <name> after %prefix"
         return (Prefix n)))

vars :: Parser [Name]
vars = many disname

constnames :: Parser [(Name,Name)]
constnames =
    sepby1 constName (tok TokComma)

constName :: Parser (Name,Name)
constName =
    ( do h <- nName
         tok TokEqual
         c <- (nName+++cexp)
         return (h,c)) +++
    ( do n <- nName
         return (n,n))

nName :: Parser Name
nName =
    name +++ disname

procspec :: Parser Decl
procspec = do
    s <- sig
    c <- mbcall
    cc <- mbccode
    f <- mbfail
    r <- mbresult
    return (ProcSpec s c cc f r)

sig :: Parser Sig
sig =
    tok TokFun `cut` (do
    n <- nName  `elserror` "expected <function name> after %fun"
    tok TokCoCo `elserror` ("expected '::' after %fun "++show n)
    t <- tType  `elserror` "expected valid type in %fun declaration"
    return (n,t))

tType :: Parser Type
tType =
    ( do s <- simpletype
         tok TokArrow
         t <- tType
         return (Arrow s t)) +++
    simpletype

simpletype :: Parser Type
simpletype =
    ( bracket (tok TokOpen) tType (tok TokClose)) +++
    typetuple  +++
    ( do n <- nName
         a <- atypes
         return (typeApply (TypeVar n) a)) +++
    ( bracket (tok TokSqOpen) tType (tok TokSqClose) >>= return . TypeList)

atypes :: Parser [Type]
atypes = many atype

atype :: Parser Type
atype =
    ( bracket (tok TokOpen) tType (tok TokClose)) +++
    typetuple  +++
    ( nName >>= \n-> return (TypeVar n))

typetuple :: Parser Type
typetuple =
    ( tok TokOpen >>
      tok TokClose >> return (TypeTuple [])) +++
    ( bracket (tok TokOpen) typetuples (tok TokClose) >>= return . TypeTuple)

typetuples :: Parser [Type]
typetuples = do
    t <- tType
    tok TokComma
    ts <- sepby1 tType (tok TokComma)
    return (t:ts)

cCode :: Parser String
cCode =
    ( ccode >>= return . unlines) +++
    cexp

mbcall :: Parser (Maybe Call)
mbcall =
    ( tok TokCall `cut` (do
         a <- args   `elserror` "improperly formed %call section"
         return (Just a))) +++
    ( return Nothing )

mbccode :: Parser (Maybe CCode)
mbccode =
    ( ccode >>= return . Just) +++
    ( return Nothing )

mbfail :: Parser (Maybe Fail)
mbfail =
    ( fails >>= return . Just) +++
    ( return Nothing )

fails :: Parser [(String,String)]
fails =
    many1 ( tok TokFail `cut` (do
               c1 <- cCode   `elserror` "expected <Ccode> in %fail decl"
               c2 <- cCode   `elserror` "expected 2nd <Ccode> in %fail decl"
               return (c1,c2)))

mbresult :: Parser (Maybe Result)
mbresult =
    ( tok TokResult `cut` (do
         d <- dis `elserror` "improperly formed <dis> in %result decl"
         return (Just d))) +++
    ( return Nothing )

dis :: Parser DIS
dis =
    ( bracket (tok TokOpen) dis (tok TokClose)) +++
    ( do d <- disname
         as <- many1 arg
         return (apply (Var d) as)) +++
    ( do n <- name
         as <- many arg
         return (apply (Constructor n) as)) +++
    ( tok TokAngOpen `cut` (do
         n1 <- name	 `elserror` "need name inside <.../...>"
         tok TokSlash	 `elserror` "need / inside <.../...>"
         n2 <- name	 `elserror` "need name inside <.../...>"
         tok TokAngClose `elserror` "need closing > in <.../...>"
         as <- many1 arg `elserror` "need args after <.../...>"
         return (apply (UserDIS True n1 n2) as))) +++
    ( tok TokAng2Open `cut` (do
         n1 <- name	 `elserror` "need name inside <<.../...>>"
         tok TokSlash	 `elserror` "need / inside <<.../...>>"
         n2 <- name	 `elserror` "need name inside <<.../...>>"
         tok TokAng2Close`elserror` "need closing >> in <<.../...>>"
         as <- many1 arg `elserror` "need args after <<.../...>>"
         return (apply (UserDIS False n1 n2) as))) +++
    ( do b <- baseTy
         case b of
           "Foreign" -> do f <- (nName+++cexp) `elserror` "expected <freeing function> in %%Foreign"
                           a <- arg            `elserror` "expected <variable> in %%Foreign"
                           return (apply (BaseDIS (Foreign f)) [a])
           _         -> do a <- arg            `elserror` "expected <variable> in %%basetype decl"
                           return (apply (BaseDIS (lookupBaseTy b)) [a])) +++
    ( do n <- name
         f <- bracket (tok TokCurOpen) fieldDISs (tok TokCurClose)
         return (let (fs,ds) = unzip f in Apply (Record n fs) ds)) +++
    tuple +++
    ( cexp >>= \c-> return (Exp c)) +++
    ( tok TokDeclare `cut` (do
         cty <- cexp	`elserror` "expected \"ctype\" in <declare> block"
         d <- disname	`elserror` "expected variable name in <declare> block"
         tok TokIn	`elserror` "expected <in> in <declare ... in ...> block"
         v <- dis	`elserror` "expected <dis> in <declare> block"
         return (apply (Declare cty (Var d)) [v])))
 
arg :: Parser DIS
arg =
    ( bracket (tok TokOpen) dis (tok TokClose)) +++
    ( disname >>= \n-> return (Var n)) +++
    ( name >>= \n-> return (Constructor n)) +++
    ( cexp >>= \c-> return (Exp c)) +++
    tuple

args :: Parser [DIS]
args = many1 arg

tuple :: Parser DIS
tuple =
    ( tok TokOpen >>
      tok TokClose >> return Tuple) +++
    ( bracket (tok TokOpen) tuples (tok TokClose) >>= return . apply Tuple)

tuples :: Parser [DIS]
tuples = do
    d <- dis
    tok TokComma
    ds <- sepby1 dis (tok TokComma)
    return (d:ds)

fieldDISs :: Parser [(String,DIS)]
fieldDISs =
    sepby1 field_elt (tok TokComma)

field_elt :: Parser (String,DIS)
field_elt = do
    n <- nName
    tok TokEqual
    d <- dis
    return (n,d)


Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].