-
Notifications
You must be signed in to change notification settings - Fork 0
/
jelly-bf.js
108 lines (102 loc) · 4.13 KB
/
jelly-bf.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
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
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);
});
},
compileOptimized:function(str,options,callback){
WebAssembly.compile(JellyBFCompiler.compile(str,options)).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()));
});
}
};