diff --git a/bf.css b/bf.css index 98822f2..d7ecc3f 100644 --- a/bf.css +++ b/bf.css @@ -15,6 +15,12 @@ html, body{ margin:0; font-family:"Signika",sans-serif; font-size:16px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } body>.wrapper{ @@ -25,11 +31,14 @@ body>.wrapper{ flex-wrap:nowrap; justify-content:center; align-items:stretch; + position:relative; } body>.wrapper>*{ display:block; overflow:hidden; + position:relative; + z-index:0; } #header{ @@ -58,7 +67,7 @@ body>.wrapper>*{ #header .title{ flex:0 0 auto; - padding:0px 12px; + padding:0px 20px; } #header .title .jelly{ @@ -156,8 +165,21 @@ body>.wrapper>*{ } #compilationinfo{ - flex:0 0 20px; + flex:0 0 26px; background-color:rgb(204,224,255); + line-height:26px; +} + +#compilationinfo .compilationinfospan{ + padding:0 12px; +} + +#compilationinfo #compilationspan{ + color:blue; +} + +#compilationinfo #executionspan{ + color:green; } #iooptions{ @@ -177,18 +199,40 @@ body>.wrapper>*{ flex-wrap:nowrap; justify-content:center; align-items:stretch; + position:relative; } #ioblock .separate>*{ display:block; overflow:hidden; + position:relative; + z-index:0; } -#ioblock .separate #inputblock{ +#ioblock .separate .ioseparateindividualblock{ flex:1 1 0px; + display:flex; + flex-direction:column; + flex-wrap:nowrap; + justify-content:center; + align-items:stretch; } -#ioblock .separate #outputblock{ +#ioblock .separate .ioseparateindividualblock>*{ + display:block; + overflow:hidden; +} + +#ioblock .separate .ioseparateindividualblock>.iotitle{ + flex:0 0 20px; + height:20px; + line-height:20px; + padding:0 6px; + background-color:rgb(230,240,255); + font-size:14px; +} + +#ioblock .separate .ioseparateindividualblock>.iocontent{ flex:1 1 0px; } @@ -196,9 +240,38 @@ body>.wrapper>*{ flex:0 0 4px; width:4px; background-color:rgb(204,224,255); + position:relative; + overflow:visible; + z-index:1; } -#ioblock .separate #inputblock .editor, #ioblock .separate #outputblock .editor{ +#ioblock .separate .vertical-spacer .actual-spacer{ + position:absolute; + top:0; + bottom:0; + left:-3px; + right:-3px; + cursor:col-resize; +} + +#ioblock .separate .ioseparateindividualblock .editor{ height:100%; width:100%; +} + +body>.wrapper>.horizontal-spacer{ + flex:0 0 0px; + height:0px; + position:relative; + overflow:visible; + z-index:1; +} + +body>.wrapper>.horizontal-spacer .actual-spacer{ + position:absolute; + top:-5px; + bottom:-5px; + left:0; + right:0; + cursor:row-resize; } \ No newline at end of file diff --git a/bf.html b/bf.html index 150e486..725a3bf 100644 --- a/bf.html +++ b/bf.html @@ -3,12 +3,13 @@ - Jelly Brainfuck Compiler + Jelly Compiler for Brainfuck - + + @@ -28,16 +29,30 @@
-
+
+
+
+
+
+
+
-
-
+
+
Input
+
+
+
+
+
+
-
-
-
+
+
Output
+
+
+
diff --git a/bf.js b/bf.js index a14b07b..689831a 100644 --- a/bf.js +++ b/bf.js @@ -89,6 +89,14 @@ window.addEventListener("load",function(){ var isCompiling=false; var toRunAfterCompiling=false; + var compilationSpan=document.getElementById("compilationspan"); + var executionSpan=document.getElementById("executionspan"); + + while(compilationSpan.firstChild)compilationSpan.removeChild(compilationSpan.firstChild); + compilationSpan.appendChild(document.createTextNode("")); + while(executionSpan.firstChild)executionSpan.removeChild(executionSpan.firstChild); + executionSpan.appendChild(document.createTextNode("")); + codeEditor.on("change",function(){ codeCompiled=false; }); @@ -107,17 +115,25 @@ window.addEventListener("load",function(){ processHandler=new JellyBFProcessHandler(); processHandler.initialize(function(){ if(!to_terminate){ + executionSpan.firstChild.nodeValue=""; + compilationSpan.firstChild.nodeValue="Compiling…"; var start_time=Date.now(); - processHandler.compile(codeEditor.getValue(),{},function(){ + processHandler.compile(codeEditor.getValue(),{},function(message){ if(!to_terminate){ - codeCompiled=true; isCompiling=false; - var end_time=Date.now(); - console.log("Compiled in "+Math.round(end_time-start_time)+" ms."); processHandlerTerminator=undefined; - if(toRunAfterCompiling){ - toRunAfterCompiling=false; - runbutton.click(); + if(message.success){ + codeCompiled=true; + var end_time=Date.now(); + console.log("Compiled in "+Math.round(end_time-start_time)+" ms."); + compilationSpan.firstChild.nodeValue="Compiled in "+Math.round(end_time-start_time)+" ms."; + if(toRunAfterCompiling){ + toRunAfterCompiling=false; + runbutton.click(); + } + } + else{ + compilationSpan.firstChild.nodeValue="Compilation failed."; } } }); @@ -140,15 +156,39 @@ window.addEventListener("load",function(){ runTerminator=function(){ to_terminate=true; }; + executionSpan.firstChild.nodeValue="Executing…"; var start_time=Date.now(); - processHandler.execute(inputEditor.getValue(),{},function(outputstr){ + processHandler.execute(inputEditor.getValue(),{},function(message){ if(!to_terminate){ - var end_time=Date.now(); - console.log("Executed in "+Math.round(end_time-start_time)+" ms."); - outputEditor.setValue(outputstr,1); runTerminator=undefined; + if(message.success){ + var end_time=Date.now(); + outputEditor.setValue(message.output,1); + console.log("Executed in "+Math.round(end_time-start_time)+" ms."); + executionSpan.firstChild.nodeValue="Executed in "+Math.round(end_time-start_time)+" ms."; + } + else{ + executionSpan.firstChild.nodeValue="Execution failed."; + } } }); } }); + + // splitters + Array.prototype.forEach.call(document.getElementById("ioblock").getElementsByClassName("vertical-spacer"),function(el){ + var splitter=new FlexSplitter(el,el.getElementsByClassName("actual-spacer")[0],0.1,0.1); + splitter.onadjust=function(){ + inputEditor.resize(); + outputEditor.resize(); + }; + }); + Array.prototype.forEach.call(document.getElementsByClassName("horizontal-spacer"),function(el){ + var splitter=new FlexSplitter(el,el.getElementsByClassName("actual-spacer")[0],0.1,0.1); + splitter.onadjust=function(){ + codeEditor.resize(); + inputEditor.resize(); + outputEditor.resize(); + }; + }); }); \ No newline at end of file diff --git a/flex-splitter.js b/flex-splitter.js new file mode 100644 index 0000000..3e3094d --- /dev/null +++ b/flex-splitter.js @@ -0,0 +1,70 @@ +var FlexSplitter=function(flex_el,drag_el,minBefore,minAfter){ + var that=this; + + var splitterElement=flex_el; + var containerElement=flex_el.parentElement; + var beforeElement=flex_el; + do{ + beforeElement=beforeElement.previousElementSibling; + }while(parseFloat(window.getComputedStyle(beforeElement).getPropertyValue("flex-grow"))===0); + var afterElement=flex_el; + do{ + afterElement=afterElement.nextElementSibling; + }while(parseFloat(window.getComputedStyle(afterElement).getPropertyValue("flex-grow"))===0); + + var containerflexdirection=window.getComputedStyle(containerElement).getPropertyValue("flex-direction"); + var isFlexVertical=(containerflexdirection.indexOf("column")!==-1); + var isFlexReverse=(containerflexdirection.indexOf("reverse")!==-1); + + minBefore=minBefore||0.1; + minAfter=minAfter||0.1; + + var mousedownLocation=undefined; + var beforeElSize=undefined; + var afterElSize=undefined; + var beforeElRatio=undefined; + var afterElRatio=undefined; + + var mouseup_handler=function(e){ + document.removeEventListener("mouseleave",mouseup_handler); + document.removeEventListener("mouseup",mouseup_handler); + document.removeEventListener("mousemove",mousemove_handler); + mousedownLocation=undefined; + beforeElSize=undefined; + afterElSize=undefined; + beforeElRatio=undefined; + afterElRatio=undefined; + if(that.onresize)that.onresize(); + }; + + var mousemove_handler=function(e){ + var mouseCurrLocation=(isFlexVertical?e.clientY:e.clientX); + var beforeElNewRatio=(beforeElSize+(isFlexReverse?(mousedownLocation-mouseCurrLocation):(mouseCurrLocation-mousedownLocation)))/beforeElSize*beforeElRatio; + var afterElNewRatio=(afterElSize-(isFlexReverse?(mousedownLocation-mouseCurrLocation):(mouseCurrLocation-mousedownLocation)))/afterElSize*afterElRatio; + var totalRatio=beforeElRatio+afterElRatio; + if(beforeElNewRatio/totalRatio + Jelly Brainfuck Compiler diff --git a/jelly-bf-processhandler.js b/jelly-bf-processhandler.js index 98ea613..9371312 100644 --- a/jelly-bf-processhandler.js +++ b/jelly-bf-processhandler.js @@ -24,7 +24,10 @@ JellyBFProcessHandler.prototype.initialize=function(callback){ JellyBFProcessHandler.prototype.compile=function(sourcecode,options,callback){ this.worker.postMessage({type:"compile",sourcecode:sourcecode,options:options}); wait_for_message(this.worker,"compiled",function(message){ - callback(); + callback({success:true}); + }); + wait_for_message(this.worker,"compileerror",function(message){ + callback({success:false}); }); }; @@ -32,7 +35,10 @@ JellyBFProcessHandler.prototype.execute=function(inputstr,options,callback){ var encodedinput=new TextEncoder().encode(inputstr); this.worker.postMessage({type:"execute",inputuint8array:encodedinput,options:options},[encodedinput.buffer]); wait_for_message(this.worker,"executed",function(message){ - callback(new TextDecoder().decode(message.outputuint8array)); + callback({success:true,output:new TextDecoder().decode(message.outputuint8array)}); + }); + wait_for_message(this.worker,"executeerror",function(message){ + callback({success:false}); }); }; diff --git a/jelly-bf-worker.js b/jelly-bf-worker.js index 882dc86..72dda8c 100644 --- a/jelly-bf-worker.js +++ b/jelly-bf-worker.js @@ -6,8 +6,14 @@ case "compile": var sourcecode=message.sourcecode; var options=message.options; - module=JellyBFSync.compile(sourcecode,options); - self.postMessage({type:"compiled"}); + try{ + module=JellyBFSync.compile(sourcecode,options); + self.postMessage({type:"compiled"}); + } + catch(e){ + console.log(e); + self.postMessage({type:"compileerror"}); + } break; case "execute-interactive": var inputbuffer=message.inputbuffer; // circular buffer @@ -17,14 +23,26 @@ var outputwaitbuffer=message.outputwaitbuffer; // all wait buffers expected to be zeroed var options=message.options; - JellyBFSync.executeInteractive(module,UInt8Array(inputbuffer),UInt8Array(outputbuffer),Int32Array(inputwaitbuffer),Int32Array(outputwaitbuffer),options); - self.postMessage({type:"executed"}); + try{ + JellyBFSync.executeInteractive(module,UInt8Array(inputbuffer),UInt8Array(outputbuffer),Int32Array(inputwaitbuffer),Int32Array(outputwaitbuffer),options); + self.postMessage({type:"executed"}); + } + catch(e){ + console.log(e); + self.postMessage({type:"executeerror"}); + } break; case "execute": var inputuint8array=message.inputuint8array; var options=message.options; - var outputuint8array=JellyBFSync.execute(module,inputuint8array,options); - self.postMessage({type:"executed",outputuint8array:outputuint8array},[outputuint8array.buffer]); + try{ + var outputuint8array=JellyBFSync.execute(module,inputuint8array,options); + self.postMessage({type:"executed",outputuint8array:outputuint8array},[outputuint8array.buffer]); + } + catch(e){ + console.log(e); + self.postMessage({type:"executeerror"}); + } break; } }); diff --git a/jelly-bf-worker.max.js b/jelly-bf-worker.max.js index 07c8351..d0017ec 100644 --- a/jelly-bf-worker.max.js +++ b/jelly-bf-worker.max.js @@ -1629,10 +1629,17 @@ var JellyBFSync = { case "compile": var sourcecode = message.sourcecode; var options = message.options; - module = JellyBFSync.compile(sourcecode, options); - self.postMessage({ - type: "compiled" - }); + try { + module = JellyBFSync.compile(sourcecode, options); + self.postMessage({ + type: "compiled" + }); + } catch (e) { + console.log(e); + self.postMessage({ + type: "compileerror" + }); + } break; case "execute-interactive": @@ -1641,20 +1648,34 @@ var JellyBFSync = { var inputwaitbuffer = message.inputwaitbuffer; var outputwaitbuffer = message.outputwaitbuffer; var options = message.options; - JellyBFSync.executeInteractive(module, UInt8Array(inputbuffer), UInt8Array(outputbuffer), Int32Array(inputwaitbuffer), Int32Array(outputwaitbuffer), options); - self.postMessage({ - type: "executed" - }); + try { + JellyBFSync.executeInteractive(module, UInt8Array(inputbuffer), UInt8Array(outputbuffer), Int32Array(inputwaitbuffer), Int32Array(outputwaitbuffer), options); + self.postMessage({ + type: "executed" + }); + } catch (e) { + console.log(e); + self.postMessage({ + type: "executeerror" + }); + } break; case "execute": var inputuint8array = message.inputuint8array; var options = message.options; - var outputuint8array = JellyBFSync.execute(module, inputuint8array, options); - self.postMessage({ - type: "executed", - outputuint8array: outputuint8array - }, [ outputuint8array.buffer ]); + try { + var outputuint8array = JellyBFSync.execute(module, inputuint8array, options); + self.postMessage({ + type: "executed", + outputuint8array: outputuint8array + }, [ outputuint8array.buffer ]); + } catch (e) { + console.log(e); + self.postMessage({ + type: "executeerror" + }); + } break; } });