diff options
author | Adam Chlipala <adamc@hcoop.net> | 2009-09-24 15:45:37 -0400 |
---|---|---|
committer | Adam Chlipala <adamc@hcoop.net> | 2009-09-24 15:45:37 -0400 |
commit | a2ab1cb6d782e13944ba21fd0368528e5a27ee9e (patch) | |
tree | 7e9955bdbe69e3b92b05bd4871aa0fa7bb66c2ec /lib | |
parent | b1c6c28afe126832b1c3bfa33b533349001aab06 (diff) |
Add tail call optimization to interpretation
Diffstat (limited to 'lib')
-rw-r--r-- | lib/js/urweb.js | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/lib/js/urweb.js b/lib/js/urweb.js index 2ebb13c5..653f8d2f 100644 --- a/lib/js/urweb.js +++ b/lib/js/urweb.js @@ -856,6 +856,13 @@ function execP(env, p, v) { function exec0(env, e) { var stack = null; + var saveEnv = function() { + if (stack.next != null && stack.next.data.c != "<") + stack = cons({c: "<", env: env}, stack.next); + else + stack = stack.next; + }; + while (true) { switch (e.c) { case "c": @@ -891,7 +898,7 @@ function exec0(env, e) { if (fr.f == null) whine("Ur: applying null function"); else if (fr.f.body) { - stack = cons({c: "<", env: env}, stack.next); + saveEnv(); env = cons(v, fr.f.env); e = fr.f.body; } else { @@ -923,7 +930,7 @@ function exec0(env, e) { stack = stack.next; break; case "=": - stack = cons({c: "<", env: env}, stack.next); + saveEnv(); env = cons(v, env); e = fr.e2; break; @@ -932,7 +939,7 @@ function exec0(env, e) { for (ps = fr.p; ps != null; ps = ps.next) { var r = execP(env, ps.data.p, v); if (r != false) { - stack = cons({c: "<", env: env}, stack.next); + saveEnv(); env = r; e = ps.data.b; break; |