summaryrefslogtreecommitdiff
path: root/ml/format.aml
blob: 6b7acef230309d5456067a6fe78755c316549be6 (plain)
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
(*
A library implementing a very simple string interpolation facility. 
An example of usage is 

   print(format "The square of $ is $\n" ["3", "9"])
*)

signature FORMAT = sig
  val format : string -> string list -> string
end

structure Format = struct
  exception ArityError of string

  fun checkArity(templN1, argsN) = let
    val n1 = Int.toString (length templN1 - 1)
    val n = Int.toString (length argsN)
  in
    if n1=n then () else raise ArityError("Expected "^n1^" arguments, got"^n)
  end

  val rec interp' =
   fn ([t], [], acc) => concat(rev (t :: acc))
    | (t :: templ, a :: args, acc) => interp'(templ, args, t :: a :: acc)
    | _ => raise ArityError "This should never happen"

  and interp'' = 
   fn (templN1, argsN) => (
      checkArity (templN1, argsN); interp' (templN1, argsN, []))

  and format = 
   fn templ => let
          val templN1 = String.fields (fn c => c = #"$") templ
      in
          fn args => interp'' (templN1, args)
      end

end: FORMAT