packages feed

KiCS-0.8.9: src/lib/Curry/Module/FlatCurryXML.curry

------------------------------------------------------------------------------
--- This library contains functions to convert FlatCurry programs
--- into corresponding XML expressions and vice versa.
--- This can be used to store Curry programs in a way independent
--- from PAKCS or to use the PAKCS back end by other systems.
---
--- The library provides the following functions:
--- <PRE>
--- "flatCurry2XmlFile": transform a FlatCurry program into XML file
--- "flatCurry2Xml":     transform a FlatCurry program into XML expression
--- "xmlFile2FlatCurry": read an XML file and return the FlatCurry program
--- "xml2FlatCurry":     transform an XML expression into a FlatCurry program
--- </PRE>
---
--- @author Michael Hanus
--- @version August 2005
------------------------------------------------------------------------------

module FlatCurryXML(flatCurry2XmlFile,flatCurry2Xml,
                    xmlFile2FlatCurry,xml2FlatCurry)  where

import FlatCurry
import XML
import Read

-- URL for the FlatCurry DTD:
flatCurryDtd = "http://www.informatik.uni-kiel.de/~curry/flatcurrynew.dtd"

------------------------------------------------------------------------------
-- Transforming FlatCurry programs into corresponding XML terms:
------------------------------------------------------------------------------

--- Transforms a FlatCurry program term into a corresponding XML file.
flatCurry2XmlFile :: Prog -> String -> IO ()
flatCurry2XmlFile flatprog filename = writeFile filename
  (showXmlDocWithParams [DtdUrl flatCurryDtd] (flatCurry2Xml flatprog))

--- Transforms a FlatCurry program term into a corresponding XML expression.
flatCurry2Xml :: Prog -> XmlExp
flatCurry2Xml (Prog modname imports types funcs ops) =
  xml "prog"
   [xml "module" [xtxt modname],
    xml "import" (map (\s->xml "module" [xtxt s]) imports),
    xml "types" (map xmlShowType types),
    xml "functions" (map xmlShowFunc funcs),
    xml "operators" (map xmlShowOp ops)]

qname2xmlattrs (mod,name) = [("module",mod),("name",name)]

xmlShowVisibity Public  = [("visibility","public")]
xmlShowVisibity Private = [("visibility","private")]

xmlShowType (Type name vis tpars consdecls) =
  XElem "type" (qname2xmlattrs name ++ xmlShowVisibity vis)
        ([xml "params" (map xmlShowTVar tpars)] ++ map xmlShowCons consdecls)
xmlShowType (TypeSyn name vis tpars texp) =
  XElem "typesyn" (qname2xmlattrs name ++ xmlShowVisibity vis)
        [xml "params" (map xmlShowTVar tpars),xmlShowTypeExpr texp]

xmlShowCons (Cons cname arity vis types) =
  XElem "cons" (qname2xmlattrs cname ++ [("arity",show arity)] ++ xmlShowVisibity vis)
        (map xmlShowTypeExpr types)

xmlShowTypeExpr (FuncType t1 t2) =
  xml "functype" [xmlShowTypeExpr t1,xmlShowTypeExpr t2]
xmlShowTypeExpr (TCons tc ts) =
  XElem "tcons" (qname2xmlattrs tc) (map xmlShowTypeExpr ts)
xmlShowTypeExpr (TVar n) = xmlShowTVar n

xmlShowTVar i = xml "tvar" [xtxt (show i)]

xmlShowFunc (Func name arity vis ftype rl) =
  XElem "func" (qname2xmlattrs name ++ [("arity",show arity)] ++ xmlShowVisibity vis)
        [xmlShowTypeExpr ftype,xmlShowRule rl]

xmlShowRule (Rule params expr) =
  xml "rule" [xml "lhs" (map xmlShowVar params),
              xml "rhs" [xmlShowExpr expr]]
xmlShowRule (External name) = xml "external" [xtxt name]

xmlShowVar i = xml "var" [xtxt (show i)]

xmlShowExpr (Var n) = xmlShowVar n
xmlShowExpr (Lit l) = xml "lit" [xmlShowLit l]
xmlShowExpr (Comb FuncCall cf es) =
  XElem "funccall" (qname2xmlattrs cf) (map xmlShowExpr es)
