summaryrefslogtreecommitdiff
path: root/lib/js
diff options
context:
space:
mode:
authorGravatar Adam Chlipala <adamc@hcoop.net>2009-09-24 15:45:37 -0400
committerGravatar Adam Chlipala <adamc@hcoop.net>2009-09-24 15:45:37 -0400
commita75e7e0645ae0dd0e5f3c51143890111d5ecae44 (patch)
tree7e9955bdbe69e3b92b05bd4871aa0fa7bb66c2ec /lib/js
parentb9f0d03e7ad47a33bf22efec31098c6c8c80ec6e (diff)
Add tail call optimization to interpretation
Diffstat (limited to 'lib/js')
-rw-r--r--lib/js/urweb.js13
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;