/* Interp.js - change control section

ID	Date	 Notes
EN001	01/03/00 Update parser to permit repeat E [L]
EN002	01/03/00 Update parser to permit bk (backwards) dv (dive) rl (roll)
DB002	01/03/00 Check for parse errors before executing the tree walkover
*/

function first(a){
return(a[1]);
}

function second(a){
return(first(a[2]));
}

function Sew(a,b){
var y=Math.max(a.length,b.length);
var x1=a[0].length;
var x2=b[0].length;
var r = new Array()
for (i=0;i<y;i++){
  r[i]=new Array();
  for (j=0;j<x1;j++)
    r[i][j]=a[i][j];
  for (j=0;j<x2;j++)
    r[i][j+x1]=b[i][j];
  }
return(r);
}

function tin(a){
p=a.substr(0,a.length-1);
x=a.charAt(a.length-1);
switch (x) {
  case "0" : return(p+"1");
  case "1" : return(p+"2");
  case "2" : return(p+"3");
  case "3" : return(p+"0");
  }
}

function Turn(a){
var y=a.length;
var x=a[0].length;
var r=new Array();
for (var i=0;i<x;i++){
  r[i]= new Array();
  for (var j=0;j<y;j++)
    r[i][j] = tin(a[y-j-1][i]);
  }
return(r);
}

function newenv(){
return(0);
}

function enrich(k,v,e){
return(new Array(new Array(k,v),e));
}

function newdef(a,e){
return(enrich(a[1],a[2],e));
}

function mapenrich(l,e){
if (l==0)
  return(e);
else
  return(newdef(l[1],mapenrich(l[2],e)));
}

function lookup(k,e){
if (e==0){
  alert("Could not find: "+k);
  return(0);
  }
else {
  if (e[0][0]==k)
    return(e[0][1]);
  else
    return(lookup(k,e[1]));
  }
}

function envmat(l,v,e,ef){
if (l==0)
  return(e);
else{
  return(enrich(l[1],WalkOver(v[1],ef), envmat(l[2],v[2],e,ef)));
  }
}

function App(lam, ap, e){
return(WalkOver(lam[2],envmat(lam[1],ap,e,e)));
}

function WalkOver(tree,e){
switch (tree[0]) {
  case "PRIM" :
    switch (tree[1]){
      case "b": case "c": case "d": case "e": case "f": case "g": case "h": case "i": case "k":
      case "lr": case "cr": case "cl":
        return(new Array(new Array(tree[1]+"0")));
        break;
      default : return(WalkOver(lookup(tree[1],e),e));break;
      }
  case "APP":
    switch (tree[1]){
      case "sew": return(Sew(WalkOver(first(tree[2]),e),WalkOver(second(tree[2]),e)));break;
      case "turn" : return(Turn(WalkOver(first(tree[2]),e)));break;
      default  : return(App(lookup(tree[1],e),tree[2],e));break;
      }
    break;
  case "LET":
    return(WalkOver(tree[2],mapenrich(tree[1],e)));
  default : return(tree);
  }//End switch tree[0]
return(tree[0]);//Complains otherwise
}

var winwidth=600;
var winheight=300;

function newwin(p){
var x=window.open('','abc','menubar=yes,toolbar=no,resizable=yes,scrollbars=yes,width='+winwidth+',height='+winheight);
x.document.open();
x.document.writeln(p);
x.document.close();
}

function p2(x){
//alert(x+' '+Math.log(x)/Math.LN2);
return(Math.pow(2,Math.floor(Math.log(x)/Math.LN2)));
}

function GoStr(s,debug,winwidth,winhieght,pw){
if (arguments.length<2)
  debug = false;
ParseError = '';
cs = new Stream(s);
ss = Lex(cs);
if (debug)
  document.debuggery.lex_out.value=ToString(ss);
tree= Parse_E(ss);
var rs='';
if (debug)
  document.debuggery.parse_out.value=PPrint(tree);
if (ParseError==''){					//DB002
  var x=WalkOver(tree,newenv());
  if (x[0].length*pw>winwidth){
    pw = p2(winwidth/x[0].length);
    }
  for (var i=0;i<x.length;i++){
    var y=x[i];
    for (var j=0;j<y.length;j++){
      rs+="<img src=\""+y[j]+".gif\">";
      }
    rs+="<BR>\n";
    }
  if (debug)
    document.debuggery.tree_out.value = rs;
  }
else
  alert(ParseError);
return(rs);
}

function Go(s,debug,winwidth,winhieght,pw){
if (arguments.length<3)
  winwidth = 600;
//alert(winwidth);
//winwidth = document.forms[0].winwidth.value;
if (arguments.length<4)
  winheight = 600;
//winheight = document.forms[0].winheight.value;
if (arguments.length<5)
  pw = 32;
//pw=document.forms[0].pw.value;
newwin("<body onLoad=\"self.focus();\" bgcolor='aqua'>\n"+GoStr(s,debug,winwidth,winhieght,pw)+"</body>");

}

