<!-- siffml-1.0 DTD.
     root element is "functions",
     but how is that made clear?
-->

<!-- "parameter entities" for use within the DTD -->

<!-- variants of VpType -->
<!ENTITY % sifflet-type 
  "(string-type|char-type|num-type|bool-type|list-type|type-variable)">

<!-- Variants of Expr.
     Expr also has a EList constructor, but this is not used
     in SiffML -->
<!ENTITY % sifflet-expr "(undefined|symbol|literal|if|call)">

<!-- Variants of Value -->
<!ENTITY % sifflet-value 
  "(True|False|char|string|int|float|list|function)">

<!-- elements -->

<!ELEMENT functions (compound-function*)>

<!ELEMENT compound-function (name, return-type, arg-types,
                             arg-names, body)>

<!ELEMENT name (#PCDATA)>
<!ELEMENT return-type %sifflet-type;> 
<!ELEMENT arg-types ((%sifflet-type;)*)>
<!ELEMENT arg-names (name*)>

<!ELEMENT body (%sifflet-expr;)>

<!-- type elements -->
<!ELEMENT string-type EMPTY>
<!ELEMENT char-type EMPTY>
<!ELEMENT num-type EMPTY>
<!ELEMENT bool-type EMPTY>
<!ELEMENT list-type (%sifflet-type;)>
<!ELEMENT type-variable (#PCDATA)>

<!-- expr elements -->

<!ELEMENT undefined EMPTY>
<!ELEMENT symbol (#PCDATA)>
<!ELEMENT literal (%sifflet-value;)>
<!ELEMENT if ((%sifflet-expr;), (%sifflet-expr;), (%sifflet-expr;))>
<!-- a "list" element as an expr is probably a mistake -->
<!-- <!ELEMENT list ((%sifflet-expr;)*)> -->
<!ELEMENT call (symbol, (%sifflet-expr;)*)>

<!-- value elements -->

<!ELEMENT True EMPTY>
<!ELEMENT False EMPTY>
<!ELEMENT char (#PCDATA)>
<!ELEMENT string (#PCDATA)>
<!ELEMENT int (#PCDATA)>
<!ELEMENT float (#PCDATA)>
<!-- a "list" element represents a list value, not a list expr -->
<!ELEMENT list ((%sifflet-value;)*)>
<!ELEMENT function (compound-function)> <!-- shouldn't happen though -->
