comparison src/monoize.sml @ 143:4b9c2bd6157c

Almost ready to have a form work
author Adam Chlipala <adamc@hcoop.net>
date Sun, 20 Jul 2008 13:30:19 -0400
parents 63c699450281
children f0d3402184d1
comparison
equal deleted inserted replaced
142:6f9e224692ec 143:4b9c2bd6157c
59 | L.TCFun _ => poly () 59 | L.TCFun _ => poly ()
60 | L.TRecord (L.CRecord ((L.KType, _), xcs), _) => 60 | L.TRecord (L.CRecord ((L.KType, _), xcs), _) =>
61 (L'.TRecord (map (fn (x, t) => (monoName env x, monoType env t)) xcs), loc) 61 (L'.TRecord (map (fn (x, t) => (monoName env x, monoType env t)) xcs), loc)
62 | L.TRecord _ => poly () 62 | L.TRecord _ => poly ()
63 63
64 | L.CApp ((L.CFfi ("Basis", "xml"), _), _) => (L'.TFfi ("Basis", "string"), loc) 64 | L.CApp ((L.CApp ((L.CApp ((L.CFfi ("Basis", "xml"), _), _), _), _), _), _) =>
65 (L'.TFfi ("Basis", "string"), loc)
65 66
66 | L.CRel _ => poly () 67 | L.CRel _ => poly ()
67 | L.CNamed n => (L'.TNamed n, loc) 68 | L.CNamed n => (L'.TNamed n, loc)
68 | L.CFfi mx => (L'.TFfi mx, loc) 69 | L.CFfi mx => (L'.TFfi mx, loc)
69 | L.CApp _ => poly () 70 | L.CApp _ => poly ()
122 end 123 end
123 124
124 val attrifyExp = fooifyExp "attr" 125 val attrifyExp = fooifyExp "attr"
125 val urlifyExp = fooifyExp "url" 126 val urlifyExp = fooifyExp "url"
126 127
128 datatype 'a failable_search =
129 Found of 'a
130 | NotFound
131 | Error
132
127 fun monoExp env (all as (e, loc)) = 133 fun monoExp env (all as (e, loc)) =
128 let 134 let
129 fun poly () = 135 fun poly () =
130 (E.errorAt loc "Unsupported expression"; 136 (E.errorAt loc "Unsupported expression";
131 Print.eprefaces' [("Expression", CorePrint.p_exp env all)]; 137 Print.eprefaces' [("Expression", CorePrint.p_exp env all)];
174 tag), _), 180 tag), _),
175 xml) => 181 xml) =>
176 let 182 let
177 fun getTag' (e, _) = 183 fun getTag' (e, _) =
178 case e of 184 case e of
179 L.EFfi ("Basis", tag) => tag 185 L.EFfi ("Basis", tag) => (tag, [])
180 | L.ECApp (e, _) => getTag' e 186 | L.ECApp (e, t) => let
187 val (tag, ts) = getTag' e
188 in
189 (tag, ts @ [t])
190 end
181 | _ => (E.errorAt loc "Non-constant XML tag"; 191 | _ => (E.errorAt loc "Non-constant XML tag";
182 Print.eprefaces' [("Expression", CorePrint.p_exp env tag)]; 192 Print.eprefaces' [("Expression", CorePrint.p_exp env tag)];
183 "") 193 ("", []))
184 194
185 fun getTag (e, _) = 195 fun getTag (e, _) =
186 case e of 196 case e of
187 L.EFfiApp ("Basis", tag, [(L.ERecord [], _)]) => tag 197 L.EFfiApp ("Basis", tag, [(L.ERecord [], _)]) => (tag, [])
188 | L.EApp (e, (L.ERecord [], _)) => getTag' e 198 | L.EApp (e, (L.ERecord [], _)) => getTag' e
189 | _ => (E.errorAt loc "Non-constant XML tag"; 199 | _ => (E.errorAt loc "Non-constant XML tag";
190 Print.eprefaces' [("Expression", CorePrint.p_exp env tag)]; 200 Print.eprefaces' [("Expression", CorePrint.p_exp env tag)];
191 "") 201 ("", []))
192 202
193 val tag = getTag tag 203 val (tag, targs) = getTag tag
194 204
195 val attrs = monoExp env attrs 205 val attrs = monoExp env attrs
196 206
197 val tagStart = 207 fun tagStart tag =
198 case #1 attrs of 208 case #1 attrs of
199 L'.ERecord xes => 209 L'.ERecord xes =>
200 let 210 let
201 fun lowercaseFirst "" = "" 211 fun lowercaseFirst "" = ""
202 | lowercaseFirst s = str (Char.toLower (String.sub (s, 0))) ^ String.extract (s, 1, NONE) 212 | lowercaseFirst s = str (Char.toLower (String.sub (s, 0)))
213 ^ String.extract (s, 1, NONE)
203 214
204 val s = (L'.EPrim (Prim.String (String.concat ["<", tag])), loc) 215 val s = (L'.EPrim (Prim.String (String.concat ["<", tag])), loc)
205 in 216 in
206 foldl (fn ((x, e, t), s) => 217 foldl (fn ((x, e, t), s) =>
207 let 218 let
208 val xp = " " ^ lowercaseFirst x ^ "=\"" 219 val xp = " " ^ lowercaseFirst x ^ "=\""
209 220
210 val fooify = 221 val fooify =
211 case x of 222 case x of
212 "Link" => urlifyExp 223 "Link" => urlifyExp
224 | "Action" => urlifyExp
213 | _ => attrifyExp 225 | _ => attrifyExp
214 in 226 in
215 (L'.EStrcat (s, 227 (L'.EStrcat (s,
216 (L'.EStrcat ((L'.EPrim (Prim.String xp), loc), 228 (L'.EStrcat ((L'.EPrim (Prim.String xp), loc),
217 (L'.EStrcat (fooify env (e, t), 229 (L'.EStrcat (fooify env (e, t),
218 (L'.EPrim (Prim.String "\""), loc)), 230 (L'.EPrim (Prim.String "\""),
231 loc)),
219 loc)), 232 loc)),
220 loc)), loc) 233 loc)), loc)
221 end) 234 end)
222 s xes 235 s xes
223 end 236 end
224 | _ => raise Fail "Attributes!" 237 | _ => raise Fail "Non-record attributes!"
225 238
226 fun normal () = 239 fun input typ =
227 (L'.EStrcat ((L'.EStrcat (tagStart, (L'.EPrim (Prim.String ">"), loc)), loc), 240 case targs of
228 (L'.EStrcat (monoExp env xml, 241 [(L.CName name, _)] =>
229 (L'.EPrim (Prim.String (String.concat ["</", tag, ">"])), loc)), loc)), 242 (L'.EStrcat (tagStart "input",
230 loc) 243 (L'.EPrim (Prim.String (" type=\"" ^ typ ^ "\" name=\"" ^ name ^ "\"/>")),
231 244 loc)), loc)
232 245 | _ => (Print.prefaces "Targs" (map (fn t => ("T", CorePrint.p_con env t)) targs);
246 raise Fail "No named passed to input tag")
233 in 247 in
234 case xml of 248 case tag of
235 (L.EApp ((L.ECApp ( 249 "submit" => (L'.EPrim (Prim.String "<input type=\"submit\"/>"), loc)
236 (L.ECApp ((L.EFfi ("Basis", "cdata"), _), 250
237 _), _), 251 | "textbox" =>
238 _), _), 252 (case targs of
239 (L.EPrim (Prim.String s), _)), _) => 253 [_, (L.CName name, _)] =>
240 if CharVector.all Char.isSpace s then 254 (L'.EStrcat (tagStart "input",
241 (L'.EStrcat (tagStart, (L'.EPrim (Prim.String "/>"), loc)), loc) 255 (L'.EPrim (Prim.String (" name=\"" ^ name ^ "\"/>")),
242 else 256 loc)), loc)
243 normal () 257 | _ => (Print.prefaces "Targs" (map (fn t => ("T", CorePrint.p_con env t)) targs);
244 | _ => normal () 258 raise Fail "No named passed to input tag"))
259
260 | _ =>
261 let
262 val tagStart = tagStart tag
263
264 fun normal () =
265 (L'.EStrcat ((L'.EStrcat (tagStart, (L'.EPrim (Prim.String ">"), loc)), loc),
266 (L'.EStrcat (monoExp env xml,
267 (L'.EPrim (Prim.String (String.concat ["</", tag, ">"])),
268 loc)), loc)),
269 loc)
270 in
271 case xml of
272 (L.EApp ((L.ECApp (
273 (L.ECApp ((L.EFfi ("Basis", "cdata"), _),
274 _), _),
275 _), _),
276 (L.EPrim (Prim.String s), _)), _) =>
277 if CharVector.all Char.isSpace s then
278 (L'.EStrcat (tagStart, (L'.EPrim (Prim.String "/>"), loc)), loc)
279 else
280 normal ()
281 | _ => normal ()
282 end
245 end 283 end
246 284
247 | L.EApp ((L.ECApp ( 285 | L.EApp ((L.ECApp (
248 (L.ECApp ((L.EFfi ("Basis", "lform"), _), _), _), 286 (L.ECApp ((L.EFfi ("Basis", "lform"), _), _), _),
249 _), _), 287 _), _),
250 xml) => 288 xml) =>
251 (L'.EStrcat ((L'.EPrim (Prim.String "<form>"), loc), 289 let
252 (L'.EStrcat (monoExp env xml, 290 fun findSubmit (e, _) =
253 (L'.EPrim (Prim.String "</form>"), loc)), loc)), loc) 291 case e of
292 L.EApp (
293 (L.EApp (
294 (L.ECApp (
295 (L.ECApp (
296 (L.ECApp (
297 (L.ECApp (
298 (L.EFfi ("Basis", "join"),
299 _), _), _),
300 _), _),
301 _), _),
302 _), _),
303 xml1), _),
304 xml2) => (case findSubmit xml1 of
305 Error => Error
306 | NotFound => findSubmit xml2
307 | Found e =>
308 case findSubmit xml2 of
309 NotFound => Found e
310 | _ => Error)
311 | L.EApp (
312 (L.EApp (
313 (L.EApp (
314 (L.ECApp (
315 (L.ECApp (
316 (L.ECApp (
317 (L.ECApp (
318 (L.ECApp (
319 (L.ECApp (
320 (L.ECApp (
321 (L.ECApp (
322 (L.EFfi ("Basis", "tag"),
323 _), _), _), _), _), _), _), _), _), _), _), _), _), _), _), _), _),
324 attrs), _),
325 _), _),
326 xml) =>
327 (case #1 attrs of
328 L.ERecord xes =>
329 (case ListUtil.search (fn ((L.CName "Action", _), e, t) => SOME (e, t)
330 | _ => NONE) xes of
331 NONE => findSubmit xml
332 | SOME et =>
333 case findSubmit xml of
334 NotFound => Found et
335 | _ => Error)
336 | _ => findSubmit xml)
337 | _ => NotFound
338
339 val (action, actionT) = case findSubmit xml of
340 NotFound => raise Fail "No submit found"
341 | Error => raise Fail "Not ready for multi-submit lforms yet"
342 | Found et => et
343
344 val actionT = monoType env actionT
345 val action = monoExp env action
346 in
347 (L'.EStrcat ((L'.EStrcat ((L'.EPrim (Prim.String "<form action=\""), loc),
348 (L'.EStrcat (urlifyExp env (action, actionT),
349 (L'.EPrim (Prim.String "\">"), loc)), loc)), loc),
350 (L'.EStrcat (monoExp env xml,
351 (L'.EPrim (Prim.String "</form>"), loc)), loc)), loc)
352 end
254 353
255 | L.EApp (e1, e2) => (L'.EApp (monoExp env e1, monoExp env e2), loc) 354 | L.EApp (e1, e2) => (L'.EApp (monoExp env e1, monoExp env e2), loc)
256 | L.EAbs (x, dom, ran, e) => 355 | L.EAbs (x, dom, ran, e) =>
257 (L'.EAbs (x, monoType env dom, monoType env ran, monoExp (Env.pushERel env x dom) e), loc) 356 (L'.EAbs (x, monoType env dom, monoType env ran, monoExp (Env.pushERel env x dom) e), loc)
258 | L.ECApp _ => poly () 357 | L.ECApp _ => poly ()