// machine components
// instruction pointer register
var ip=0;
// w register, argument to docol and literal prims
var w=undefined;
// stack and return stack
var S=new Stack;
var RS=new Stack;
// memory
var M=new Array;
// text input buffer
var Tib=new Array;

function initialize() {
	ip=0;
	S=new Stack;
	RS=new Stack;
	M=new Array;
	curs=0;
	for(var r=0;r<25;r++) {
	 for(var c=0;c<80;c++) {
	  scr[r*80+c]=' ';
	 }
	}
	var dirty=true;
}

function toChar(c) {
  return String.fromCharCode(c);
}

var tc=0;
function trace(str) {
	return;
    var od=document.getElementById('trace');
    od.innerHTML += str + "\t";
	if ((tc+=str.length+8) > 72) {
		od.innerHTML += "\n";
		tc=0;
    }
}
function trace2(str) {
    var od=document.getElementById('trace');
    od.innerHTML += str + "\t";
	if ((tc+=String(str).length+8) > 72) {
		od.innerHTML += "\n";
		tc=0;
    }
}

function dprint(str) {
    var od=document.getElementById('trace');
    var bl=document.createTextNode(str+"\n");
    od.appendChild(bl);
}


var running=500;
var lc=0;
// forth main loop
function doNext() {
    window.status="running "+lc;
    while(running-->0) {
	lc++;
	if (ip != ip) {
	    alert("ip is NaN!");
	    window.status="error "+lc;
	    iopause();
	    running=-2;
	    break;
	}
	var i=M[ip++];
	if (i != undefined && i.prim != undefined) {
        try {
	    var r=i.prim(i);
        } catch (e) {
          trace2(S.s);
          trace2("x"+n2h(ip-1,2)+" "+i+":"+e.message);
          running=-2;
          window.status="error "+lc;
          iopause();
          break;
        }
	    if (r) break;  // wait for reschedule
	} else {
	    // put literal data into w register as prim argument
	    w=i;
	}
    }
    if (running == -1) {
	running=500;
	window.setTimeout(doNext,0);
	window.status="paused "+lc;
    } else {
        window.status="waiting "+lc;
    }
}
