Skip to content

Commit

Permalink
working non-optimizing 8-bit version
Browse files Browse the repository at this point in the history
  • Loading branch information
btzy committed Mar 28, 2017
1 parent 95c9a2a commit 0486a77
Show file tree
Hide file tree
Showing 5 changed files with 961 additions and 0 deletions.
32 changes: 32 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Jelly Brainfuck Compiler</title>
<link rel="stylesheet" href="main.css" />
<script src="wasm32codegen.max.js" type="text/javascript"></script>
<script src="jelly-bf.js" type="text/javascript"></script>
<script src="main.js" type="text/javascript"></script>
</head>
<body>
<h2 class="area">Jelly Brainfuck Compiler</h2>
<div class="area">Brainfuck is compiled to WebAssembly and executed <span style="text-decoration:underline;">natively</span> in your browser. Each cell is 8 bytes. Input and output are treated as UTF-8.</div>
<div class="area">
<div>Code here:</div>
<textarea id="codetextbox"></textarea>
</div>
<div class="area">
<div>Input here:</div>
<textarea id="inputtextbox"></textarea>
</div>
<div class="area">
<div>Press this button:</div>
<input id="codebutton" type="button" value="Compile and run" />
</div>
<div class="area">
<div>Output here:</div>
<textarea id="outputtextbox" readonly></textarea>
<input id="clearoutputbutton" type="button" value="Clear output" />
</div>
</body>
</html>
103 changes: 103 additions & 0 deletions jelly-bf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
var JellyBF={
compile:function(str,options,callback){
// compiles BF code string to a WebAssembly.Module
var moduleWriter=new Wasm32ModuleWriter();

var memoryWriter=new Wasm32MemoryWriter(16,16);
moduleWriter.setMemory(memoryWriter);

var codeWriter=new Wasm32CodeWriter([Wasm32VarType.i32]); // ptr
var memIndex=0;
for(var i=0;i<str.length;++i){
switch(str[i]){
case '+':
codeWriter.get_local(0);
codeWriter.get_local(0);
codeWriter.i32_load8_u(0);
codeWriter.i32_const(1);
codeWriter.i32_add();
codeWriter.i32_store8(0); // TODO: is order of arguments correct?
break;
case '-':
codeWriter.get_local(0);
codeWriter.get_local(0);
codeWriter.i32_load8_u(0);
codeWriter.i32_const(1);
codeWriter.i32_sub();
codeWriter.i32_store8(0);
break;
case '>':
codeWriter.get_local(0);
codeWriter.i32_const(1);
codeWriter.i32_add();
codeWriter.set_local(0);
break;
case '<':
codeWriter.get_local(0);
codeWriter.i32_const(1);
codeWriter.i32_sub();
codeWriter.set_local(0);
break;
case '[':
codeWriter.get_local(0);
codeWriter.i32_load8_u(0);
codeWriter.if(Wasm32VarType.none);
codeWriter.loop(Wasm32VarType.none);
break;
case ']':
codeWriter.get_local(0);
codeWriter.i32_load8_u(0);
codeWriter.br_if(0);
codeWriter.end();
codeWriter.end();
break;
case ',':
codeWriter.get_local(0);
codeWriter.call("input"); // input: [] => [i32]
codeWriter.i32_store8(0);
break;
case '.':
codeWriter.get_local(0);
codeWriter.i32_load8_u(0);
codeWriter.call("output"); // output: [i32] => []
break;
}
}
codeWriter.end();
var type=new Wasm32TypeWriter([],[]).toUint8Array();
moduleWriter.addFunction("main",type,codeWriter);

moduleWriter.exportFunction("main","main");
moduleWriter.importFunction("input",new Wasm32TypeWriter([],[Wasm32VarType.i32]).toUint8Array(),"interaction","input");
moduleWriter.importFunction("output",new Wasm32TypeWriter([Wasm32VarType.i32],[]).toUint8Array(),"interaction","output");

var byteCode=moduleWriter.generateModule();

WebAssembly.compile(byteCode).then(function(compiledModule){
callback(compiledModule);
});
},
execute:function(compiledModule,inputString,callback){
var inputArr=new TextEncoder().encode(inputString);
var inputPtr=0;
var outputArr=new ResizableUint8Array();
WebAssembly.instantiate(compiledModule,{
interaction:{
input:function(){
if(inputPtr<inputArr.length){
return inputArr[inputPtr++];
}
else{
return 0;
}
},
output:function(byte){
outputArr.push(byte);
}
}
}).then(function(instance){
instance.exports.main();
callback(new TextDecoder().decode(outputArr.toUint8Array()));
});
}
};
10 changes: 10 additions & 0 deletions main.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.area{
margin:10px 0;
}

textarea{
width:100%;
min-height:120px;
box-sizing:border-box;
resize:vertical;
}
19 changes: 19 additions & 0 deletions main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
window.addEventListener("load",function(){
var codeTextbox=document.getElementById("codetextbox");
var inputTextbox=document.getElementById("inputtextbox");
var outputTextbox=document.getElementById("outputtextbox");
var codeButton=document.getElementById("codebutton");
var clearOutputButton=document.getElementById("clearoutputbutton");
codeButton.addEventListener("click",function(){
var codestr=codeTextbox.value;
var instr=inputTextbox.value;
JellyBF.compile(codestr,{},function(compiledModule){
JellyBF.execute(compiledModule,instr,function(outstr){
outputTextbox.value=outstr;
});
});
});
clearOutputButton.addEventListener("click",function(){
outputTextbox.value="";
});
});
Loading

0 comments on commit 0486a77

Please sign in to comment.