comparison lib/js/urweb.js @ 970:8371d12ae63f

Hopefully complete refactoring of Jscomp to output ASTs; partial implementation of interpreter in runtime system (demo/alert works)
author Adam Chlipala <adamc@hcoop.net>
date Tue, 22 Sep 2009 12:23:21 -0400
parents 001edfbe2561
children c22e524a6dd3
comparison
equal deleted inserted replaced
969:001edfbe2561 970:8371d12ae63f
1 // Function versions of operators
2
3 function not(x) { return !x; }
4 function neg(x) { return -x; }
5
6 function eq(x, y) { return x == y; }
7 function plus(x, y) { return x + y; }
8 function minus(x, y) { return x - y; }
9 function times(x, y) { return x * y; }
10 function div(x, y) { return x / y; }
11 function mod(x, y) { return x % y; }
12 function lt(x, y) { return x < y; }
13 function le(x, y) { return x <= y; }
14
1 // Lists 15 // Lists
2 16
3 function cons(v, ls) { 17 function cons(v, ls) {
4 return { next : ls, data : v }; 18 return { next : ls, data : v };
5 } 19 }
763 } 777 }
764 778
765 779
766 // Key events 780 // Key events
767 781
768 function kc(e) { 782 var uw_event = null;
769 return window.event ? e.keyCode : e.which; 783
784 function kc() {
785 return window.event ? uw_event.keyCode : uw_event.which;
786 }
787
788
789 // The Ur interpreter
790
791 var urfuncs = [];
792
793 function lookup(env, n) {
794 while (env != null) {
795 if (n == 0)
796 return env.data;
797 else {
798 --n;
799 env = env.next;
800 }
801 }
802
803 throw "Out-of-bounds Ur variable reference";
804 }
805
806 function exec0(env, e) {
807 var stack = null;
808
809 while (true) {
810 switch (e.c) {
811 case "c":
812 var v = e.v;
813 if (stack == null)
814 return v;
815 var fr = stack.data;
816
817 switch (fr.c) {
818 case "s":
819 e = {c: "c", v: {v: v}};
820 stack = stack.next;
821 break;
822 case "1":
823 e = {c: "c", v: {n: fr.n, v: v}};
824 stack = stack.next;
825 break;
826 case "f":
827 fr.args[fr.pos++] = v;
828 if (fr.a == null) {
829 e = {c: "c", v: fr.f.apply(null, fr.args)};
830 stack = stack.next;
831 } else {
832 e = fr.a.data;
833 fr.a = fr.a.next;
834 }
835 break;
836 case "a1":
837 if (v == null || !v.body)
838 throw "Ur: applying non-function";
839 stack = cons({c: "a2", env: v.env, body: v.body}, stack.next);
840 e = fr.x;
841 break;
842 case "a2":
843 stack = cons({c: "a3", env: env}, stack.next);
844 env = cons(v, fr.env);
845 e = fr.body;
846 break;
847 case "a3":
848 env = fr.env;
849 stack = stack.next;
850 break;
851 case "r":
852 fr.fs["_" + fr.n] = v;
853 if (fr.l == null) {
854 e = {c: "c", v: fr.fs};
855 stack = stack.next;
856 } else {
857 fr.n = fr.l.data.n;
858 e = fr.l.data.v;
859 fr.l = fr.l.next;
860 }
861 break;
862 case ".":
863 e = {c: "c", v: v["_" + fr.f]};
864 stack = stack.next;
865 break;
866 case ";":
867 e = fr.e2;
868 stack = stack.next;
869 break;
870 case "=1":
871 env = cons(v, env);
872 e = fr.e2;
873 stack = stack.next;
874 break;
875 case "=":
876 env = cons(v, env);
877 e = fr.e2;
878 stack = cons({c: "a3", env: env}, stack.next);
879 break;
880 default:
881 throw "Unknown Ur continuation kind";
882 }
883
884 break;
885 case "v":
886 e = {c: "c", v: lookup(env, e.n)};
887 break;
888 case "n":
889 e = {c: "c", v: urfuncs[e.n]};
890 break;
891 case "s":
892 stack = cons({c: "s"}, stack);
893 e = e.v;
894 break;
895 case "1":
896 stack = cons({c: "1", n: e.n}, stack);
897 e = e.v;
898 break;
899 case "f":
900 if (e.a == null)
901 e = {c: "c", v: e.f()};
902 else {
903 var args = [];
904 stack = cons({c: "f", f: e.f, args: args, pos: 0, a: e.a.next}, stack);
905 e = e.a.data;
906 }
907 break;
908 case "l":
909 e = {c: "c", v: {env: env, body: e.b}};
910 break;
911 case "a":
912 stack = cons({c: "a1", x: e.x}, stack);
913 e = e.f;
914 break;
915 case "r":
916 if (e.l == null)
917 throw "Empty Ur record in interpretation";
918 var fs = {};
919 stack = cons({c: "r", n: e.l.data.n, fs: fs, l: e.l.next}, stack);
920 e = e.l.data;
921 break;
922 case ".":
923 stack = cons({c: ".", f: e.f}, stack);
924 e = e.r;
925 break;
926 case ";":
927 stack = cons({c: ";", e2: e.e2}, stack);
928 e = e.e1;
929 break;
930 case "=":
931 stack = cons({c: "=", e2: e.e2}, stack);
932 e = e.e1;
933 break;
934 case "e":
935 var env0 = env;
936 var e0 = e.e;
937 e = {c: "c", v: cs(function() { return exec0(env0, e0); })};
938 break;
939 default:
940 throw "Unknown Ur expression kind";
941 }
942 }
943 }
944
945 function exec(e) {
946 var r = exec0(null, e);
947
948 if (r != null && r.body)
949 return function(v) { return exec0(cons(v, r.env), r.body); };
950 else
951 return r;
770 } 952 }
771 953
772 954
773 // App-specific code 955 // App-specific code
774 956