functor PPrint(ImpAst : IMPAST) : PPRINT = struct
  
  structure ImpAst = ImpAst

  fun pprintVar x = print x

  local 
      open ImpAst
  in
  fun pprintAexp a = pprintAexp'(0, a)
  and pprintBexp b = pprintBexp'(0, b)
  and pprintCom c = pprintCom'(0, "", c)
  and NSpace 0 = ()
    | NSpace n = (print " "; NSpace(n-1))
		 
		 
  and pprintAexp'(n, (Int m)) = print(Int.toString m)
    | pprintAexp'(n, (Var x)) = pprintVar x
    | pprintAexp'(n, (Plus(a1, a2)))  = (print "("; pprintAexp'(n, a1); print " + "; pprintAexp'(n, a2); print ")")
					
  and	pprintBexp'(n, (True)) = print "true"
      | pprintBexp'(n, (False)) = print "false"
      | pprintBexp'(n, (Less  (a1, a2))) = (print "("; pprintAexp'(n, a1); print " < "; pprintAexp'(n, a2); print ")")
				       
  and pprintCom' (n, l, Skip) = (NSpace n; print l; print "skip")
    | pprintCom' (n, l, Assign(x, a)) = (NSpace n; print l; pprintVar x; print " := "; pprintAexp a)
    | pprintCom' (n, l, Goto(l')) = (NSpace n; print l; print "goto "; print l')
    | pprintCom' (n, l, Break) = (NSpace n; print l; print "break")
    | pprintCom' (n, l, Continue) = (NSpace n; print l; print "continue")
    | pprintCom' (n, l, Label(l', c)) = (pprintCom'(n, (l ^ l' ^ ": "), c))
    | pprintCom' (n, l, Seq(c1, c2)) = (pprintCom'(n, l, c1); print ";\n"; pprintCom'(n, "", c2))
    | pprintCom' (n, l, If(b, c1, c2)) = (NSpace n; print l; print "if "; pprintBexp b; print " then {\n";
					 pprintCom'(n+2, "", c1); print "\n"; NSpace n; print "} else {\n";
					 pprintCom'(n+2, "", c2); print "\n"; NSpace n; print "}")
    | pprintCom' (n, l, While(b, c)) = (NSpace n; print l; print "while "; pprintBexp b; print " do {\n";
				     pprintCom'(n+2, "", c); print "\n"; NSpace n; print "}")

				    
  end
      
end


