comparison src/jscomp.sml @ 815:493f44759879

Redo Jscomp
author Adam Chlipala <adamc@hcoop.net>
date Sun, 17 May 2009 18:41:43 -0400
parents 7b380e2b9e68
children 395a5d450cc0
comparison
equal deleted inserted replaced
814:3f3b211f9bca 815:493f44759879
124 andalso cu (inner + 2) body 124 andalso cu (inner + 2) body
125 andalso cu inner initial 125 andalso cu inner initial
126 | EDml e => cu inner e 126 | EDml e => cu inner e
127 | ENextval e => cu inner e 127 | ENextval e => cu inner e
128 | EUnurlify (e, _) => cu inner e 128 | EUnurlify (e, _) => cu inner e
129 | EJavaScript (_, e, _) => cu inner e 129 | EJavaScript (_, e) => cu inner e
130 | ESignalReturn e => cu inner e 130 | ESignalReturn e => cu inner e
131 | ESignalBind (e1, e2) => cu inner e1 andalso cu inner e2 131 | ESignalBind (e1, e2) => cu inner e1 andalso cu inner e2
132 | ESignalSource e => cu inner e 132 | ESignalSource e => cu inner e
133 | EServerCall (e, ek, _, _) => cu inner e andalso cu inner ek 133 | EServerCall (e, ek, _, _) => cu inner e andalso cu inner ek
134 | ERecv (e, ek, _) => cu inner e andalso cu inner ek 134 | ERecv (e, ek, _) => cu inner e andalso cu inner ek
167 bind = fn (inner, b) => 167 bind = fn (inner, b) =>
168 case b of 168 case b of
169 U.Exp.RelE _ => inner+1 169 U.Exp.RelE _ => inner+1
170 | _ => inner} 170 | _ => inner}
171 171
172 val desourceify' = 172 exception CantEmbed of typ
173 U.Exp.map {typ = fn t => t, 173
174 exp = fn e =>
175 case e of
176 EJavaScript (_, e, _) => #1 e
177 | _ => e}
178
179 val desourceify =
180 U.File.map {typ = fn t => t,
181 exp = fn e =>
182 case e of
183 EJavaScript (m, e, eo) => EJavaScript (m, desourceify' e, eo)
184 | _ => e,
185 decl = fn d => d}
186
187 fun process file = 174 fun process file =
188 let 175 let
189 val (someTs, nameds) = 176 val (someTs, nameds) =
190 foldl (fn ((DVal (_, n, t, e, _), _), (someTs, nameds)) => (someTs, IM.insert (nameds, n, e)) 177 foldl (fn ((DVal (_, n, t, e, _), _), (someTs, nameds)) => (someTs, IM.insert (nameds, n, e))
191 | ((DValRec vis, _), (someTs, nameds)) => 178 | ((DValRec vis, _), (someTs, nameds)) =>
385 maxName = #maxName st} 372 maxName = #maxName st}
386 in 373 in
387 ((EApp ((ENamed n', loc), e), loc), st) 374 ((EApp ((ENamed n', loc), e), loc), st)
388 end) 375 end)
389 376
390 | _ => (EM.errorAt loc "Don't know how to embed type in JavaScript"; 377 | _ => raise CantEmbed t
378 (*(EM.errorAt loc "Don't know how to embed type in JavaScript";
391 Print.prefaces "Can't embed" [("t", MonoPrint.p_typ MonoEnv.empty t)]; 379 Print.prefaces "Can't embed" [("t", MonoPrint.p_typ MonoEnv.empty t)];
392 (str loc "ERROR", st)) 380 (str loc "ERROR", st))*)
393 381
394 fun unurlifyExp loc (t : typ, st) = 382 fun unurlifyExp loc (t : typ, st) =
395 case #1 t of 383 case #1 t of
396 TRecord [] => ("null", st) 384 TRecord [] => ("null", st)
397 | TRecord [(x, t)] => 385 | TRecord [(x, t)] =>
771 in 759 in
772 (str name, st) 760 (str name, st)
773 end 761 end
774 | EFfiApp (m, x, args) => 762 | EFfiApp (m, x, args) =>
775 let 763 let
776 val args =
777 case (m, x, args) of
778 ("Basis", "new_client_source", [(EJavaScript (_, e, _), _)]) =>
779 (foundJavaScript := true; [e])
780 | ("Basis", "set_client_source", [e1, (EJavaScript (_, e2, _), _)]) =>
781 (foundJavaScript := true; [e1, e2])
782 | _ => args
783
784 val name = case Settings.jsFunc (m, x) of 764 val name = case Settings.jsFunc (m, x) of
785 NONE => (EM.errorAt loc ("Unsupported FFI function " 765 NONE => (EM.errorAt loc ("Unsupported FFI function "
786 ^ x ^ " in JavaScript"); 766 ^ x ^ " in JavaScript");
787 "ERROR") 767 "ERROR")
788 | SOME s => s 768 | SOME s => s
983 str ",", 963 str ",",
984 e2, 964 e2,
985 str ")"], st) 965 str ")"], st)
986 end 966 end
987 967
988 | EJavaScript (Source _, _, SOME _) => 968 | EJavaScript (Source _, e) =>
989 (foundJavaScript := true; 969 (foundJavaScript := true;
990 (e, st)) 970 jsE inner (e, st))
991 | EJavaScript (_, _, SOME e) => 971 | EJavaScript (_, e) =>
992 (foundJavaScript := true; 972 let
993 (strcat [str "cs(function(){return ", 973 val (e, st) = jsE inner (e, st)
994 compact inner e, 974 in
995 str "})"], 975 foundJavaScript := true;
996 st)) 976 (strcat [str "cs(function(){return ",
977 compact inner e,
978 str "})"],
979 st)
980 end
997 981
998 | EClosure _ => unsupported "EClosure" 982 | EClosure _ => unsupported "EClosure"
999 | EQuery _ => unsupported "Query" 983 | EQuery _ => unsupported "Query"
1000 | EDml _ => unsupported "DML" 984 | EDml _ => unsupported "DML"
1001 | ENextval _ => unsupported "Nextval" 985 | ENextval _ => unsupported "Nextval"
1002 | EUnurlify _ => unsupported "EUnurlify" 986 | EUnurlify _ => unsupported "EUnurlify"
1003 | EReturnBlob _ => unsupported "EUnurlify" 987 | EReturnBlob _ => unsupported "EUnurlify"
1004 | EJavaScript (_, e, _) =>
1005 let
1006 val (e, st) = jsE inner (e, st)
1007 in
1008 foundJavaScript := true;
1009 (strcat [str "cs(function(){return ",
1010 e,
1011 str "})"],
1012 st)
1013 end
1014 988
1015 | ESignalReturn e => 989 | ESignalReturn e =>
1016 let 990 let
1017 val (e, st) = jsE inner (e, st) 991 val (e, st) = jsE inner (e, st)
1018 in 992 in
1092 end 1066 end
1093 in 1067 in
1094 jsE 1068 jsE
1095 end 1069 end
1096 1070
1097 val decl : state -> decl -> decl * state = 1071
1098 U.Decl.foldMapB {typ = fn x => x, 1072 fun patBinds ((p, _), env) =
1099 exp = fn (env, e, st) => 1073 case p of
1100 let 1074 PWild => env
1101 fun doCode m env e = 1075 | PVar (_, t) => t :: env
1102 let 1076 | PPrim _ => env
1103 val len = length env 1077 | PCon (_, _, NONE) => env
1104 fun str s = (EPrim (Prim.String s), #2 e) 1078 | PCon (_, _, SOME p) => patBinds (p, env)
1105 1079 | PRecord xpts => foldl (fn ((_, p, _), env) => patBinds (p, env)) env xpts
1106 val locals = List.tabulate 1080 | PNone _ => env
1107 (varDepth e, 1081 | PSome (_, p) => patBinds (p, env)
1108 fn i => str ("var _" ^ Int.toString (len + i) ^ ";")) 1082
1109 val old = e 1083 fun exp outer (e as (_, loc), st) =
1110 val (e, st) = jsExp m env 0 (e, st) 1084 ((*Print.preface ("exp", MonoPrint.p_exp MonoEnv.empty e);*)
1111 val e = 1085 case #1 e of
1112 case locals of 1086 EPrim _ => (e, st)
1113 [] => e 1087 | ERel _ => (e, st)
1114 | _ => 1088 | ENamed _ => (e, st)
1115 strcat (#2 e) (str "(function(){" 1089 | ECon (_, _, NONE) => (e, st)
1116 :: locals 1090 | ECon (dk, pc, SOME e) =>
1117 @ [str "return ", 1091 let
1118 e, 1092 val (e, st) = exp outer (e, st)
1119 str "}())"]) 1093 in
1120 in 1094 ((ECon (dk, pc, SOME e), loc), st)
1121 (*Print.prefaces "jsify" [("old", MonoPrint.p_exp MonoEnv.empty old), 1095 end
1122 ("new", MonoPrint.p_exp MonoEnv.empty e)];*) 1096 | ENone _ => (e, st)
1123 (EJavaScript (m, old, SOME e), st) 1097 | ESome (t, e) =>
1124 end 1098 let
1125 in 1099 val (e, st) = exp outer (e, st)
1126 case e of 1100 in
1127 (*EJavaScript (m as Source t, orig, NONE) => 1101 ((ESome (t, e), loc), st)
1128 let 1102 end
1129 val loc = #2 orig 1103 | EFfi _ => (e, st)
1130 val (e, st) = doCode m (t :: env) (ERel 0, loc) 1104 | EFfiApp (m, x, es) =>
1131 in 1105 let
1132 (ELet ("x", t, orig, (e, loc)), st) 1106 val (es, st) = ListUtil.foldlMap (exp outer) st es
1133 end 1107 in
1134 |*) EJavaScript (m, orig, NONE) => 1108 ((EFfiApp (m, x, es), loc), st)
1135 (foundJavaScript := true; 1109 end
1136 doCode m env orig) 1110 | EApp (e1, e2) =>
1137 | _ => (e, st) 1111 let
1138 end, 1112 val (e1, st) = exp outer (e1, st)
1139 decl = fn (_, e, st) => (e, st), 1113 val (e2, st) = exp outer (e2, st)
1140 bind = fn (env, U.Decl.RelE (_, t)) => t :: env 1114 in
1141 | (env, _) => env} 1115 ((EApp (e1, e2), loc), st)
1142 [] 1116 end
1117 | EAbs (x, dom, ran, e) =>
1118 let
1119 val (e, st) = exp (dom :: outer) (e, st)
1120 in
1121 ((EAbs (x, dom, ran, e), loc), st)
1122 end
1123
1124 | EUnop (s, e) =>
1125 let
1126 val (e, st) = exp outer (e, st)
1127 in
1128 ((EUnop (s, e), loc), st)
1129 end
1130 | EBinop (s, e1, e2) =>
1131 let
1132 val (e1, st) = exp outer (e1, st)
1133 val (e2, st) = exp outer (e2, st)
1134 in
1135 ((EBinop (s, e1, e2), loc), st)
1136 end
1137
1138 | ERecord xets =>
1139 let
1140 val (xets, st) = ListUtil.foldlMap (fn ((x, e, t), st) =>
1141 let
1142 val (e, st) = exp outer (e, st)
1143 in
1144 ((x, e, t), st)
1145 end) st xets
1146 in
1147 ((ERecord xets, loc), st)
1148 end
1149 | EField (e, s) =>
1150 let
1151 val (e, st) = exp outer (e, st)
1152 in
1153 ((EField (e, s), loc), st)
1154 end
1155
1156 | ECase (e, pes, ts) =>
1157 let
1158 val (e, st) = exp outer (e, st)
1159 val (pes, st) = ListUtil.foldlMap (fn ((p, e), st) =>
1160 let
1161 val (e, st) = exp (patBinds (p, outer)) (e, st)
1162 in
1163 ((p, e), st)
1164 end) st pes
1165 in
1166 ((ECase (e, pes, ts), loc), st)
1167 end
1168
1169 | EStrcat (e1, e2) =>
1170 let
1171 val (e1, st) = exp outer (e1, st)
1172 val (e2, st) = exp outer (e2, st)
1173 in
1174 ((EStrcat (e1, e2), loc), st)
1175 end
1176
1177 | EError (e, t) =>
1178 let
1179 val (e, st) = exp outer (e, st)
1180 in
1181 ((EError (e, t), loc), st)
1182 end
1183 | EReturnBlob {blob, mimeType, t} =>
1184 let
1185 val (blob, st) = exp outer (blob, st)
1186 val (mimeType, st) = exp outer (mimeType, st)
1187 in
1188 ((EReturnBlob {blob = blob, mimeType = mimeType, t = t}, loc), st)
1189 end
1190
1191 | EWrite e =>
1192 let
1193 val (e, st) = exp outer (e, st)
1194 in
1195 ((EWrite e, loc), st)
1196 end
1197 | ESeq (e1, e2) =>
1198 let
1199 val (e1, st) = exp outer (e1, st)
1200 val (e2, st) = exp outer (e2, st)
1201 in
1202 ((ESeq (e1, e2), loc), st)
1203 end
1204 | ELet (x, t, e1, e2) =>
1205 let
1206 val (e1, st) = exp outer (e1, st)
1207 val (e2, st) = exp (t :: outer) (e2, st)
1208 in
1209 ((ELet (x, t, e1, e2), loc), st)
1210 end
1211
1212 | EClosure (n, es) =>
1213 let
1214 val (es, st) = ListUtil.foldlMap (exp outer) st es
1215 in
1216 ((EClosure (n, es), loc), st)
1217 end
1218
1219 | EQuery {exps, tables, state, query, body, initial} =>
1220 let
1221 val (query, st) = exp outer (query, st)
1222 val (body, st) = exp outer (body, st)
1223 val (initial, st) = exp outer (initial, st)
1224 in
1225 ((EQuery {exps = exps, tables = tables, state = state,
1226 query = query, body = body, initial = initial}, loc), st)
1227 end
1228 | EDml e =>
1229 let
1230 val (e, st) = exp outer (e, st)
1231 in
1232 ((EDml e, loc), st)
1233 end
1234 | ENextval e =>
1235 let
1236 val (e, st) = exp outer (e, st)
1237 in
1238 ((ENextval e, loc), st)
1239 end
1240
1241 | EUnurlify (e, t) =>
1242 let
1243 val (e, st) = exp outer (e, st)
1244 in
1245 ((EUnurlify (e, t), loc), st)
1246 end
1247
1248 | EJavaScript (m, e') =>
1249 (let
1250 val len = length outer
1251 fun str s = (EPrim (Prim.String s), #2 e')
1252
1253 val locals = List.tabulate
1254 (varDepth e',
1255 fn i => str ("var _" ^ Int.toString (len + i) ^ ";"))
1256
1257 val (e', st) = jsExp m outer 0 (e', st)
1258
1259 val e' =
1260 case locals of
1261 [] => e'
1262 | _ =>
1263 strcat (#2 e') (str "(function(){"
1264 :: locals
1265 @ [str "return ",
1266 e',
1267 str "}())"])
1268 in
1269 (e', st)
1270 end handle CantEmbed _ => (e, st))
1271
1272 | ESignalReturn e =>
1273 let
1274 val (e, st) = exp outer (e, st)
1275 in
1276 ((ESignalReturn e, loc), st)
1277 end
1278 | ESignalBind (e1, e2) =>
1279 let
1280 val (e1, st) = exp outer (e1, st)
1281 val (e2, st) = exp outer (e2, st)
1282 in
1283 ((ESignalBind (e1, e2), loc), st)
1284 end
1285 | ESignalSource e =>
1286 let
1287 val (e, st) = exp outer (e, st)
1288 in
1289 ((ESignalSource e, loc), st)
1290 end
1291
1292 | EServerCall (e1, e2, t, ef) =>
1293 let
1294 val (e1, st) = exp outer (e1, st)
1295 val (e2, st) = exp outer (e2, st)
1296 in
1297 ((EServerCall (e1, e2, t, ef), loc), st)
1298 end
1299 | ERecv (e1, e2, t) =>
1300 let
1301 val (e1, st) = exp outer (e1, st)
1302 val (e2, st) = exp outer (e2, st)
1303 in
1304 ((ERecv (e1, e2, t), loc), st)
1305 end
1306 | ESleep (e1, e2) =>
1307 let
1308 val (e1, st) = exp outer (e1, st)
1309 val (e2, st) = exp outer (e2, st)
1310 in
1311 ((ESleep (e1, e2), loc), st)
1312 end)
1313
1314 fun decl (d as (_, loc), st) =
1315 case #1 d of
1316 DVal (x, n, t, e, s) =>
1317 let
1318 val (e, st) = exp [] (e, st)
1319 in
1320 ((DVal (x, n, t, e, s), loc), st)
1321 end
1322 | DValRec vis =>
1323 let
1324 val (vis, st) = ListUtil.foldlMap (fn ((x, n, t, e, s), st) =>
1325 let
1326 val (e, st) = exp [] (e, st)
1327 in
1328 ((x, n, t, e, s), st)
1329 end) st vis
1330 in
1331 ((DValRec vis, loc), st)
1332 end
1333 | _ => (d, st)
1143 1334
1144 fun doDecl (d, st) = 1335 fun doDecl (d, st) =
1145 let 1336 let
1146 val (d, st) = decl st d 1337 (*val () = Print.preface ("doDecl", MonoPrint.p_decl MonoEnv.empty d)*)
1338 val (d, st) = decl (d, st)
1147 in 1339 in
1148 (List.revAppend (#decls st, [d]), 1340 (List.revAppend (#decls st, [d]),
1149 {decls = [], 1341 {decls = [],
1150 script = #script st, 1342 script = #script st,
1151 included = #included st, 1343 included = #included st,
1161 included = IS.empty, 1353 included = IS.empty,
1162 injectors = IM.empty, 1354 injectors = IM.empty,
1163 listInjectors = TM.empty, 1355 listInjectors = TM.empty,
1164 decoders = IM.empty, 1356 decoders = IM.empty,
1165 maxName = U.File.maxName file + 1} 1357 maxName = U.File.maxName file + 1}
1166 (desourceify file) 1358 file
1167 1359
1168 val inf = TextIO.openIn (OS.Path.joinDirFile {dir = Config.libJs, file = "urweb.js"}) 1360 val inf = TextIO.openIn (OS.Path.joinDirFile {dir = Config.libJs, file = "urweb.js"})
1169 fun lines acc = 1361 fun lines acc =
1170 case TextIO.inputLine inf of 1362 case TextIO.inputLine inf of
1171 NONE => String.concat (rev acc) 1363 NONE => String.concat (rev acc)