compiler.js

function COMPILE (E) {
	return COMP(E,null,[4,[21,null]])

	function ATOM(E){ return E==null || typeof(E) != "object" }
	function COMP (E,N,C) {
		if(ATOM(E)) return [1,[LOCATION(E,N),C]]
		switch(E[0]){
		case "QUOTE": return [2,[E[1][0],C]]
		case "ADD":   return COMP(E[1][0], N, COMP(E[1][1][0], N, [15,C]))
		case "SUB":   return COMP(E[1][0], N, COMP(E[1][1][0], N, [16,C]))
		case "MUL":   return COMP(E[1][0], N, COMP(E[1][1][0], N, [17,C]))
		case "DIV":   return COMP(E[1][0], N, COMP(E[1][1][0], N, [18,C]))
		case "REM":   return COMP(E[1][0], N, COMP(E[1][1][0], N, [19,C]))
		case "LEQ":   return COMP(E[1][0], N, COMP(E[1][1][0], N, [20,C]))
		case "EQ":    return COMP(E[1][0], N, COMP(E[1][1][0], N, [14,C]))
		case "CAR":   return COMP(E[1][0], N, [10,C])
		case "CDR":   return COMP(E[1][0], N, [11,C])
		case "ATOM":  return COMP(E[1][0], N, [12,C])
		case "CONS":  return COMP(E[1][1][0], N, COMP(E[1][0], N, [13,C]))
		case "IF":
			var THENPT = COMP(E[1][1][0], N, [9,null])
			var ELSEPT = COMP(E[1][1][1][0], N,[9,null])
			return COMP(E[1][0], N, [8,[THENPT,[ELSEPT,C]]])
		case "LAMBDA":
			var BODY = COMP(E[1][1][0],[E[1][0],N], [5,null])
	        return [3,[BODY,C]];
		case "LET":
			var M = [VARS(E[1][1]), N]
			var ARGS = EXPRS(E[1][1])
			var BODY = COMP(E[1][0], M, [5,null])
			return COMPLIS(ARGS, N, [3,[BODY,[4,C]]])
		case "LETREC":
			var M = [VARS(E[1][1]), N]
			var ARGS = EXPRS(E[1][1])
			var BODY = COMP(E[1][0], M, [5,null])
			return [6,COMPLIS(ARGS,M,[3,[BODY,[7,C]]])]
		default:
			return COMPLIS(E[1], N, COMP(E[0], N, [4,C]))
		}
	}
	function COMPLIS (E, N, C) {
		if(E == null) return [2,[null,C]]
		else           return COMPLIS(E[1], N, COMP(E[0], N, [13,C]))
	}
	function LOCATION (E, N) {
		function MEMBER (E, N){
			     if (N == null)  return false;
			else if (E == N[0]) return true;
			else                  return MEMBER(E,N[1])
		}
		function POSN (E, N) {
			if (E == N[0]) return 0;
			else             return POSN(E, N[1])+1;
		}
		function INCAR (L) {
			return [L[0]+1, L[1]];
		}

		if (MEMBER(E, N[0])) return [0,POSN(E,N[0])]
		else                   return INCAR(LOCATION(E, N[1]))
	}
	function VARS (D) {
	    if (D == null) return null;
		else            return [D[0][0],VARS(D[1])];
	}
	function EXPRS (D) {
	    if (D == null) return null;
	    else			return [D[0][1], EXPRS(D[1])]
	}
}