diff --git a/bf.html b/bf.html
index cad2a6b..2cf029b 100644
--- a/bf.html
+++ b/bf.html
@@ -14,6 +14,14 @@
+
diff --git a/bf.js b/bf.js
index 149b5f6..501910d 100644
--- a/bf.js
+++ b/bf.js
@@ -39,7 +39,7 @@ window.addEventListener("load",function(){
// memoryview
var memoryview=document.getElementById("memoryview");
- var memoryviewmanager=new MemoryView(memoryview.getElementsByClassName("memory-cells")[0],new Uint8Array(30000),0,29999);
+ var memoryviewmanager=undefined;
// buttons
var openbutton=document.getElementById("openbutton");
@@ -349,7 +349,7 @@ window.addEventListener("load",function(){
else{
console.log("Execution paused.");
}
- draw_execution_paused(options.index);
+ draw_execution_paused(options.index,options.memoryuint8array,options.memory_ptr);
continuehandler=options.resume;
});
show_execution_only_buttons(true);
@@ -460,7 +460,7 @@ window.addEventListener("load",function(){
}
});
var execution_location_marker_id=undefined,execution_location_line_id=undefined;
- var draw_execution_paused=function(index){
+ var draw_execution_paused=function(index,memoryuint8array,memory_ptr){
undraw_execution_paused();
var Range=ace.require('ace/range').Range;
var pos=codeEditor.getSession().getDocument().indexToPosition(index);
@@ -481,6 +481,8 @@ window.addEventListener("load",function(){
execution_is_paused=true;
stepbutton.classList.remove("displaynone");
memoryview.classList.remove("displaynone");
+ codeEditor.resize();
+ memoryviewmanager=new MemoryView(memoryview.getElementsByClassName("memory-cells")[0],memoryuint8array,0,29999,memory_ptr);
};
var undraw_execution_paused=function(){
if(execution_location_marker_id!==undefined)codeEditor.getSession().removeMarker(execution_location_marker_id);
@@ -497,6 +499,11 @@ window.addEventListener("load",function(){
execution_is_paused=false;
stepbutton.classList.add("displaynone");
memoryview.classList.add("displaynone");
+ codeEditor.resize();
+ if(memoryviewmanager){
+ memoryviewmanager.clear();
+ memoryviewmanager=undefined;
+ }
};
diff --git a/jelly-bf-interpreter.js b/jelly-bf-interpreter.js
index cd5dc4a..d2c25c1 100644
--- a/jelly-bf-interpreter.js
+++ b/jelly-bf-interpreter.js
@@ -1,11 +1,11 @@
-JellyBFInterpreter=function(codeString,get_input,put_output,breakpointuint8array,globalpauseuint8array){
+JellyBFInterpreter=function(codeString,get_input,put_output,breakpointuint8array,globalpauseuint8array,memoryuint8array){
this.code=codeString;
this.get_input=get_input;
this.put_output=put_output;
this.breakpointuint8array=breakpointuint8array;
this.globalpauseuint8array=globalpauseuint8array;
this.memory_cells=30000;
- this.memory=new Uint8Array(this.memory_cells);
+ this.memory=memoryuint8array||new Uint8Array(this.memory_cells);
this.memory_ptr=0;
this.next_instruction_index=[];
this.loop_pair=[];
@@ -56,33 +56,36 @@ JellyBFInterpreter.prototype.run=function(){
++this.memory_ptr;
}
else if(this.code[this.instruction_ptr]==="+"){
- this.memory[this.memory_ptr]=(this.memory[this.memory_ptr]+1)&255;
+ Atomics.add(this.memory,this.memory_ptr,1);
+ //this.memory[this.memory_ptr]=(this.memory[this.memory_ptr]+1)&255;
}
else if(this.code[this.instruction_ptr]==="-"){
- this.memory[this.memory_ptr]=(this.memory[this.memory_ptr]-1)&255;
+ Atomics.sub(this.memory,this.memory_ptr,1);
+ //this.memory[this.memory_ptr]=(this.memory[this.memory_ptr]-1)&255;
}
else if(this.code[this.instruction_ptr]==="["){
- if(this.memory[this.memory_ptr]===0){
+ if(Atomics.load(this.memory,this.memory_ptr)===0){
this.instruction_ptr=this.loop_pair[this.instruction_ptr];
}
}
else if(this.code[this.instruction_ptr]==="]"){
- if(this.memory[this.memory_ptr]!==0){
+ if(Atomics.load(this.memory,this.memory_ptr)!==0){
this.instruction_ptr=this.loop_pair[this.instruction_ptr];
}
}
else if(this.code[this.instruction_ptr]===","){
- this.memory[this.memory_ptr]=this.get_input();
+ Atomics.store(this.memory,this.memory_ptr,this.get_input());
+ //this.memory[this.memory_ptr]=this.get_input();
}
else if(this.code[this.instruction_ptr]==="."){
- this.put_output(this.memory[this.memory_ptr]);
+ this.put_output(Atomics.load(this.memory,this.memory_ptr));
}
else{
throw "Internal error!";
}
this.instruction_ptr=this.next_instruction_index[this.instruction_ptr];
- if(this.instruction_ptr!==Number.MAX_SAFE_INTEGER&&Atomics.load(this.breakpointuint8array,this.instruction_ptr)!==0)return {type:JellyBFInterpreter.RunResult.PAUSED_AT_BREAKPOINT,index:this.instruction_ptr};
- if(this.instruction_ptr!==Number.MAX_SAFE_INTEGER&&Atomics.load(this.globalpauseuint8array,0)!==0)return {type:JellyBFInterpreter.RunResult.PAUSED_WITHOUT_BREAKPOINT,index:this.instruction_ptr};
+ if(this.instruction_ptr!==Number.MAX_SAFE_INTEGER&&Atomics.load(this.breakpointuint8array,this.instruction_ptr)!==0)return {type:JellyBFInterpreter.RunResult.PAUSED_AT_BREAKPOINT,index:this.instruction_ptr,memory_ptr:this.memory_ptr};
+ if(this.instruction_ptr!==Number.MAX_SAFE_INTEGER&&Atomics.load(this.globalpauseuint8array,0)!==0)return {type:JellyBFInterpreter.RunResult.PAUSED_WITHOUT_BREAKPOINT,index:this.instruction_ptr,memory_ptr:this.memory_ptr};
}
return {type:JellyBFInterpreter.RunResult.PROGRAM_TERMINATED};
};
\ No newline at end of file
diff --git a/jelly-bf-processhandler.js b/jelly-bf-processhandler.js
index 5312bb1..02568a2 100644
--- a/jelly-bf-processhandler.js
+++ b/jelly-bf-processhandler.js
@@ -164,16 +164,18 @@ JellyBFProcessHandler.prototype.executeInteractive=function(options,inputRequest
delete options.breakpointBuffer;
delete options.globalPauseBuffer;
+ var memoryBuffer=new SharedArrayBuffer(30000);
+
var resumer=function(){
that.worker.postMessage({type:"interpret-continue"});
};
var interpretHandler=function(e){
if(e.data.type==="interpret-breakpoint"){
- pausedCallback({breakpoint:true,resume:resumer,index:e.data.index});
+ pausedCallback({breakpoint:true,resume:resumer,index:e.data.index,memoryuint8array:new Uint8Array(memoryBuffer),memory_ptr:e.data.memory_ptr});
}
else if(e.data.type==="interpret-paused"){
- pausedCallback({breakpoint:false,resume:resumer,index:e.data.index});
+ pausedCallback({breakpoint:false,resume:resumer,index:e.data.index,memoryuint8array:new Uint8Array(memoryBuffer),memory_ptr:e.data.memory_ptr});
}
};
@@ -205,7 +207,7 @@ JellyBFProcessHandler.prototype.executeInteractive=function(options,inputRequest
doneCallback({success:false});
});
- this.worker.postMessage({type:"interpret-interactive",sourcecode:sourcecode,inputbuffer:inputBuffer,outputbuffer:outputBuffer,inputwaitbuffer:inputWaitBuffer,outputwaitbuffer:outputWaitBuffer,breakpointbuffer:breakpointBuffer,globalpausebuffer:globalpauseBuffer,options:options});
+ this.worker.postMessage({type:"interpret-interactive",sourcecode:sourcecode,inputbuffer:inputBuffer,outputbuffer:outputBuffer,inputwaitbuffer:inputWaitBuffer,outputwaitbuffer:outputWaitBuffer,breakpointbuffer:breakpointBuffer,globalpausebuffer:globalpauseBuffer,memorybuffer:memoryBuffer,options:options});
}
else{
var that=this;
diff --git a/jelly-bf-sync.js b/jelly-bf-sync.js
index 174d831..d272331 100644
--- a/jelly-bf-sync.js
+++ b/jelly-bf-sync.js
@@ -84,7 +84,7 @@ var JellyBFSync={
terminate_output();
return true;
},
- interpretInteractive:function(str,inputuint8array,outputuint8array,inputwaitint32array,outputwaitint32array,breakpointuint8array,globalpauseuint8array,options,updatedOutputCallback,requestInputCallback){
+ interpretInteractive:function(str,inputuint8array,outputuint8array,inputwaitint32array,outputwaitint32array,breakpointuint8array,globalpauseuint8array,memoryuint8array,options,updatedOutputCallback,requestInputCallback){
var WaitArrayId={
READ_HEAD:0,
WRITE_HEAD:1,
@@ -132,7 +132,7 @@ var JellyBFSync={
Atomics.store(outputwaitint32array,WaitArrayId.WRITE_HEAD,output_write_head+1);
updatedOutputCallback();
};
- var instance=new JellyBFInterpreter(str,get_input,put_output,breakpointuint8array,globalpauseuint8array);
+ var instance=new JellyBFInterpreter(str,get_input,put_output,breakpointuint8array,globalpauseuint8array,memoryuint8array);
return {
run:function(){
var res=instance.run();
diff --git a/jelly-bf-worker.js b/jelly-bf-worker.js
index 04e3604..7e15caf 100644
--- a/jelly-bf-worker.js
+++ b/jelly-bf-worker.js
@@ -60,8 +60,9 @@
var options=message.options;
var breakpointbuffer=message.breakpointbuffer;
var globalpausebuffer=message.globalpausebuffer;
+ var memorybuffer=message.memorybuffer;
try{
- interpretstate=JellyBFSync.interpretInteractive(sourcecode, new Uint8Array(inputbuffer), new Uint8Array(outputbuffer), new Int32Array(inputwaitbuffer), new Int32Array(outputwaitbuffer), new Uint8Array(breakpointbuffer), new Uint8Array(globalpausebuffer),options,function(){
+ interpretstate=JellyBFSync.interpretInteractive(sourcecode, new Uint8Array(inputbuffer), new Uint8Array(outputbuffer), new Int32Array(inputwaitbuffer), new Int32Array(outputwaitbuffer), new Uint8Array(breakpointbuffer), new Uint8Array(globalpausebuffer),memorybuffer?(new Uint8Array(memorybuffer)):undefined,options,function(){
self.postMessage({type:"output-updated"});
},function(readhead){
self.postMessage({type:"input-requested",readhead:readhead});
@@ -88,10 +89,10 @@
interpretstate=undefined;
}
else if(ret.type===JellyBFInterpreter.RunResult.PAUSED_AT_BREAKPOINT){
- self.postMessage({type:"interpret-breakpoint",index:ret.index});
+ self.postMessage({type:"interpret-breakpoint",index:ret.index,memory_ptr:ret.memory_ptr});
}
else if(ret.type===JellyBFInterpreter.RunResult.PAUSED_WITHOUT_BREAKPOINT){
- self.postMessage({type:"interpret-paused",index:ret.index});
+ self.postMessage({type:"interpret-paused",index:ret.index,memory_ptr:ret.memory_ptr});
}
else{
self.postMessage({type:"interpreterror"});
diff --git a/jelly-bf-worker.max.js b/jelly-bf-worker.max.js
index d7eafa9..edd9793 100644
--- a/jelly-bf-worker.max.js
+++ b/jelly-bf-worker.max.js
@@ -1540,14 +1540,14 @@ var JellyBF_CloseAndAttemptUnrollLoop = function(codeChunks, options) {
}
};
-JellyBFInterpreter = function(codeString, get_input, put_output, breakpointuint8array, globalpauseuint8array) {
+JellyBFInterpreter = function(codeString, get_input, put_output, breakpointuint8array, globalpauseuint8array, memoryuint8array) {
this.code = codeString;
this.get_input = get_input;
this.put_output = put_output;
this.breakpointuint8array = breakpointuint8array;
this.globalpauseuint8array = globalpauseuint8array;
this.memory_cells = 3e4;
- this.memory = new Uint8Array(this.memory_cells);
+ this.memory = memoryuint8array || new Uint8Array(this.memory_cells);
this.memory_ptr = 0;
this.next_instruction_index = [];
this.loop_pair = [];
@@ -1589,7 +1589,7 @@ JellyBFInterpreter.RunResult = {
};
JellyBFInterpreter.prototype.run = function() {
- while (this.instruction_ptr != Number.MAX_SAFE_INTEGER) {
+ while (this.instruction_ptr !== Number.MAX_SAFE_INTEGER) {
if (this.code[this.instruction_ptr] === "<") {
if (this.memory_ptr === 0) throw JellyBFInterpreter.RuntimeError.INVALID_MEMORY_ACCESS;
--this.memory_ptr;
@@ -1597,32 +1597,34 @@ JellyBFInterpreter.prototype.run = function() {
if (this.memory_ptr + 1 === this.memory_cells) throw JellyBFInterpreter.RuntimeError.INVALID_MEMORY_ACCESS;
++this.memory_ptr;
} else if (this.code[this.instruction_ptr] === "+") {
- this.memory[this.memory_ptr] = this.memory[this.memory_ptr] + 1 & 255;
+ Atomics.add(this.memory, this.memory_ptr, 1);
} else if (this.code[this.instruction_ptr] === "-") {
- this.memory[this.memory_ptr] = this.memory[this.memory_ptr] - 1 & 255;
+ Atomics.sub(this.memory, this.memory_ptr, 1);
} else if (this.code[this.instruction_ptr] === "[") {
- if (this.memory[this.memory_ptr] === 0) {
+ if (Atomics.load(this.memory, this.memory_ptr) === 0) {
this.instruction_ptr = this.loop_pair[this.instruction_ptr];
}
} else if (this.code[this.instruction_ptr] === "]") {
- if (this.memory[this.memory_ptr] !== 0) {
+ if (Atomics.load(this.memory, this.memory_ptr) !== 0) {
this.instruction_ptr = this.loop_pair[this.instruction_ptr];
}
} else if (this.code[this.instruction_ptr] === ",") {
- this.memory[this.memory_ptr] = this.get_input();
+ Atomics.store(this.memory, this.memory_ptr, this.get_input());
} else if (this.code[this.instruction_ptr] === ".") {
- this.put_output(this.memory[this.memory_ptr]);
+ this.put_output(Atomics.load(this.memory, this.memory_ptr));
} else {
throw "Internal error!";
}
this.instruction_ptr = this.next_instruction_index[this.instruction_ptr];
if (this.instruction_ptr !== Number.MAX_SAFE_INTEGER && Atomics.load(this.breakpointuint8array, this.instruction_ptr) !== 0) return {
type: JellyBFInterpreter.RunResult.PAUSED_AT_BREAKPOINT,
- index: this.instruction_ptr
+ index: this.instruction_ptr,
+ memory_ptr: this.memory_ptr
};
if (this.instruction_ptr !== Number.MAX_SAFE_INTEGER && Atomics.load(this.globalpauseuint8array, 0) !== 0) return {
type: JellyBFInterpreter.RunResult.PAUSED_WITHOUT_BREAKPOINT,
- index: this.instruction_ptr
+ index: this.instruction_ptr,
+ memory_ptr: this.memory_ptr
};
}
return {
@@ -1712,7 +1714,7 @@ var JellyBFSync = {
terminate_output();
return true;
},
- interpretInteractive: function(str, inputuint8array, outputuint8array, inputwaitint32array, outputwaitint32array, breakpointuint8array, globalpauseuint8array, options, updatedOutputCallback, requestInputCallback) {
+ interpretInteractive: function(str, inputuint8array, outputuint8array, inputwaitint32array, outputwaitint32array, breakpointuint8array, globalpauseuint8array, memoryuint8array, options, updatedOutputCallback, requestInputCallback) {
var WaitArrayId = {
READ_HEAD: 0,
WRITE_HEAD: 1,
@@ -1757,7 +1759,7 @@ var JellyBFSync = {
Atomics.store(outputwaitint32array, WaitArrayId.WRITE_HEAD, output_write_head + 1);
updatedOutputCallback();
};
- var instance = new JellyBFInterpreter(str, get_input, put_output, breakpointuint8array, globalpauseuint8array);
+ var instance = new JellyBFInterpreter(str, get_input, put_output, breakpointuint8array, globalpauseuint8array, memoryuint8array);
return {
run: function() {
var res = instance.run();
@@ -1844,8 +1846,9 @@ var JellyBFSync = {
var options = message.options;
var breakpointbuffer = message.breakpointbuffer;
var globalpausebuffer = message.globalpausebuffer;
+ var memorybuffer = message.memorybuffer;
try {
- interpretstate = JellyBFSync.interpretInteractive(sourcecode, new Uint8Array(inputbuffer), new Uint8Array(outputbuffer), new Int32Array(inputwaitbuffer), new Int32Array(outputwaitbuffer), new Uint8Array(breakpointbuffer), new Uint8Array(globalpausebuffer), options, function() {
+ interpretstate = JellyBFSync.interpretInteractive(sourcecode, new Uint8Array(inputbuffer), new Uint8Array(outputbuffer), new Int32Array(inputwaitbuffer), new Int32Array(outputwaitbuffer), new Uint8Array(breakpointbuffer), new Uint8Array(globalpausebuffer), memorybuffer ? new Uint8Array(memorybuffer) : undefined, options, function() {
self.postMessage({
type: "output-updated"
});
@@ -1887,12 +1890,14 @@ var JellyBFSync = {
} else if (ret.type === JellyBFInterpreter.RunResult.PAUSED_AT_BREAKPOINT) {
self.postMessage({
type: "interpret-breakpoint",
- index: ret.index
+ index: ret.index,
+ memory_ptr: ret.memory_ptr
});
} else if (ret.type === JellyBFInterpreter.RunResult.PAUSED_WITHOUT_BREAKPOINT) {
self.postMessage({
type: "interpret-paused",
- index: ret.index
+ index: ret.index,
+ memory_ptr: ret.memory_ptr
});
} else {
self.postMessage({
diff --git a/jelly-memoryview.js b/jelly-memoryview.js
index 8169f57..8029030 100644
--- a/jelly-memoryview.js
+++ b/jelly-memoryview.js
@@ -1,10 +1,11 @@
-var MemoryView=function(root_el,uint8_array,min_index,max_index){
+var MemoryView=function(root_el,uint8_array,min_index,max_index,memory_ptr){
this.root=root_el;
this.minIndex=min_index;
this.maxIndex=max_index;
this.currentIndex=this.minIndex;
this.viewLength=1;
this.data=uint8_array;
+ this.ptr=memory_ptr;
this.redraw();
var that=this;
window.addEventListener("resize",function(){
@@ -17,12 +18,16 @@ MemoryView.prototype.refresh=function(){
var labels=this.root.getElementsByClassName("labelwrapper")[0].getElementsByClassName("label");
for(var i=0;ithis.maxIndex-this.minIndex+1)this.viewLength=this.maxIndex-this.minIndex+1;
@@ -45,6 +50,16 @@ MemoryView.prototype.redraw=function(){
this.refresh();
};
+MemoryView.prototype.centerAtIndex=function(index){
+ if(indexthis.maxIndex)return false;
+ index-=(this.viewLength-1)/2;
+ if(index<0)index=0;
+ if(index+this.viewLength>this.maxIndex+1)index=this.maxIndex+1-this.viewLength;
+ this.currentIndex=index;
+ this.refresh();
+ return true;
+};
+
MemoryView.prototype.goToIndex=function(index){
if(indexthis.maxIndex)return false;
if(index