comparison src/jscomp.sml @ 638:3ee6bb48f6e8

RPC returning an enumeration
author Adam Chlipala <adamc@hcoop.net>
date Sun, 08 Mar 2009 12:37:42 -0400
parents 5891f47d7cff
children b98f547a6a45
comparison
equal deleted inserted replaced
637:24fd1edfcaa3 638:3ee6bb48f6e8
62 type state = { 62 type state = {
63 decls : decl list, 63 decls : decl list,
64 script : string list, 64 script : string list,
65 included : IS.set, 65 included : IS.set,
66 injectors : int IM.map, 66 injectors : int IM.map,
67 decoders : int IM.map,
67 maxName : int 68 maxName : int
68 } 69 }
69 70
70 fun varDepth (e, _) = 71 fun varDepth (e, _) =
71 case e of 72 case e of
249 | TDatatype (n, ref (dk, cs)) => 250 | TDatatype (n, ref (dk, cs)) =>
250 (case IM.find (#injectors st, n) of 251 (case IM.find (#injectors st, n) of
251 SOME n' => ((EApp ((ENamed n', loc), e), loc), st) 252 SOME n' => ((EApp ((ENamed n', loc), e), loc), st)
252 | NONE => 253 | NONE =>
253 let 254 let
254 val dk = ElabUtil.classifyDatatype cs
255
256 val n' = #maxName st 255 val n' = #maxName st
257 val st = {decls = #decls st, 256 val st = {decls = #decls st,
258 script = #script st, 257 script = #script st,
259 included = #included st, 258 included = #included st,
260 injectors = IM.insert (#injectors st, n, n'), 259 injectors = IM.insert (#injectors st, n, n'),
260 decoders = #decoders st,
261 maxName = n' + 1} 261 maxName = n' + 1}
262 262
263 val (pes, st) = ListUtil.foldlMap 263 val (pes, st) = ListUtil.foldlMap
264 (fn ((_, cn, NONE), st) => 264 (fn ((_, cn, NONE), st) =>
265 (((PCon (dk, PConVar cn, NONE), loc), 265 (((PCon (dk, PConVar cn, NONE), loc),
273 in 273 in
274 (((PCon (dk, PConVar cn, SOME (PVar ("x", t), loc)), loc), 274 (((PCon (dk, PConVar cn, SOME (PVar ("x", t), loc)), loc),
275 case dk of 275 case dk of
276 Option => 276 Option =>
277 if isNullable t then 277 if isNullable t then
278 strcat loc [str loc "{_v:", 278 strcat loc [str loc "{v:",
279 e, 279 e,
280 str loc "}"] 280 str loc "}"]
281 else 281 else
282 e 282 e
283 | _ => strcat loc [str loc ("{n:" ^ Int.toString cn 283 | _ => strcat loc [str loc ("{n:" ^ Int.toString cn
296 val st = {decls = (DValRec [("jsify", n', (TFun (t, s), loc), 296 val st = {decls = (DValRec [("jsify", n', (TFun (t, s), loc),
297 body, "jsify")], loc) :: #decls st, 297 body, "jsify")], loc) :: #decls st,
298 script = #script st, 298 script = #script st,
299 included = #included st, 299 included = #included st,
300 injectors = #injectors st, 300 injectors = #injectors st,
301 decoders= #decoders st,
301 maxName = #maxName st} 302 maxName = #maxName st}
302 in 303 in
303 ((EApp ((ENamed n', loc), e), loc), st) 304 ((EApp ((ENamed n', loc), e), loc), st)
304 end) 305 end)
305 306
319 end 320 end
320 | TRecord ((x, t) :: xts) => 321 | TRecord ((x, t) :: xts) =>
321 let 322 let
322 val (e', st) = unurlifyExp loc (t, st) 323 val (e', st) = unurlifyExp loc (t, st)
323 val (es, st) = ListUtil.foldlMap 324 val (es, st) = ListUtil.foldlMap
324 (fn ((x, t), st) => 325 (fn ((x, t), st) =>
325 let 326 let
326 val (e, st) = unurlifyExp loc (t, st) 327 val (e, st) = unurlifyExp loc (t, st)
327 in 328 in
328 (",_" ^ x ^ ":" ^ e, st) 329 (",_" ^ x ^ ":" ^ e, st)
329 end) 330 end)
330 st xts 331 st xts
331 in 332 in
332 (String.concat ("{_" 333 (String.concat ("{_"
333 :: x 334 :: x
334 :: ":" 335 :: ":"
335 :: e' 336 :: e'
341 | TFfi ("Basis", "int") => ("parseInt(t[i++])", st) 342 | TFfi ("Basis", "int") => ("parseInt(t[i++])", st)
342 | TFfi ("Basis", "float") => ("parseFloat(t[i++])", st) 343 | TFfi ("Basis", "float") => ("parseFloat(t[i++])", st)
343 344
344 | TFfi ("Basis", "bool") => ("t[i++] == \"True\"", st) 345 | TFfi ("Basis", "bool") => ("t[i++] == \"True\"", st)
345 346
346 | TOption t => raise Fail "!!" (* 347 | TOption t =>
347 let 348 let
348 val (e', st) = quoteExp loc t ((ERel 0, loc), st) 349 val (e, st) = unurlifyExp loc (t, st)
350 val e = if isNullable t then
351 "{v:" ^ e ^ "}"
352 else
353 e
349 in 354 in
350 ((ECase (e, 355 ("(uu=t[i++],uu==\"Some\"?" ^ e ^ ":null)", st)
351 [((PNone t, loc), 356 end
352 str loc "null"), 357
353 ((PSome (t, (PVar ("x", t), loc)), loc), 358 | TDatatype (n, ref (dk, cs)) =>
354 if isNullable t then 359 (case IM.find (#decoders st, n) of
355 strcat loc [str loc "{v:", e', str loc "}"] 360 SOME n' => ("(tmp=_n" ^ Int.toString n' ^ "(t,i),i=tmp._1,tmp._2)", st)
356 else
357 e')],
358 {disc = (TOption t, loc),
359 result = (TFfi ("Basis", "string"), loc)}), loc),
360 st)
361 end*)
362
363 | TDatatype (n, ref (dk, cs)) => raise Fail "!!" (*
364 (case IM.find (#injectors st, n) of
365 SOME n' => ((EApp ((ENamed n', loc), e), loc), st)
366 | NONE => 361 | NONE =>
367 let 362 let
368 val dk = ElabUtil.classifyDatatype cs
369
370 val n' = #maxName st 363 val n' = #maxName st
371 val st = {decls = #decls st, 364 val st = {decls = #decls st,
372 script = #script st, 365 script = #script st,
373 included = #included st, 366 included = #included st,
374 injectors = IM.insert (#injectors st, n, n'), 367 injectors = #injectors st,
368 decoders = IM.insert (#decoders st, n, n'),
375 maxName = n' + 1} 369 maxName = n' + 1}
376 370
377 val (pes, st) = ListUtil.foldlMap 371 val (e, st) = foldl (fn ((x, cn, NONE), (e, st)) =>
378 (fn ((_, cn, NONE), st) => 372 ("x==\"" ^ x ^ "\"?"
379 (((PCon (dk, PConVar cn, NONE), loc), 373 ^ (case dk of
380 case dk of 374 Option => "null"
381 Option => str loc "null" 375 | _ => Int.toString cn)
382 | _ => str loc (Int.toString cn)), 376 ^ ":" ^ e,
383 st) 377 st)
384 | ((_, cn, SOME t), st) => 378 | ((x, cn, SOME t), (e, st)) =>
385 let 379 let
386 val (e, st) = quoteExp loc t ((ERel 0, loc), st) 380 val (e', st) = unurlifyExp loc (t, st)
387 in 381 in
388 (((PCon (dk, PConVar cn, SOME (PVar ("x", t), loc)), loc), 382 ("x==\"" ^ x ^ "\"?"
389 case dk of 383 ^ (case dk of
390 Option => 384 Option =>
391 if isNullable t then 385 if isNullable t then
392 strcat loc [str loc "{_v:", 386 "{v:" ^ e' ^ "}"
393 e, 387 else
394 str loc "}"] 388 e'
395 else 389 | _ => "{n:" ^ Int.toString cn ^ ",v:" ^ e' ^ "}")
396 e 390 ^ ":" ^ e,
397 | _ => strcat loc [str loc ("{n:" ^ Int.toString cn
398 ^ ",v:"),
399 e,
400 str loc "}"]),
401 st) 391 st)
402 end) 392 end)
403 st cs 393 ("pf()", st) cs
404 394
405 val s = (TFfi ("Basis", "string"), loc) 395 val body = "function _n" ^ Int.toString n' ^ "(t,i){var x=t[i++];var r="
406 val body = (ECase ((ERel 0, loc), pes, 396 ^ e ^ ";return {_1:i,_2:r}}\n\n"
407 {disc = t, result = s}), loc) 397
408 val body = (EAbs ("x", t, s, body), loc) 398 val st = {decls = #decls st,
409 399 script = body :: #script st,
410 val st = {decls = (DValRec [("jsify", n', (TFun (t, s), loc),
411 body, "jsify")], loc) :: #decls st,
412 script = #script st,
413 included = #included st, 400 included = #included st,
414 injectors = #injectors st, 401 injectors = #injectors st,
402 decoders = #decoders st,
415 maxName = #maxName st} 403 maxName = #maxName st}
416 in 404 in
417 ((EApp ((ENamed n', loc), e), loc), st) 405 ("(tmp=_n" ^ Int.toString n' ^ "(t,i),i=tmp._1,tmp._2)", st)
418 end)*) 406 end)
419 407
420 | _ => (EM.errorAt loc "Don't know how to unurlify type in JavaScript"; 408 | _ => (EM.errorAt loc "Don't know how to unurlify type in JavaScript";
421 Print.prefaces "Can't unurlify" [("t", MonoPrint.p_typ MonoEnv.empty t)]; 409 Print.prefaces "Can't unurlify" [("t", MonoPrint.p_typ MonoEnv.empty t)];
422 ("ERROR", st)) 410 ("ERROR", st))
423 411
600 let 588 let
601 val st = {decls = #decls st, 589 val st = {decls = #decls st,
602 script = #script st, 590 script = #script st,
603 included = IS.add (#included st, n), 591 included = IS.add (#included st, n),
604 injectors = #injectors st, 592 injectors = #injectors st,
593 decoders = #decoders st,
605 maxName = #maxName st} 594 maxName = #maxName st}
606 595
607 val (e, st) = jsExp mode skip [] 0 (e, st) 596 val (e, st) = jsExp mode skip [] 0 (e, st)
608 val e = deStrcat 0 e 597 val e = deStrcat 0 e
609 598
611 in 600 in
612 {decls = #decls st, 601 {decls = #decls st,
613 script = sc :: #script st, 602 script = sc :: #script st,
614 included = #included st, 603 included = #included st,
615 injectors = #injectors st, 604 injectors = #injectors st,
605 decoders= #decoders st,
616 maxName = #maxName st} 606 maxName = #maxName st}
617 end 607 end
618 in 608 in
619 (str ("_n" ^ Int.toString n), st) 609 (str ("_n" ^ Int.toString n), st)
620 end 610 end
984 (List.revAppend (#decls st, [d]), 974 (List.revAppend (#decls st, [d]),
985 {decls = [], 975 {decls = [],
986 script = #script st, 976 script = #script st,
987 included = #included st, 977 included = #included st,
988 injectors = #injectors st, 978 injectors = #injectors st,
979 decoders = #decoders st,
989 maxName = #maxName st}) 980 maxName = #maxName st})
990 end 981 end
991 982
992 val (ds, st) = ListUtil.foldlMapConcat doDecl 983 val (ds, st) = ListUtil.foldlMapConcat doDecl
993 {decls = [], 984 {decls = [],
994 script = [], 985 script = [],
995 included = IS.empty, 986 included = IS.empty,
996 injectors = IM.empty, 987 injectors = IM.empty,
988 decoders = IM.empty,
997 maxName = U.File.maxName file + 1} 989 maxName = U.File.maxName file + 1}
998 file 990 file
999 991
1000 val inf = TextIO.openIn (OS.Path.joinDirFile {dir = Config.libJs, file = "urweb.js"}) 992 val inf = TextIO.openIn (OS.Path.joinDirFile {dir = Config.libJs, file = "urweb.js"})
1001 fun lines acc = 993 fun lines acc =