using System.Xml; using Nemerle.Utility; using Nemerle.Collections; using Nemerle.IO; variant Xml { | Elt { name : string; attrs : Hashtable [string, string]; mutable children : list [Xml]; } public override ToString () : string { match (this) { | Elt (name, _, ch) => $ "($name $ch)" } } } module Formatter { read_xml () : Xml { def reader = XmlTextReader (System.Console.OpenStandardInput ()); def loop (acc) { if (reader.Read ()) match (reader.NodeType) { | XmlNodeType.Element => def attrs = Hashtable (); def name = reader.Name; def attrcnt = reader.AttributeCount; for (mutable i = 0; i < attrcnt; ++i) { reader.MoveToAttribute (i); attrs [reader.Name] = reader.Value; } _ = reader.MoveToElement (); def content = if (reader.IsEmptyElement) [] else loop ([]); def elt = Xml.Elt (name, attrs, content); loop (elt :: acc) | XmlNodeType.EndElement => List.Rev (acc) // ignore text | _ => loop (acc) } else List.Rev (acc) } List.Head (loop ([])) } handle_ty (e : Xml) : string { | Xml.Elt ("tapp", a, []) => a["ref"] | Xml.Elt ("tapp", a, args) => a["ref"] + "<" + NString.Concat (", ", List.Map (args, handle_ty)) + ">" | Xml.Elt ("tprod", _, args) => NString.Concat (" * ", List.Map (args, handle_ty)) | Xml.Elt ("tfun", _, [Xml.Elt ("from", _, [from]), Xml.Elt ("to", _, [to])]) => handle_ty (from) + " -> " + handle_ty (to) | Xml.Elt ("tvoid", _, []) => "void" | Xml.Elt ("tref", _, [t]) => "ref " + handle_ty (t) | Xml.Elt ("tout", _, [t]) => "out " + handle_ty (t) | Xml.Elt ("tarray", a, [t]) => "array" + (if (a["rank"] == "1") "" else "." + a["rank"]) + " <" + handle_ty (t) + ">" | Xml.Elt ("ttypelist", _, _) => "..." | Xml.Elt (name, _, _) => $ "[unknown: $name]" } handle_decl (e : Xml) : void { | Xml.Elt ("alias", a, [Xml.Elt ("modifiers", _, _), Xml.Elt ("aliased", _, [ty])]) => def name = a["name"]; print ("type $name = $(handle_ty (ty));\n") | Xml.Elt (name, _, _) => print ("unknown $name\n") } public Main () : void { match (read_xml ()) { | (Xml.Elt ("unit", _, lst)) as e => print ("$e\n"); List.Iter (lst, handle_decl) | Xml.Elt => print ("invalid toplevel") } } }