xmlShowExpr (Comb ConsCall cf es) =
  XElem "conscall" (qname2xmlattrs cf) (map xmlShowExpr es)
xmlShowExpr (Comb (FuncPartCall n) cf es) =
  XElem "funcpartcall" (qname2xmlattrs cf ++ [("missing",show n)]) (map xmlShowExpr es)
xmlShowExpr (Comb (ConsPartCall n) cf es) =
  XElem "conspartcall" (qname2xmlattrs cf ++ [("missing",show n)]) (map xmlShowExpr es)
xmlShowExpr (Free xs e) =
  xml "free" [xml "freevars" (map xmlShowVar xs), xmlShowExpr e]
xmlShowExpr (Or e1 e2) =
  xml "or" [xmlShowExpr e1,xmlShowExpr e2]
xmlShowExpr (Case ctype e cs) =
  XElem (if ctype==Flex then "fcase" else "case") []
        ([xmlShowExpr e] ++ map xmlShowBranch cs)
xmlShowExpr (Let bindings expr) =
  xml "letrec" (map (\(i,e)->xml "binding" [xmlShowVar i, xmlShowExpr e]) bindings
                ++ [xmlShowExpr expr])

xmlShowLit (Intc   i) = xml "intc"   [xtxt (show i)]
xmlShowLit (Floatc f) = xml "floatc" [xtxt (show f)]
xmlShowLit (Charc  c) = xml "charc"  [xtxt (show (ord c))]

xmlShowBranch (Branch (Pattern cons xs) e) =
  xml "branch" [XElem "pattern" (qname2xmlattrs cons) (map xmlShowVar xs),
                xmlShowExpr e]
xmlShowBranch (Branch (LPattern lit) e) =
  xml "branch" [xml "lpattern" [xmlShowLit lit], xmlShowExpr e]

xmlShowOp (Op name fix prec) =
  XElem "op" (qname2xmlattrs name ++ [("fixity",show fix),("prec",show prec)]) []


------------------------------------------------------------------------------
-- Transforming XML terms into corresponding FlatCurry programs:
------------------------------------------------------------------------------

--- Reads an XML file with a FlatCurry program and returns
--- the FlatCurry program.
xmlFile2FlatCurry :: String -> IO Prog
xmlFile2FlatCurry filename =
  do xexp <- readXmlFile filename
     return (xml2FlatCurry xexp)

--- Transforms an XML term into a FlatCurry program.
xml2FlatCurry :: XmlExp -> Prog
xml2FlatCurry
 (XElem "prog" []
   [XElem "module"      [] xmodname,
    XElem "import"      [] ximports,
    XElem "types"       [] xtypes,
    XElem "functions"   [] xfunctions,
    XElem "operators"   [] xoperators]) =
  Prog (textOfXml xmodname)
       (map (\(XElem "module" [] xim) -> textOfXml xim) ximports)
       (map flatx2typedecl xtypes)
       (map (\(XElem "func" [("module",mod),("name",fname),("arity",farity),xvis]
                            [xftype,xfbody])
             -> Func (mod,fname) (readNat farity) (xvis2vis xvis) (flatx2texp xftype)
                     (flatx2FunBody xfbody))
            xfunctions)
       (map (\(XElem "op"
                     [("module",mod),("name",name),("fixity",xfix),("prec",xprec)] [])
             -> Op (mod,name) (flatx2Fixity xfix) (readNat xprec))
            xoperators)

flatx2typedecl (XElem "type" [("module",tmod),("name",tname),xtvis]
                      (XElem "params" [] xtvars : xconstructors)) =
  Type (tmod,tname) (xvis2vis xtvis)
       (map (\ (XElem "tvar" [] xtvar) -> readNat (textOfXml xtvar)) xtvars)
       (map (\ (XElem "cons" [("module",mod),("name",xcn),("arity",xar),xvis] xtexps)
              -> Cons (mod,xcn) (readNat xar) (xvis2vis xvis) (map flatx2texp xtexps))
            xconstructors)
flatx2typedecl (XElem "typesyn" [("module",tmod),("name",tname),xtvis]
                      [XElem "params" [] xtvars, xtexp]) =
  TypeSyn (tmod,tname) (xvis2vis xtvis)
          (map (\ (XElem "tvar" [] xtvar) -> readNat (textOfXml xtvar)) xtvars)
          (flatx2texp xtexp)

