~ehmry/dhall-nim

ref: 88637947bfa6dd6b90063519e4089ffa86b90bba dhall-nim/src/dhall/xml.nim -rw-r--r-- 2.0 KiB
88637947Emery Hemingway Add xml_to_dhall utility 11 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import ./terms

import std/options, std/strtabs, std/xmltree

proc toDhall*(xml: XmlNode): Term =
  ## Convert an XML node to a Dhall Term according to ``Prelude.XML``.
  ## https://github.com/dhall-lang/dhall-lang/blob/v19.0.0/Prelude/XML/Type.dhall
  proc toApp(xml: XmlNode): Term =
    case xml.kind
    of xnText:
      result = newApp(newField(newVar"xml", "text"), xml.text.newTerm)
    of xnElement:
      var attrs = Term(kind: tList, list: newSeqOfCap[Term](xml.attrsLen))
      if xml.attrsLen == 0:
        attrs.listType = some newRecordType(
            [("mapKey", bText.newTerm), ("mapValue", bText.newTerm)])
      else:
        for key, val in xml.attrs.pairs:
          attrs.list.add newRecordLiteral(
            [("mapKey", key.newTerm), ("mapValue", val.newTerm)])
      var content = Term(kind: tList, list: newSeqOfCap[Term](xml.len))
      if xml.len == 0:
        content.listType = some newVar"XML"
      else:
        for subNode in xml.items:
          case subNode.kind
          of xnText, xnElement:
            content.list.add subNode.toApp
          else: discard
      result = newApp(newField(newVar"xml", "element"), newRecordLiteral([ (
          "attributes", attrs), ("content", content), ("name",
          xml.tag.newTerm)]))
    else:
      raiseAssert("unrepresentable XML kind " & $xml.kind)
  var XMLVar = newVar"XML"
  var textPi = newPi(bText.newTerm, XMLVar)
  var elementPi = newPi(
    newRecordType([
      ("name", bText.newTerm),
      ("content", newListType(XMLVar)),
      ("attributes", newListType(
        newRecordType([
          ("mapKey", bText.newTerm), ("mapValue", bText.newTerm)
        ])
      )
    )]),
    XMLvar)
  result = Term(kind: tLambda,
    funcLabel: "XML",
    funcType: bType.newTerm,
    funcBody: Term(kind: tLambda,
        funcLabel: "xml",
        funcType: newRecordType([
          ("text", textPi),
          ("element", elementPi)]),
          funcBody: xml.toApp))

proc toXml*(expr: Value): XmlNode =
  raiseAssert "not implemented"