Plan 9 from Bell Labs’s /usr/web/sources/contrib/fernan/nhc98/src/compiler98/Derive/XML.hs

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


module Derive.XML (deriveXML) where

import List
import Syntax
import MkSyntax(mkInt)
import IntState
import IdKind
import NT
import State
import Derive.Lib
import TokenId(TokenId,tTrue,t_Tuple,t_Colon,t_List
              ,tShowXml,t_toHType,t_showsElem
              ,t_stagparen,t_showConstr,t_compose,t_Defined,t_Constr
              ,dropM)
import Nice(showsOp,showsVar)

deriveXML tidFun cls typ tvs ctxs pos =
 getUnique >>>= \d ->
 let expD = ExpVar pos d
     iToHType    = tidFun (t_toHType,Method)
     iShowsElem  = tidFun (t_showsElem,Method)

     expToHType  = ExpVar pos iToHType
     expShowsElem  = ExpVar pos iShowsElem

     expTrue   = ExpCon pos (tidFun (tTrue,Con))
     expPair   = ExpCon pos (tidFun (t_Tuple 2,Con))
     expCons   = ExpCon pos (tidFun (t_Colon,Con))
     expNil    = ExpCon pos (tidFun (t_List,Con))
     expDefined= ExpCon pos (tidFun (t_Defined,Con))
     expConstr = ExpCon pos (tidFun (t_Constr,Con))
     expDot    = ExpVar pos (tidFun (t_compose,Var))
     expId     = ExpVar pos (tidFun (t_id,Var))
     expStagparen  = ExpVar pos (tidFun (t_stagparen,Var))
     expShowConstr = ExpVar pos (tidFun (t_showConstr,Var))
 in
  getInfo typ >>>= \ typInfo -> 
  mapS getInfo (constrsI typInfo) >>>= \ constrInfos ->
  let sizeC = ((ceiling . logBase 2 . fromIntegral . length) constrInfos)::Int
  in
    addInstMethod tShowXml (tidI typInfo) t_toHType (NewType tvs [] ctxs [mkNTcons typ (map mkNTvar tvs)]) iToHType >>>= \ funH ->
    addInstMethod tShowXml (tidI typInfo) t_showsElem (NewType tvs [] ctxs [mkNTcons typ (map mkNTvar tvs)]) iShowsElem >>>= \ funS ->
    mapS (mkShowsFun expTrue expShowsElem expToHType expStagparen expShowConstr expDot expId pos) (zip [0..] constrInfos) >>>= \ funSs ->
    mkHTypeFuns expTrue expToHType expDefined expConstr expCons expNil pos typInfo constrInfos >>>= \ funHs ->
    unitS $
      DeclInstance pos (syntaxCtxs pos ctxs) cls [syntaxType pos typ tvs] $
        DeclsParse [DeclFun pos funH funHs
                   ,DeclFun pos funS funSs]



mkShowsFun expTrue expShowsElem expToHType expStagparen expShowConstr expDot expId pos (numC,constrInfo) =
  getUnique >>>= \v ->
  let 
    --conTid = dropM (tidI constrInfo)
      con    = ExpCon pos (uniqueI constrInfo)
      expV   = ExpVar pos v
      expTag = ExpApplication pos [expShowConstr, mkInt pos numC,
                                     ExpApplication pos [expToHType, expV]]
      expStag x = ExpApplication pos [expStagparen, expTag, x]
  in case ntI constrInfo of
     NewType _ _ _ [nt] -> -- This constructor has no arguments
       unitS (Fun [PatAs pos v con] [(expTrue,expStag expId)] (DeclsParse []))
     NewType _ _ _ (_:nts) ->  -- We want a list with one element for each arg
       mapS ( \ _ -> unitS (ExpVar pos) =>>> getUnique) nts >>>= \args ->
       let expShowsArg arg = ExpApplication pos [expShowsElem,arg]
       in unitS (
          Fun [PatAs pos v (ExpApplication pos (con:args))]
              [(expTrue, expStag (foldr1
                                    (\arg z-> ExpApplication pos [expDot,arg,z])
                                    (map expShowsArg args)))]
              (DeclsParse []))