flatx2FunBody (XElem "external" [] xename) = External (textOfXml xename)
flatx2FunBody (XElem "rule" [] [XElem "lhs" [] xvars,
                                XElem "rhs" [] [xrhs]]) =
   Rule (map flatx2var xvars) (flatx2exp xrhs)

flatx2var :: XmlExp -> VarIndex
flatx2var (XElem "var" [] xvar) = readNat (textOfXml xvar)

flatx2exp :: XmlExp -> Expr
flatx2exp (XElem "var" [] xvar) = Var (readNat (textOfXml xvar))
flatx2exp (XElem "lit" [] [xlit]) = Lit (flatx2lit xlit)
flatx2exp (XElem "funccall" [("module",mod),("name",name)] xexps) =
  Comb FuncCall (mod,name) (map flatx2exp xexps)
flatx2exp (XElem "conscall" [("module",mod),("name",name)] xexps) =
  Comb ConsCall (mod,name) (map flatx2exp xexps)
flatx2exp (XElem "funcpartcall" [("module",mod),("name",name),("missing",nmiss)] xexps) =
  Comb (FuncPartCall (readNat nmiss)) (mod,name) (map flatx2exp xexps)
flatx2exp (XElem "conspartcall" [("module",mod),("name",name),("missing",nmiss)] xexps) =
  Comb (ConsPartCall (readNat nmiss)) (mod,name) (map flatx2exp xexps)
flatx2exp (XElem "free" [] [XElem "freevars" [] xvars, xexp]) =
  Free (map flatx2var xvars) (flatx2exp xexp)
flatx2exp (XElem "or" [] [xexp1,xexp2]) =
  Or (flatx2exp xexp1) (flatx2exp xexp2)
flatx2exp (XElem "case" [] (xexp : xbranches)) =
  Case Rigid (flatx2exp xexp) (map flatx2branch xbranches)
flatx2exp (XElem "fcase" [] (xexp : xbranches)) =
  Case Flex (flatx2exp xexp) (map flatx2branch xbranches)
flatx2exp (XElem "let" [] xbindings) =
  let (bindings,exp) = flatx2let xbindings
   in Let bindings exp
flatx2exp (XElem "letrec" [] xbindings) =
  let (bindings,exp) = flatx2let xbindings
   in Let bindings exp

flatx2let [xexp] = ([],flatx2exp xexp)
flatx2let (XElem "binding" [] [XElem "var" [] xvar, xexp] : xb:xbs) =
  let (bindings,exp) = flatx2let (xb:xbs)
   in ((readNat (textOfXml xvar), flatx2exp xexp) : bindings, exp)

flatx2branch (XElem "branch" [] [XElem "pattern" [("module",mod),("name",cons)] xvars,xexp]) =
  Branch (Pattern (mod,cons) (map flatx2var xvars)) (flatx2exp xexp)
flatx2branch (XElem "branch" [] [XElem "lpattern" [] [xlit], xexp]) =
  Branch (LPattern (flatx2lit xlit)) (flatx2exp xexp)
flatx2branch (XElem "branch" [] [XElem "hpattern" _ _,_]) =
  error "Higher-order patterns not supported in this version of FlatCurry!"

flatx2lit :: XmlExp -> Literal
flatx2lit (XElem "intc" [] xintc) = Intc (readNat (textOfXml xintc))
flatx2lit (XElem "floatc" [] _) =
            error "Reading of floats not yet implemented!"
flatx2lit (XElem "charc" [] xintc) = Charc (chr (readNat (textOfXml xintc)))

flatx2texp :: XmlExp -> TypeExpr
flatx2texp (XElem "tvar" [] xtvar) = TVar (readNat (textOfXml xtvar))
flatx2texp (XElem "functype" [] [xtexp1,xtexp2]) =
   FuncType (flatx2texp xtexp1) (flatx2texp xtexp2)
flatx2texp (XElem "tcons" [("module",mod),("name",tcname)] xtexps) =
   TCons (mod,tcname) (map flatx2texp xtexps)

xvis2vis ("visibility","public")  = Public
xvis2vis ("visibility","private") = Private

flatx2Fixity "InfixOp"  = InfixOp
flatx2Fixity "InfixlOp" = InfixlOp
flatx2Fixity "InfixrOp" = InfixrOp


------------------------------------------------------------------------------