-
Notifications
You must be signed in to change notification settings - Fork 1
/
smlcgic.sml
82 lines (65 loc) · 2.17 KB
/
smlcgic.sml
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
structure TemplateComp =
struct
fun makeHeader fname =
"(* Generated by smlcgic *)\n" ^
"structure Template =\n" ^
"struct\n" ^
" open CGI\n" ^
" val PROGRAM_NAME = \"" ^ fname ^ "\"\n\n" ^
" fun render (title,content) =\n" ^
" let\n"
datatype frag = Code of string
| Verbatim of string
fun parse tmpl =
let
fun openTag c [] = (c,[])
| openTag c ((#"<")::(#"%")::t) = (c,t)
| openTag c (h::t) = openTag (c @ [h]) t
fun closeTag c [] = (c,[])
| closeTag c ((#"%")::(#">")::t) = (c,t)
| closeTag c (h::t) = closeTag (c @ [h]) t
fun loop [] = []
| loop l =
let
val (c,t) = openTag [] l
val (c',t') = closeTag [] t
in
Verbatim (String.implode c) ::
Code (String.implode c') ::
loop t'
end
in
loop (String.explode tmpl)
end
fun fragToStr (Verbatim s) =
" val _ = print \"" ^ String.toString s ^ "\""
| fragToStr (Code s) =
if String.isPrefix "%" s then
" val _ = print (" ^ String.extract(s,1,NONE) ^ ")"
else s
fun main () =
let
val fname =
hd (CommandLine.arguments ()) handle _ =>
raise Fail "Usage: smlcgic <filename>"
val fi = TextIO.openIn fname
val oname = OS.Path.base fname ^ ".cgi.sml"
val parts = parse (TextIO.inputAll fi)
val out = String.concatWith "\n" (map fragToStr parts)
val _ = TextIO.closeIn fi
val fo = TextIO.openOut oname
val _ = TextIO.output (fo, makeHeader fname)
val _ = TextIO.output (fo, out ^ "\n in () end\nend\n")
val _ = TextIO.closeOut fo
val mlbname = OS.Path.base fname ^ ".cgi.mlb"
val fo' = TextIO.openOut mlbname
val _ = TextIO.output (fo',
"$(SML_LIB)/basis/basis.mlb\n" ^
"$(SMACKAGE)/smlcgi/v0/cgi.mlb\n" ^
oname ^ "\n")
val _ = TextIO.closeOut fo'
in
OS.Process.success
end
end
val _ = TemplateComp.main ()