-- this code is modified from *showType*, not from *readsPrec*.
mkHTypeFuns expTrue expToHType expDefined expConstr expCons expNil pos typInfo constrInfos =
  getUnique >>>= \ v ->
  let expV      = ExpVar pos v
      expGetCon = ExpApplication pos [expGetBits, expBH, mkInt pos sizeC]
  in
   --mkListExp pos expCons expNil expGtGtEq expGet expBH expReturn constrInfos >>>= \listExp->
     mkAltList pos expTrue (mkGetExp pos expGtGtEq expGet expBH expReturn) constrInfos >>>= \altList->
     unitS [Fun [expBH]
                [(expTrue, ExpApplication pos
                             [expGtGtEq,
                              expGetCon,
                              ExpLambda pos [expI]
                                 (ExpCase pos expI altList)
                             ])]
                (DeclsParse [])]

mkGetExp pos expGtGtEq expGet expBH expReturn expCon args constrInfo =
  foldr (\ arg z -> ExpApplication pos [expGtGtEq, (ExpApplication pos [expGet,expBH]), ExpLambda pos [arg] z])
        (ExpApplication pos [expReturn,
                             ExpApplication pos (expCon:args)])
        args


mkAltList pos expTrue mkExpFun constrInfos =
  mapS (\(n,constrInfo) ->
         let expCon = ExpCon pos (uniqueI constrInfo)
             expN   = mkInt pos n
         in
         case ntI constrInfo of
           NewType _ _ _ (_:nts) ->
             mapS ( \ _ -> unitS (ExpVar pos) =>>> getUnique) nts >>>= \args ->
             unitS (Alt expN
                        [(expTrue, mkExpFun expCon args constrInfo)]
                        (DeclsParse []))
       )
       (zip [0..] constrInfos)



-- this code is modified from *showType*, not from *readsPrec*.
mkFGetFuns expTrue expGetBitsF expFGet expLtLt expPair expCons expNil sizeC pos typInfo constrInfos =
  getUnique >>>= \ bh ->
  getUnique >>>= \ p ->
  getUnique >>>= \ p' ->
  getUnique >>>= \ n ->
  let expBH = ExpVar pos bh
      expP  = ExpVar pos p
      expP' = ExpVar pos p'
      expN  = ExpVar pos n
      expInit   = ExpApplication pos [expGetBitsF, expBH, mkInt pos sizeC, expP]
      expFGetBH = ExpApplication pos [expFGet, expBH]
  in
     mkAltList pos expTrue (mkGetFExp pos expLtLt expFGetBH expPair expP') constrInfos >>>= \altList->
     unitS [Fun [expBH,expP]
                [(expTrue, ExpLet pos (DeclsParse [DeclPat (Alt (ExpApplication pos [expPair,expN,expP'])
                                                                [(expTrue,expInit)]
                                                                (DeclsParse []))])
                                      (ExpCase pos expN altList)
                )]
                (DeclsParse [])]

mkGetFExp pos expLtLt expFGetBH expPair expP' expCon args constrInfo =
    foldl (\ acc arg -> ExpApplication pos [expLtLt, acc, expFGetBH])
          (ExpApplication pos [expPair,expCon,expP'])
          args


mkSizeFun sizeC expTrue expSize expPlus pos constrInfo =
  let
      con           = ExpCon pos (uniqueI constrInfo)
      expCsize      = mkInt pos sizeC
      expSizeOf arg = ExpApplication pos [expSize,arg]
  in case ntI constrInfo of
     NewType _ _ _ (_:nts) ->
       mapS ( \_ -> unitS (ExpVar pos) =>>> getUnique) nts >>>= \args ->
       unitS (
          Fun [ExpApplication pos (con:args)]
              [(expTrue, foldl (\z arg-> ExpApplication pos [expPlus,expSizeOf arg,z]) expCsize args)]
              (DeclsParse []))


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].