# HG changeset patch # User Adam Chlipala # Date 1253627585 14400 # Node ID 001edfbe2561a3bf7ba917fd8e68d9d88697ed64 # Parent b8048f6e25ef0ee9a226d131a81e4e7f9d686fb4 Iterative versions of some JavaScript list functions diff -r b8048f6e25ef -r 001edfbe2561 lib/js/urweb.js --- a/lib/js/urweb.js Sat Sep 19 16:18:54 2009 -0400 +++ b/lib/js/urweb.js Tue Sep 22 09:53:05 2009 -0400 @@ -3,8 +3,18 @@ function cons(v, ls) { return { next : ls, data : v }; } +function rev(ls) { + var acc = null; + for (; ls; ls = ls.next) + acc = cons(ls.data, acc); + return acc; +} function concat(ls1, ls2) { - return (ls1 ? cons(ls1.data, concat(ls1.next, ls2)) : ls2); + var acc = ls2; + ls1 = rev(ls1); + for (; ls1; ls1 = ls1.next) + acc = cons(ls1.data, acc); + return acc; } function member(x, ls) { for (; ls; ls = ls.next) @@ -13,13 +23,32 @@ return false; } function remove(x, ls) { - return (ls ? (ls.data == x ? ls.next : cons(ls.data, remove(x, ls.next))) : null); + var acc = null; + + for (; ls; ls = ls.next) + if (ls.data == x) + return concat(acc, ls.next); + else + acc = cons(ls.data, acc); + + return ls; } function union(ls1, ls2) { - return (ls1 ? (member(ls1.data, ls2) ? union(ls1.next, ls2) : cons(ls1.data, union(ls1.next, ls2))) : ls2); + var acc = ls2; + + for (; ls1; ls1 = ls1.next) + if (!member(ls1.data, ls2)) + acc = cons(ls1.data, acc); + + return acc; } function length(ls) { - return (ls ? 1 + length(ls.next) : 0); + var acc = 0; + + for (; ls; ls = ls.next) + ++acc; + + return acc; } @@ -63,6 +92,8 @@ function doExn(v) { if (v == null || v.uw_error == null) { var s = (v == null ? "null" : v.toString()); + if (v != null && v.fileName && v.lineNumber) + s += " (" + v.fileName + ":" + v.lineNumber + ")"; runHandlers("Fail", failHandlers, s); } }