diff --git a/index-notworking.html b/index-notworking.html
index 88a6dbc..af3d016 100644
--- a/index-notworking.html
+++ b/index-notworking.html
@@ -7,7 +7,7 @@
-
+
Jelly Brainfuck Compiler
diff --git a/jelly-bf-sync.js b/jelly-bf-sync.js
new file mode 100644
index 0000000..37440c2
--- /dev/null
+++ b/jelly-bf-sync.js
@@ -0,0 +1,83 @@
+var JellyBFSync={
+ compile:function(str,options){
+ return WebAssembly.Module(JellyBFCompiler.compile(str,options));
+ },
+ execute:function(module,inputuint8array,options){
+ options.eof_value=options.eof_value||0;
+ var inputindex=0;
+ var outputdata=new ResizableUint8Array();
+ var get_input=function(){
+ if(inputindex this._data.length) {
+ var new_buffer = new ArrayBuffer(Math.max(this._data.length * 2, this._size + amount));
+ var new_data = new Uint8Array(new_buffer);
+ for (var i = 0; i < this._size; ++i) {
+ new_data[i] = this._data[i];
+ }
+ this._buffer = new_buffer;
+ this._data = new_data;
+ }
+};
+
+ResizableUint8Array.prototype.push = function(value) {
+ this.reserve_extra(1);
+ this._data[this._size++] = value;
+};
+
+ResizableUint8Array.prototype.append = function(value_uint8array) {
+ this.reserve_extra(value_uint8array.length);
+ for (var i = 0; i < value_uint8array.length; ++i) {
+ this._data[this._size++] = value_uint8array[i];
+ }
+};
+
+ResizableUint8Array.prototype.pop = function() {
+ return this._data[--this._size];
+};
+
+ResizableUint8Array.prototype.insert_arr = function(index, value_uint8array) {
+ this.reserve_extra(value_uint8array.length);
+ for (var i = this._size - 1; i >= index; --i) {
+ this._data[i + value_uint8array.length] = this._data[i];
+ }
+ for (var i = 0; i < value_uint8array.length; ++i) {
+ this._data[index + i] = value_uint8array[i];
+ }
+ this._size += value_uint8array.length;
+};
+
+ResizableUint8Array.prototype.toUint8Array = function() {
+ var ret_arr = new Uint8Array(this._size);
+ for (var i = 0; i < this._size; ++i) {
+ ret_arr[i] = this._data[i];
+ }
+ return ret_arr;
+};
+
+var encodeUIntString = function(str) {
+ return new TextEncoder().encode(str);
+};
+
+var VLQEncoder = {};
+
+VLQEncoder.encodeUInt = function(value) {
+ if (value < 0 || value !== Math.floor(value)) debugger;
+ var output = new ResizableUint8Array();
+ while (true) {
+ var next_val = value % 128;
+ value = Math.floor(value / 128);
+ if (value > 0) {
+ output.push(128 + next_val);
+ } else {
+ output.push(next_val);
+ break;
+ }
+ }
+ return output.toUint8Array();
+};
+
+VLQEncoder.encodeInt = function(value) {
+ if (value !== Math.floor(value)) debugger;
+ var output = new ResizableUint8Array();
+ var is_neg = value < 0;
+ if (is_neg) value = -value - 1;
+ while (true) {
+ var next_val = value % 128;
+ value = Math.floor(value / 128);
+ if (value > 0 || next_val >= 64) {
+ if (is_neg) output.push(~next_val & 255); else output.push(128 + next_val);
+ } else {
+ if (is_neg) output.push(~next_val & 127); else output.push(next_val);
+ break;
+ }
+ }
+ return output.toUint8Array();
+};
+
+var Wasm32VarType = {
+ i32: 127,
+ i64: 126,
+ f32: 125,
+ f64: 124,
+ anyfunc: 112,
+ func: 96,
+ none: 64
+};
+
+var Wasm32ExternalKind = {
+ function: 0,
+ table: 1,
+ memory: 2,
+ global: 3
+};
+
+var Wasm32TypeWriter = function(param_types, result_types) {
+ this._param_types = param_types ? param_types : [];
+ this._result_types = result_types ? result_types : [];
+};
+
+Wasm32TypeWriter.prototype.toUint8Array = function() {
+ var output = new ResizableUint8Array();
+ output.push(Wasm32VarType.func);
+ output.append(VLQEncoder.encodeUInt(this._param_types.length));
+ for (var i = 0; i < this._param_types.length; ++i) {
+ output.push(this._param_types[i]);
+ }
+ output.append(VLQEncoder.encodeUInt(this._result_types.length));
+ for (var i = 0; i < this._result_types.length; ++i) {
+ output.push(this._result_types[i]);
+ }
+ return output.toUint8Array();
+};
+
+var Wasm32FunctionWriter = function(type_index) {
+ this._type = type_index;
+};
+
+Wasm32FunctionWriter.prototype.toUint8Array = function() {
+ var output = new ResizableUint8Array();
+ output.append(VLQEncoder.encodeUInt(this._type));
+ return output.toUint8Array();
+};
+
+var Wasm32CodeWriter = function(local_types) {
+ this._localTypes = local_types ? local_types : [];
+ this._data = new ResizableUint8Array();
+ this._functionlinks = [];
+};
+
+Wasm32CodeWriter.prototype.setName = function(name) {
+ this._functionname = name;
+};
+
+Wasm32CodeWriter.prototype.setType = function(type) {
+ this._functiontype = type;
+};
+
+Wasm32CodeWriter.prototype.setLocalTypes = function(local_types) {
+ this._localTypes = local_types ? local_types : [];
+};
+
+Wasm32CodeWriter.instruction = {
+ unreachable: 0,
+ nop: 1,
+ block: 2,
+ loop: 3,
+ if: 4,
+ else: 5,
+ end: 11,
+ br: 12,
+ br_if: 13,
+ br_table: 14,
+ return: 15,
+ call: 16,
+ call_indirect: 17,
+ drop: 26,
+ select: 27,
+ get_local: 32,
+ set_local: 33,
+ tee_local: 34,
+ get_global: 35,
+ set_global: 36,
+ i32_load: 40,
+ i64_load: 41,
+ f32_load: 42,
+ f64_load: 43,
+ i32_load8_s: 44,
+ i32_load8_u: 45,
+ i32_load16_s: 46,
+ i32_load16_u: 47,
+ i64_load8_s: 48,
+ i64_load8_u: 49,
+ i64_load16_s: 50,
+ i64_load16_u: 51,
+ i64_load32_s: 52,
+ i64_load32_u: 53,
+ i32_store: 54,
+ i64_store: 55,
+ f32_store: 56,
+ f64_store: 57,
+ i32_store8: 58,
+ i32_store16: 59,
+ i64_store8: 60,
+ i64_store16: 61,
+ i64_store32: 62,
+ current_memory: 63,
+ grow_memory: 64,
+ i32_const: 65,
+ i64_const: 66,
+ f32_const: 67,
+ f64_const: 68,
+ i32_eqz: 69,
+ i32_eq: 70,
+ i32_ne: 71,
+ i32_add: 106,
+ i32_sub: 107,
+ i32_mul: 108
+};
+
+Wasm32CodeWriter.prototype.writeRawBytes = function() {
+ for (var i = 0; i < arguments.length; ++i) {
+ if (!(arguments[i] >= 0 && arguments[i] < 256)) debugger;
+ this._data.push(arguments[i]);
+ }
+};
+
+Wasm32CodeWriter.prototype.writeUint8Array = function(arr) {
+ this._data.append(arr);
+};
+
+Wasm32CodeWriter.prototype.unreachable = function() {
+ this.writeRawBytes(Wasm32CodeWriter.instruction.unreachable);
+};
+
+Wasm32CodeWriter.prototype.nop = function() {
+ this.writeRawBytes(Wasm32CodeWriter.instruction.nop);
+};
+
+Wasm32CodeWriter.prototype.block = function(result_type) {
+ this.writeRawBytes(Wasm32CodeWriter.instruction.block, result_type);
+};
+
+Wasm32CodeWriter.prototype.loop = function(result_type) {
+ this.writeRawBytes(Wasm32CodeWriter.instruction.loop, result_type);
+};
+
+Wasm32CodeWriter.prototype.if = function(result_type) {
+ this.writeRawBytes(Wasm32CodeWriter.instruction.if, result_type);
+};
+
+Wasm32CodeWriter.prototype.else = function() {
+ this.writeRawBytes(Wasm32CodeWriter.instruction.else);
+};
+
+Wasm32CodeWriter.prototype.end = function() {
+ this.writeRawBytes(Wasm32CodeWriter.instruction.end);
+};
+
+Wasm32CodeWriter.prototype.br = function(relative_depth) {
+ this.writeRawBytes(Wasm32CodeWriter.instruction.br);
+ this.writeUint8Array(VLQEncoder.encodeUInt(relative_depth));
+};
+
+Wasm32CodeWriter.prototype.br_if = function(relative_depth) {
+ this.writeRawBytes(Wasm32CodeWriter.instruction.br_if);
+ this.writeUint8Array(VLQEncoder.encodeUInt(relative_depth));
+};
+
+Wasm32CodeWriter.prototype.return = function() {
+ this.writeRawBytes(Wasm32CodeWriter.instruction.return);
+};
+
+Wasm32CodeWriter.prototype.call = function(function_index_or_name) {
+ if (typeof function_index_or_name === "number") {
+ this.writeRawBytes(Wasm32CodeWriter.instruction.call);
+ this.writeUint8Array(VLQEncoder.encodeUInt(function_index_or_name));
+ } else {
+ this.writeRawBytes(Wasm32CodeWriter.instruction.call);
+ this._functionlinks.push({
+ location: this._data.size(),
+ name: function_index_or_name
+ });
+ }
+};
+
+Wasm32CodeWriter.prototype.drop = function() {
+ this.writeRawBytes(Wasm32CodeWriter.instruction.drop);
+};
+
+Wasm32CodeWriter.prototype.select = function() {
+ this.writeRawBytes(Wasm32CodeWriter.instruction.select);
+};
+
+Wasm32CodeWriter.prototype.get_local = function(localidx) {
+ this.writeRawBytes(Wasm32CodeWriter.instruction.get_local);
+ this.writeUint8Array(VLQEncoder.encodeUInt(localidx));
+};
+
+Wasm32CodeWriter.prototype.set_local = function(localidx) {
+ this.writeRawBytes(Wasm32CodeWriter.instruction.set_local);
+ this.writeUint8Array(VLQEncoder.encodeUInt(localidx));
+};
+
+Wasm32CodeWriter.prototype.tee_local = function(localidx) {
+ this.writeRawBytes(Wasm32CodeWriter.instruction.tee_local);
+ this.writeUint8Array(VLQEncoder.encodeUInt(localidx));
+};
+
+Wasm32CodeWriter.prototype.i32_load = function(offset, log_align) {
+ log_align = log_align || 0;
+ this.writeRawBytes(Wasm32CodeWriter.instruction.i32_load);
+ this.writeUint8Array(VLQEncoder.encodeUInt(log_align));
+ this.writeUint8Array(VLQEncoder.encodeUInt(offset));
+};
+
+Wasm32CodeWriter.prototype.i64_load = function(offset, log_align) {
+ log_align = log_align || 0;
+ this.writeRawBytes(Wasm32CodeWriter.instruction.i64_load);
+ this.writeUint8Array(VLQEncoder.encodeUInt(log_align));
+ this.writeUint8Array(VLQEncoder.encodeUInt(offset));
+};
+
+Wasm32CodeWriter.prototype.f32_load = function(offset, log_align) {
+ log_align = log_align || 0;
+ this.writeRawBytes(Wasm32CodeWriter.instruction.f32_load);
+ this.writeUint8Array(VLQEncoder.encodeUInt(log_align));
+ this.writeUint8Array(VLQEncoder.encodeUInt(offset));
+};
+
+Wasm32CodeWriter.prototype.f64_load = function(offset, log_align) {
+ log_align = log_align || 0;
+ this.writeRawBytes(Wasm32CodeWriter.instruction.f64_load);
+ this.writeUint8Array(VLQEncoder.encodeUInt(log_align));
+ this.writeUint8Array(VLQEncoder.encodeUInt(offset));
+};
+
+Wasm32CodeWriter.prototype.i32_load8_s = function(offset, log_align) {
+ log_align = log_align || 0;
+ this.writeRawBytes(Wasm32CodeWriter.instruction.i32_load8_s);
+ this.writeUint8Array(VLQEncoder.encodeUInt(log_align));
+ this.writeUint8Array(VLQEncoder.encodeUInt(offset));
+};
+
+Wasm32CodeWriter.prototype.i32_load8_u = function(offset, log_align) {
+ log_align = log_align || 0;
+ this.writeRawBytes(Wasm32CodeWriter.instruction.i32_load8_u);
+ this.writeUint8Array(VLQEncoder.encodeUInt(log_align));
+ this.writeUint8Array(VLQEncoder.encodeUInt(offset));
+};
+
+Wasm32CodeWriter.prototype.i32_load16_s = function(offset, log_align) {
+ log_align = log_align || 0;
+ this.writeRawBytes(Wasm32CodeWriter.instruction.i32_load16_s);
+ this.writeUint8Array(VLQEncoder.encodeUInt(log_align));
+ this.writeUint8Array(VLQEncoder.encodeUInt(offset));
+};
+
+Wasm32CodeWriter.prototype.i32_load16_u = function(offset, log_align) {
+ log_align = log_align || 0;
+ this.writeRawBytes(Wasm32CodeWriter.instruction.i32_load16_u);
+ this.writeUint8Array(VLQEncoder.encodeUInt(log_align));
+ this.writeUint8Array(VLQEncoder.encodeUInt(offset));
+};
+
+Wasm32CodeWriter.prototype.i64_load8_s = function(offset, log_align) {
+ log_align = log_align || 0;
+ this.writeRawBytes(Wasm32CodeWriter.instruction.i64_load8_s);
+ this.writeUint8Array(VLQEncoder.encodeUInt(log_align));
+ this.writeUint8Array(VLQEncoder.encodeUInt(offset));
+};
+
+Wasm32CodeWriter.prototype.i64_load8_u = function(offset, log_align) {
+ log_align = log_align || 0;
+ this.writeRawBytes(Wasm32CodeWriter.instruction.i64_load8_u);
+ this.writeUint8Array(VLQEncoder.encodeUInt(log_align));
+ this.writeUint8Array(VLQEncoder.encodeUInt(offset));
+};
+
+Wasm32CodeWriter.prototype.i64_load16_s = function(offset, log_align) {
+ log_align = log_align || 0;
+ this.writeRawBytes(Wasm32CodeWriter.instruction.i64_load16_s);
+ this.writeUint8Array(VLQEncoder.encodeUInt(log_align));
+ this.writeUint8Array(VLQEncoder.encodeUInt(offset));
+};
+
+Wasm32CodeWriter.prototype.i64_load16_u = function(offset, log_align) {
+ log_align = log_align || 0;
+ this.writeRawBytes(Wasm32CodeWriter.instruction.i64_load16_u);
+ this.writeUint8Array(VLQEncoder.encodeUInt(log_align));
+ this.writeUint8Array(VLQEncoder.encodeUInt(offset));
+};
+
+Wasm32CodeWriter.prototype.i64_load32_s = function(offset, log_align) {
+ log_align = log_align || 0;
+ this.writeRawBytes(Wasm32CodeWriter.instruction.i64_load32_s);
+ this.writeUint8Array(VLQEncoder.encodeUInt(log_align));
+ this.writeUint8Array(VLQEncoder.encodeUInt(offset));
+};
+
+Wasm32CodeWriter.prototype.i64_load32_u = function(offset, log_align) {
+ log_align = log_align || 0;
+ this.writeRawBytes(Wasm32CodeWriter.instruction.i64_load32_u);
+ this.writeUint8Array(VLQEncoder.encodeUInt(log_align));
+ this.writeUint8Array(VLQEncoder.encodeUInt(offset));
+};
+
+Wasm32CodeWriter.prototype.i32_store = function(offset, log_align) {
+ log_align = log_align || 0;
+ this.writeRawBytes(Wasm32CodeWriter.instruction.i32_store);
+ this.writeUint8Array(VLQEncoder.encodeUInt(log_align));
+ this.writeUint8Array(VLQEncoder.encodeUInt(offset));
+};
+
+Wasm32CodeWriter.prototype.i64_store = function(offset, log_align) {
+ log_align = log_align || 0;
+ this.writeRawBytes(Wasm32CodeWriter.instruction.i64_store);
+ this.writeUint8Array(VLQEncoder.encodeUInt(log_align));
+ this.writeUint8Array(VLQEncoder.encodeUInt(offset));
+};
+
+Wasm32CodeWriter.prototype.f32_store = function(offset, log_align) {
+ log_align = log_align || 0;
+ this.writeRawBytes(Wasm32CodeWriter.instruction.f32_store);
+ this.writeUint8Array(VLQEncoder.encodeUInt(log_align));
+ this.writeUint8Array(VLQEncoder.encodeUInt(offset));
+};
+
+Wasm32CodeWriter.prototype.f64_store = function(offset, log_align) {
+ log_align = log_align || 0;
+ this.writeRawBytes(Wasm32CodeWriter.instruction.f64_store);
+ this.writeUint8Array(VLQEncoder.encodeUInt(log_align));
+ this.writeUint8Array(VLQEncoder.encodeUInt(offset));
+};
+
+Wasm32CodeWriter.prototype.i32_store8 = function(offset, log_align) {
+ log_align = log_align || 0;
+ this.writeRawBytes(Wasm32CodeWriter.instruction.i32_store8);
+ this.writeUint8Array(VLQEncoder.encodeUInt(log_align));
+ this.writeUint8Array(VLQEncoder.encodeUInt(offset));
+};
+
+Wasm32CodeWriter.prototype.i32_store16 = function(offset, log_align) {
+ log_align = log_align || 0;
+ this.writeRawBytes(Wasm32CodeWriter.instruction.i32_store16);
+ this.writeUint8Array(VLQEncoder.encodeUInt(log_align));
+ this.writeUint8Array(VLQEncoder.encodeUInt(offset));
+};
+
+Wasm32CodeWriter.prototype.i64_store8 = function(offset, log_align) {
+ log_align = log_align || 0;
+ this.writeRawBytes(Wasm32CodeWriter.instruction.i64_store8);
+ this.writeUint8Array(VLQEncoder.encodeUInt(log_align));
+ this.writeUint8Array(VLQEncoder.encodeUInt(offset));
+};
+
+Wasm32CodeWriter.prototype.i64_store16 = function(offset, log_align) {
+ log_align = log_align || 0;
+ this.writeRawBytes(Wasm32CodeWriter.instruction.i64_store16);
+ this.writeUint8Array(VLQEncoder.encodeUInt(log_align));
+ this.writeUint8Array(VLQEncoder.encodeUInt(offset));
+};
+
+Wasm32CodeWriter.prototype.i64_store32 = function(offset, log_align) {
+ log_align = log_align || 0;
+ this.writeRawBytes(Wasm32CodeWriter.instruction.i64_store32);
+ this.writeUint8Array(VLQEncoder.encodeUInt(log_align));
+ this.writeUint8Array(VLQEncoder.encodeUInt(offset));
+};
+
+Wasm32CodeWriter.prototype.current_memory = function() {
+ this.writeRawBytes(Wasm32CodeWriter.instruction.current_memory, 0);
+};
+
+Wasm32CodeWriter.prototype.grow_memory = function() {
+ this.writeRawBytes(Wasm32CodeWriter.instruction.grow_memory, 0);
+};
+
+Wasm32CodeWriter.prototype.i32_const = function(val_i32) {
+ this.writeRawBytes(Wasm32CodeWriter.instruction.i32_const);
+ this.writeUint8Array(VLQEncoder.encodeInt(val_i32));
+};
+
+Wasm32CodeWriter.prototype.i64_const = function(val_i64) {
+ this.writeRawBytes(Wasm32CodeWriter.instruction.i64_const);
+ this.writeUint8Array(VLQEncoder.encodeInt(val_i64));
+};
+
+Wasm32CodeWriter.prototype.i32_eqz = function() {
+ this.writeRawBytes(Wasm32CodeWriter.instruction.i32_eqz);
+};
+
+Wasm32CodeWriter.prototype.i32_eq = function() {
+ this.writeRawBytes(Wasm32CodeWriter.instruction.i32_eq);
+};
+
+Wasm32CodeWriter.prototype.i32_ne = function() {
+ this.writeRawBytes(Wasm32CodeWriter.instruction.i32_ne);
+};
+
+Wasm32CodeWriter.prototype.i32_add = function() {
+ this.writeRawBytes(Wasm32CodeWriter.instruction.i32_add);
+};
+
+Wasm32CodeWriter.prototype.i32_sub = function() {
+ this.writeRawBytes(Wasm32CodeWriter.instruction.i32_sub);
+};
+
+Wasm32CodeWriter.prototype.i32_mul = function() {
+ this.writeRawBytes(Wasm32CodeWriter.instruction.i32_mul);
+};
+
+Wasm32CodeWriter.prototype.toUint8Array = function() {
+ var output = new ResizableUint8Array();
+ output.append(VLQEncoder.encodeUInt(this._localTypes.length));
+ for (var i = 0; i < this._localTypes.length; ++i) {
+ output.push(1);
+ output.push(this._localTypes[i]);
+ }
+ output.append(this._data.toUint8Array());
+ output.insert_arr(0, VLQEncoder.encodeUInt(output.size()));
+ return output.toUint8Array();
+};
+
+var Wasm32ExportWriter = function(field, kind, index) {
+ this._field = field;
+ this._kind = kind;
+ this._index = index;
+};
+
+Wasm32ExportWriter.prototype.setName = function(name) {
+ this._functionname = name;
+};
+
+Wasm32ExportWriter.prototype.toUint8Array = function() {
+ var output = new ResizableUint8Array();
+ var encoded_field_bytes = encodeUIntString(this._field);
+ output.append(VLQEncoder.encodeUInt(encoded_field_bytes.length));
+ output.append(encoded_field_bytes);
+ output.push(this._kind);
+ output.append(VLQEncoder.encodeUInt(this._index));
+ return output.toUint8Array();
+};
+
+var Wasm32ImportWriter = function(module, field, kind) {
+ this._module = module;
+ this._field = field;
+ this._kind = kind;
+};
+
+Wasm32ImportWriter.prototype.setName = function(name) {
+ this._functionname = name;
+};
+
+Wasm32ImportWriter.prototype.setType = function(type) {
+ this._functiontype = type;
+};
+
+Wasm32ImportWriter.prototype.toUint8Array = function() {
+ var output = new ResizableUint8Array();
+ var module_bytes = encodeUIntString(this._module);
+ var field_bytes = encodeUIntString(this._field);
+ output.push(VLQEncoder.encodeUInt(module_bytes.length));
+ output.append(module_bytes);
+ output.push(VLQEncoder.encodeUInt(field_bytes.length));
+ output.append(field_bytes);
+ output.push(this._kind);
+ output.append(VLQEncoder.encodeUInt(this._type));
+ return output.toUint8Array();
+};
+
+var Wasm32MemoryWriter = function(initial_pages, maximum_pages) {
+ this._initial_pages = initial_pages;
+ if (maximum_pages) this._maximum_pages = maximum_pages;
+};
+
+Wasm32MemoryWriter.prototype.toUint8Array = function() {
+ var output = new ResizableUint8Array();
+ if (this._maximum_pages) {
+ output.push(1);
+ output.append(VLQEncoder.encodeUInt(this._initial_pages));
+ output.append(VLQEncoder.encodeUInt(this._maximum_pages));
+ } else {
+ output.push(0);
+ output.append(VLQEncoder.encodeUInt(this._initial_pages));
+ }
+ return output.toUint8Array();
+};
+
+var Wasm32ModuleWriter = function() {
+ this._types = [];
+ this._imports = [];
+ this._functions = [];
+ this._memory = [];
+ this._exports = [];
+ this._codes = [];
+};
+
+Wasm32ModuleWriter.sectionCode = {
+ TYPE: 1,
+ IMPORT: 2,
+ FUNCTION: 3,
+ TABLE: 4,
+ MEMORY: 5,
+ GLOBAL: 6,
+ EXPORT: 7,
+ START: 8,
+ ELEMENT: 9,
+ CODE: 10,
+ DATA: 11
+};
+
+Wasm32ModuleWriter.prototype.setMemory = function(memory) {
+ this._memory = [ memory ];
+};
+
+Wasm32ModuleWriter.prototype.exportFunction = function(name, field) {
+ field = field || name;
+ var exportWriter = new Wasm32ExportWriter(field, Wasm32ExternalKind.function);
+ exportWriter.setName(name);
+ this._exports.push(exportWriter);
+};
+
+Wasm32ModuleWriter.prototype.importFunction = function(name, type, module, field) {
+ var importWriter = new Wasm32ImportWriter(module, field, Wasm32ExternalKind.function);
+ importWriter.setName(name);
+ importWriter.setType(type);
+ this._imports.push(importWriter);
+};
+
+Wasm32ModuleWriter.prototype.addFunction = function(name, type, codeWriter) {
+ codeWriter.setName(name);
+ codeWriter.setType(type);
+ this._codes.push(codeWriter);
+};
+
+Wasm32ModuleWriter.prototype.generateModule = function() {
+ var funcTypes = [];
+ var funcTypesOffset = this._types.length;
+ var funcTypesEqComp = function(type_data) {
+ return function(el) {
+ if (el.length != type_data.length) return false;
+ for (var i = 0; i < el.length; ++i) {
+ if (el[i] != type_data[i]) return false;
+ }
+ return true;
+ };
+ };
+ var funcNames = [];
+ var funcNamesOffset = this._functions.length;
+ this._imports.forEach(function(obj) {
+ var name = obj._functionname;
+ if (name) {
+ if (funcNames.findIndex(function(el) {
+ return el.name === name;
+ }) === -1) funcNames.push({
+ name: name,
+ funcType: obj._functiontype
+ }); else throw 'Repeated function "' + name + '".';
+ }
+ });
+ this._codes.forEach(function(obj) {
+ var name = obj._functionname;
+ if (name) {
+ if (funcNames.findIndex(function(el) {
+ return el.name === name;
+ }) === -1) funcNames.push({
+ name: name,
+ funcType: obj._functiontype
+ }); else throw 'Repeated function "' + name + '".';
+ }
+ });
+ funcNames.forEach(function(el) {
+ if (funcTypes.findIndex(funcTypesEqComp(el.funcType)) === -1) funcTypes.push(el.funcType);
+ });
+ var that = this;
+ funcTypes.forEach(function(type) {
+ that._types.push(type);
+ });
+ var that = this;
+ this._codes.forEach(function(obj) {
+ var type = obj._functiontype;
+ if (type) {
+ var typeIndex = funcTypes.findIndex(funcTypesEqComp(obj._functiontype)) + funcTypesOffset;
+ if (typeIndex === -1) throw "Weird assembler bug.";
+ var functionWriter = new Wasm32FunctionWriter(typeIndex);
+ that._functions.push(functionWriter);
+ }
+ });
+ this._imports.forEach(function(obj) {
+ var type = obj._functiontype;
+ if (type) {
+ var typeIndex = funcTypes.findIndex(funcTypesEqComp(type)) + funcTypesOffset;
+ if (typeIndex === -1) throw "Weird assembler bug.";
+ obj._type = typeIndex;
+ }
+ });
+ this._codes.forEach(function(obj) {
+ var functionLinks = obj._functionlinks;
+ functionLinks.sort(function(a, b) {
+ return b.location - a.location;
+ });
+ functionLinks.forEach(function(functionLink) {
+ var funcIndex = funcNames.findIndex(function(el) {
+ return el.name === functionLink.name;
+ }) + funcNamesOffset;
+ if (funcIndex === -1) throw 'Undeclared function "' + functionLink.name + '".';
+ obj._data.insert_arr(functionLink.location, VLQEncoder.encodeUInt(funcIndex));
+ });
+ });
+ this._exports.forEach(function(obj) {
+ var name = obj._functionname;
+ if (name) {
+ var funcIndex = funcNames.findIndex(function(el) {
+ return el.name === name;
+ }) + funcNamesOffset;
+ if (funcIndex === -1) throw 'Undeclared function "' + functionLink.name + '".';
+ obj._index = funcIndex;
+ }
+ });
+ this._exports.forEach(function(obj) {
+ if (obj._functionname) obj._functionname = undefined;
+ });
+ this._imports.forEach(function(obj) {
+ if (obj._functionname) {
+ obj._functionname = undefined;
+ obj._functiontype = undefined;
+ }
+ });
+ this._codes.forEach(function(obj) {
+ if (obj._functionname) {
+ obj._functionname = undefined;
+ obj._functiontype = undefined;
+ }
+ });
+ var output = new ResizableUint8Array();
+ var wasm_header = new Uint8Array(8);
+ wasm_header[0] = 0;
+ wasm_header[1] = 97;
+ wasm_header[2] = 115;
+ wasm_header[3] = 109;
+ wasm_header[4] = 1;
+ wasm_header[5] = 0;
+ wasm_header[6] = 0;
+ wasm_header[7] = 0;
+ output.append(wasm_header);
+ if (this._types.length > 0) {
+ output.push(Wasm32ModuleWriter.sectionCode.TYPE);
+ var sizeloc = output.size();
+ output.append(VLQEncoder.encodeUInt(this._types.length));
+ for (var i = 0; i < this._types.length; ++i) {
+ output.append(this._types[i]);
+ }
+ output.insert_arr(sizeloc, VLQEncoder.encodeUInt(output.size() - sizeloc));
+ }
+ if (this._imports.length > 0) {
+ output.push(Wasm32ModuleWriter.sectionCode.IMPORT);
+ var sizeloc = output.size();
+ output.append(VLQEncoder.encodeUInt(this._imports.length));
+ for (var i = 0; i < this._imports.length; ++i) {
+ output.append(this._imports[i].toUint8Array());
+ }
+ output.insert_arr(sizeloc, VLQEncoder.encodeUInt(output.size() - sizeloc));
+ }
+ if (this._functions.length > 0) {
+ output.push(Wasm32ModuleWriter.sectionCode.FUNCTION);
+ var sizeloc = output.size();
+ output.append(VLQEncoder.encodeUInt(this._functions.length));
+ for (var i = 0; i < this._functions.length; ++i) {
+ output.append(this._functions[i].toUint8Array());
+ }
+ output.insert_arr(sizeloc, VLQEncoder.encodeUInt(output.size() - sizeloc));
+ }
+ if (this._memory.length > 0) {
+ output.push(Wasm32ModuleWriter.sectionCode.MEMORY);
+ var sizeloc = output.size();
+ output.append(VLQEncoder.encodeUInt(this._memory.length));
+ for (var i = 0; i < this._memory.length; ++i) {
+ output.append(this._memory[i].toUint8Array());
+ }
+ output.insert_arr(sizeloc, VLQEncoder.encodeUInt(output.size() - sizeloc));
+ }
+ if (this._exports.length > 0) {
+ output.push(Wasm32ModuleWriter.sectionCode.EXPORT);
+ var sizeloc = output.size();
+ output.append(VLQEncoder.encodeUInt(this._exports.length));
+ for (var i = 0; i < this._exports.length; ++i) {
+ output.append(this._exports[i].toUint8Array());
+ }
+ output.insert_arr(sizeloc, VLQEncoder.encodeUInt(output.size() - sizeloc));
+ }
+ if (this._codes.length > 0) {
+ output.push(Wasm32ModuleWriter.sectionCode.CODE);
+ var sizeloc = output.size();
+ output.append(VLQEncoder.encodeUInt(this._codes.length));
+ for (var i = 0; i < this._codes.length; ++i) {
+ output.append(this._codes[i].toUint8Array());
+ }
+ output.insert_arr(sizeloc, VLQEncoder.encodeUInt(output.size() - sizeloc));
+ }
+ return output.toUint8Array();
+};
+
+var JellyBFCompiler = {};
+
+JellyBFCompiler.compile = function(str, options) {
+ if (options.wraparound === undefined) options.wraparound = true;
+ if (options.infiniteloops === undefined) options.infiniteloops = true;
+ if (options.bitwidth === undefined) options.bitwidth = 8;
+ if (options.bitwidth !== 8 && options.bitwidth !== 16 && options.bitwidth !== 32) return;
+ var codeChunks = [];
+ for (var i = 0; i < str.length; ++i) {
+ switch (str[i]) {
+ case "+":
+ var newDelta = new JellyBFRangeDelta();
+ newDelta.addDelta(0, 1);
+ JellyBF_InsertAndAttemptCoalesceDeltas(codeChunks, newDelta);
+ break;
+
+ case "-":
+ var newDelta = new JellyBFRangeDelta();
+ newDelta.addDelta(0, -1);
+ JellyBF_InsertAndAttemptCoalesceDeltas(codeChunks, newDelta);
+ break;
+
+ case ">":
+ var newDelta = new JellyBFRangeDelta();
+ newDelta.addExitDelta(1);
+ JellyBF_InsertAndAttemptCoalesceDeltas(codeChunks, newDelta);
+ break;
+
+ case "<":
+ var newDelta = new JellyBFRangeDelta();
+ newDelta.addExitDelta(-1);
+ JellyBF_InsertAndAttemptCoalesceDeltas(codeChunks, newDelta);
+ break;
+
+ case "[":
+ codeChunks.push("[");
+ break;
+
+ case "]":
+ JellyBF_CloseAndAttemptUnrollLoop(codeChunks, options);
+ break;
+
+ case ",":
+ codeChunks.push(",");
+ break;
+
+ case ".":
+ codeChunks.push(".");
+ break;
+ }
+ }
+ var resolvedCodeChunks = [];
+ var currentState = new JellyBFPossibleState(true);
+ for (var i = 0; i < codeChunks.length; ++i) {}
+ return JellyBF_WriteCodeChunksToModule(codeChunks);
+};
+
+var JellyBF_WriteCodeChunksToModule = function(codeChunks) {
+ var moduleWriter = new Wasm32ModuleWriter();
+ var memoryWriter = new Wasm32MemoryWriter(16, 16);
+ moduleWriter.setMemory(memoryWriter);
+ var codeWriter = new Wasm32CodeWriter([ Wasm32VarType.i32 ]);
+ codeWriter.i32_const(524288);
+ codeWriter.set_local(0);
+ var maxlocals = 1;
+ for (var i = 0; i < codeChunks.length; ++i) {
+ if (codeChunks[i] instanceof JellyBFRangeDelta) {
+ var jellyBFrangedelta = codeChunks[i];
+ if (jellyBFrangedelta._data.length > 0) {
+ var stateRefsLocalOffset = 1;
+ var stateRefs = [];
+ jellyBFrangedelta._data.forEach(function(entry) {
+ if (entry._combination.isZero()) debugger;
+ entry._combination._terms.forEach(function(term) {
+ term._parts.forEach(function(part) {
+ if (part instanceof JellyBFLinearStateRef) {
+ var stateRefIndex = stateRefs.findIndex(function(arg) {
+ return arg >= part._index;
+ });
+ if (stateRefIndex === -1) stateRefs.push(part._index); else if (stateRefs[stateRefIndex] !== part._index) stateRefs.splice(stateRefIndex, 0, part._index);
+ } else debugger;
+ });
+ });
+ });
+ var offset = Math.min(jellyBFrangedelta._data[0]._index, jellyBFrangedelta._exitindex);
+ if (stateRefs.length > 0) offset = Math.min(offset, stateRefs[0]);
+ if (offset !== 0) {
+ codeWriter.get_local(0);
+ codeWriter.i32_const(offset);
+ codeWriter.i32_add();
+ codeWriter.set_local(0);
+ }
+ stateRefs.forEach(function(ref, localidx) {
+ var effectiveLocalIdx = stateRefsLocalOffset + localidx;
+ var effectiveOffset = ref - offset;
+ codeWriter.get_local(0);
+ codeWriter.i32_load8_u(effectiveOffset);
+ codeWriter.set_local(effectiveLocalIdx);
+ });
+ jellyBFrangedelta._data.forEach(function(entry) {
+ if (entry._combination.isZero()) debugger;
+ var effectiveOffset = entry._index - offset;
+ codeWriter.get_local(0);
+ codeWriter.get_local(0);
+ codeWriter.i32_load8_u(effectiveOffset);
+ entry._combination._terms.forEach(function(term, termindex) {
+ if (term._coefficient === 0) debugger;
+ if (term._parts.length === 1 && term._coefficient === 1) {
+ var part = term._parts[0];
+ if (part instanceof JellyBFLinearStateRef) {
+ var stateRefIndex = stateRefs.findIndex(function(arg) {
+ return arg >= part._index;
+ });
+ var effectiveLocalIdx = stateRefsLocalOffset + stateRefIndex;
+ codeWriter.get_local(effectiveLocalIdx);
+ } else debugger;
+ } else {
+ codeWriter.i32_const(term._coefficient);
+ term._parts.forEach(function(part) {
+ if (part instanceof JellyBFLinearStateRef) {
+ var stateRefIndex = stateRefs.findIndex(function(arg) {
+ return arg >= part._index;
+ });
+ var effectiveLocalIdx = stateRefsLocalOffset + stateRefIndex;
+ codeWriter.get_local(effectiveLocalIdx);
+ codeWriter.i32_mul();
+ } else debugger;
+ });
+ }
+ codeWriter.i32_add();
+ });
+ codeWriter.i32_store8(effectiveOffset);
+ });
+ if (jellyBFrangedelta._exitindex - offset !== 0) {
+ codeWriter.get_local(0);
+ codeWriter.i32_const(jellyBFrangedelta._exitindex - offset);
+ codeWriter.i32_add();
+ codeWriter.set_local(0);
+ }
+ maxlocals = Math.max(maxlocals, stateRefsLocalOffset + stateRefs.length);
+ } else {
+ if (jellyBFrangedelta._exitindex !== 0) {
+ codeWriter.get_local(0);
+ codeWriter.i32_const(codeChunks[i]._exitindex);
+ codeWriter.i32_add();
+ codeWriter.set_local(0);
+ }
+ }
+ } else {
+ switch (codeChunks[i]) {
+ 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");
+ codeWriter.i32_store8(0);
+ break;
+
+ case ".":
+ codeWriter.get_local(0);
+ codeWriter.i32_load8_u(0);
+ codeWriter.call("output");
+ break;
+ }
+ }
+ }
+ codeWriter.end();
+ var localTypesParam = [];
+ for (var i = 0; i < maxlocals; ++i) {
+ localTypesParam.push(Wasm32VarType.i32);
+ }
+ codeWriter.setLocalTypes(localTypesParam);
+ 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();
+ return byteCode;
+};
+
+var JellyBFEntry = function(index, delta) {
+ this._index = index;
+ this._delta = delta;
+};
+
+var JellyBFDelta = function() {
+ this._data = [];
+ this._exitindex = 0;
+};
+
+JellyBFDelta.prototype.applyDelta = function(index, delta) {
+ var dataIndex = this._data.findIndex(function(el) {
+ return el._index >= index;
+ });
+ if (dataIndex === -1) {
+ if (delta !== 0) this._data.push(new JellyBFEntry(index, delta));
+ } else if (this._data[dataIndex]._index === index) {
+ this._data[dataIndex]._delta += delta;
+ if (this._data[dataIndex]._delta === 0) this._data.splice(dataIndex, 1);
+ } else {
+ if (delta !== 0) this._data.splice(dataIndex, 0, new JellyBFEntry(index, delta));
+ }
+};
+
+JellyBFDelta.prototype.applyExitDelta = function(delta) {
+ this._exitindex += delta;
+};
+
+JellyBFDelta.prototype.coalesceWith = function(jellyBFdelta) {
+ var that = this;
+ jellyBFdelta._data.forEach(function(entry) {
+ that.applyDelta(that._exitindex + entry._index, entry._delta);
+ });
+ this._exitindex += jellyBFdelta._exitindex;
+};
+
+var find_gcd = function(a, b) {
+ if (a < b) {
+ var tmp = a;
+ a = b;
+ b = tmp;
+ }
+ if (b === 0) return a;
+ return find_gcd(b, a % b);
+};
+
+var RationalNumber = function(num, den) {
+ this._sgn = num < 0;
+ this._num = Math.abs(num);
+ this._den = den;
+};
+
+RationalNumber.prototype.reduce = function() {
+ var gcd = find_gcd(this._num, this._den);
+ this._num /= gcd;
+ this._den /= gcd;
+};
+
+RationalNumber.prototype.multiplyWith = function(val) {
+ if (val instanceof RationalNumber) {
+ this._sgn = this._sgn !== val._sgn;
+ this._num *= val._num;
+ this._den *= val._den;
+ this.reduce();
+ } else {
+ this._sgn = this.sgn !== val < 0;
+ this.num *= Math.abs(val);
+ this.reduce();
+ }
+};
+
+var JellyBFLinearStateRef = function(index) {
+ this._index = index;
+};
+
+JellyBFLinearStateRef.sortOrder = 1;
+
+JellyBFLinearStateRef.Comparer = function(a, b) {
+ return a._index - b._index;
+};
+
+JellyBFLinearStateRef.prototype.addShift = function(index_shift, input_shift) {
+ this._index += index_shift;
+};
+
+JellyBFLinearStateRef.prototype.clone = function() {
+ return new JellyBFLinearStateRef(this._index);
+};
+
+var JellyBFLinearInputRef = function(index) {
+ this._index = index;
+};
+
+JellyBFLinearInputRef.sortOrder = 2;
+
+JellyBFLinearInputRef.Comparer = function(a, b) {
+ return a._index - b._index;
+};
+
+JellyBFLinearInputRef.prototype.addShift = function(index_shift, input_shift) {
+ this._index += input_shift;
+};
+
+JellyBFLinearInputRef.prototype.clone = function() {
+ return new JellyBFLinearInputRef(this._index);
+};
+
+var JellyBFLinearTermParts = {};
+
+JellyBFLinearTermParts.Comparer = function(a, b) {
+ var aconstructor = a.constructor;
+ var bconstructor = b.constructor;
+ if (aconstructor !== bconstructor) {
+ return aconstructor.sortOrder - bconstructor.sortOrder;
+ }
+ return aconstructor.Comparer(a, b);
+};
+
+JellyBFLinearTermParts.FinderLow = function(a) {
+ return function(arg) {
+ return JellyBFLinearTermParts.Comparer(arg, a) >= 0;
+ };
+};
+
+var JellyBFLinearTerm = function(coefficient) {
+ this._parts = [];
+ this._coefficient = coefficient;
+};
+
+JellyBFLinearTerm.makeConstant = function(value) {
+ var ret = new JellyBFLinearTerm();
+ ret._coefficient = value;
+ return ret;
+};
+
+JellyBFLinearTerm.makeFromPart = function(part) {
+ var ret = new JellyBFLinearTerm(1);
+ ret._parts = [ part ];
+ return ret;
+};
+
+JellyBFLinearTerm.Comparer = function(a, b) {
+ var maxlen = Math.max(a._parts.length, b._parts.length);
+ for (var i = 0; i < maxlen; ++i) {
+ if (a._parts.length <= i) return -1;
+ if (b._parts.length <= i) return 1;
+ var ret = JellyBFLinearTermParts.Comparer(a._parts[i], b._parts[i]);
+ if (ret !== 0) return ret;
+ }
+ return 0;
+};
+
+JellyBFLinearTerm.FinderLow = function(a) {
+ return function(arg) {
+ return JellyBFLinearTerm.Comparer(arg, a) >= 0;
+ };
+};
+
+JellyBFLinearTerm.IsEqual = function(a, b) {
+ if (a._parts.length !== b._parts.length) return false;
+ var len = a._parts.length;
+ for (var i = 0; i < len; ++i) {
+ var ret = JellyBFLinearTermParts.Comparer(a._parts[i], b._parts[i]);
+ if (ret !== 0) return false;
+ }
+ return true;
+};
+
+JellyBFLinearTerm.prototype.addWith = function(linearterm) {
+ this._coefficient += linearterm._coefficient;
+};
+
+JellyBFLinearTerm.prototype.multiplyWith = function(linearterm) {
+ if (linearterm.isZero()) debugger;
+ var this_parts = this._parts;
+ linearterm._parts.forEach(function(part) {
+ var index = this_parts.findIndex(JellyBFLinearTermParts.FinderLow(part));
+ if (index === -1) {
+ this_parts.push(part);
+ } else {
+ this_parts.splice(index, 0, part);
+ }
+ });
+ this._coefficient *= linearterm._coefficient;
+};
+
+JellyBFLinearTerm.prototype.isZero = function() {
+ return this._coefficient === 0;
+};
+
+JellyBFLinearTerm.prototype.clone = function() {
+ var ret = new JellyBFLinearTerm(this._coefficient);
+ this._parts.forEach(function(part) {
+ ret._parts.push(part.clone());
+ });
+ return ret;
+};
+
+var JellyBFLinear = function() {
+ this._terms = [];
+};
+
+JellyBFLinear.prototype.addTerm = function(linearterm) {
+ if (linearterm.isZero()) debugger;
+ var dataIndex = this._terms.findIndex(JellyBFLinearTerm.FinderLow(linearterm));
+ if (dataIndex === -1) {
+ this._terms.push(linearterm);
+ } else if (JellyBFLinearTerm.IsEqual(this._terms[dataIndex], linearterm)) {
+ this._terms[dataIndex].addWith(linearterm);
+ if (this._terms[dataIndex].isZero()) this._terms.splice(dataIndex, 1);
+ } else {
+ this._terms.splice(dataIndex, 0, linearterm);
+ }
+};
+
+JellyBFLinear.prototype.multiplyTerm = function(linearterm) {
+ if (linearterm.isZero()) debugger;
+ this._terms.forEach(function(term) {
+ term.multiplyWith(linearterm.clone());
+ });
+};
+
+JellyBFLinear.prototype.multiplyLinear = function(linearcombination) {
+ var old_terms = this._terms;
+ var new_terms = [];
+ linearcombination._terms.forEach(function(ins_term) {
+ old_terms.forEach(function(old_term) {
+ var cl = old_term.clone();
+ cl.multiplyWith(ins_term.clone());
+ new_terms.push(cl);
+ });
+ });
+ new_terms.sort(JellyBFLinearTerm.Comparer);
+ this._terms = new_terms;
+};
+
+JellyBFLinear.prototype.isZero = function() {
+ return this._terms.length === 0;
+};
+
+JellyBFLinear.prototype.clone = function() {
+ var ret = new JellyBFLinear();
+ this._terms.forEach(function(term) {
+ ret._terms.push(term.clone());
+ });
+ return ret;
+};
+
+JellyBFLinear.prototype.coalesceWith = function(jellyBFlinear) {
+ var that = this;
+ jellyBFlinear._terms.forEach(function(term) {
+ that.addTerm(term);
+ });
+};
+
+JellyBFLinear.prototype.expandState = function(jellyBFrangedelta) {
+ if (!(jellyBFrangedelta instanceof JellyBFRangeDelta)) debugger;
+ var new_terms = [];
+ this._terms.forEach(function(term) {
+ var part_indices_for_expansion = [];
+ var new_term = new JellyBFLinearTerm(term._coefficient);
+ term._parts.forEach(function(part) {
+ if (part instanceof JellyBFLinearStateRef) {
+ part_indices_for_expansion.push(part._index);
+ } else if (part instanceof JellyBFLinearOutputRef) {
+ new_term.push(part);
+ } else debugger;
+ });
+ var lincombin = new JellyBFLinear();
+ lincombin.addTerm(JellyBFLinearTerm.makeConstant(1));
+ part_indices_for_expansion.forEach(function(index) {
+ var applyIndex = jellyBFrangedelta._data.findIndex(JellyBFRangeEntry.FinderEqualIndex(index));
+ var applyCombination = new JellyBFLinear();
+ applyCombination.addTerm(JellyBFLinearTerm.makeFromPart(new JellyBFLinearStateRef(index)));
+ if (applyIndex !== -1) {
+ applyCombination.coalesceWith(jellyBFrangedelta._data[applyIndex]._combination.clone());
+ }
+ lincombin.multiplyLinear(applyCombination);
+ });
+ lincombin.multiplyTerm(new_term);
+ lincombin._terms.forEach(function(term) {
+ new_terms.push(term);
+ });
+ });
+ this._terms = [];
+ var that = this;
+ new_terms.forEach(function(term) {
+ that.addTerm(term);
+ });
+};
+
+JellyBFLinear.IsExactSame = function(a, b) {
+ if (a._terms.length !== b._terms.length) return false;
+ var maxlen = a._terms.length;
+ for (var i = 0; i < maxlen; ++i) {
+ if (!JellyBFLinearTerm.IsEqual(a._terms[i], b._terms[i])) return false;
+ if (a._terms[i]._coefficient !== b._terms[i]._coefficient) return false;
+ }
+ return true;
+};
+
+var JellyBFRangeEntry = function(index) {
+ this._index = index;
+ this._combination = new JellyBFLinear();
+};
+
+JellyBFRangeEntry.Comparer = function(a, b) {
+ return a._index - b._index;
+};
+
+JellyBFRangeEntry.FinderLow = function(a) {
+ return function(arg) {
+ return arg._index >= a._index;
+ };
+};
+
+JellyBFRangeEntry.FinderLowIndex = function(index) {
+ return function(arg) {
+ return arg._index >= index;
+ };
+};
+
+JellyBFRangeEntry.FinderEqual = function(a) {
+ return function(arg) {
+ return arg._index === a._index;
+ };
+};
+
+JellyBFRangeEntry.FinderEqualIndex = function(index) {
+ return function(arg) {
+ return arg._index === index;
+ };
+};
+
+JellyBFRangeEntry.IsEqual = function(a, b) {
+ return a._index === b._index;
+};
+
+JellyBFRangeEntry.IsEqualIndex = function(a, index) {
+ return a._index === index;
+};
+
+JellyBFRangeEntry.prototype.addTerm = function(linearterm) {
+ this._combination.addTerm(linearterm);
+};
+
+JellyBFRangeEntry.prototype.multiplyTerm = function(linearterm) {
+ this._combination.multiplyTerm(linearterm);
+};
+
+JellyBFRangeEntry.prototype.isZero = function() {
+ return this._combination.isZero();
+};
+
+JellyBFRangeEntry.prototype.coalesceWith = function(jellyBFrangeentry) {
+ this._combination.coalesceWith(jellyBFrangeentry._combination);
+};
+
+JellyBFRangeEntry.makeFromTerm = function(index, term) {
+ if (!(term instanceof JellyBFLinearTerm)) debugger;
+ var ret = new JellyBFRangeEntry(index);
+ ret.addTerm(term);
+ return ret;
+};
+
+var JellyBFRangeDelta = function() {
+ this._data = [];
+ this._outputs = [];
+ this._exitindex = 0;
+ this._inputcount = 0;
+};
+
+JellyBFRangeDelta.prototype.addEntry = function(jellyBFrangeentry) {
+ var dataIndex = this._data.findIndex(JellyBFRangeEntry.FinderLow(jellyBFrangeentry));
+ if (dataIndex === -1) {
+ this._data.push(jellyBFrangeentry);
+ } else if (JellyBFRangeEntry.IsEqual(this._data[dataIndex], jellyBFrangeentry)) {
+ this._data[dataIndex].coalesceWith(jellyBFrangeentry);
+ if (this._data[dataIndex].isZero()) this._data.splice(dataIndex, 1);
+ } else {
+ this._data.splice(dataIndex, 0, jellyBFrangeentry);
+ }
+};
+
+JellyBFRangeDelta.prototype.addDelta = function(index, delta) {
+ var dataIndex = this._data.findIndex(JellyBFRangeEntry.FinderLowIndex(index));
+ if (dataIndex === -1) {
+ if (delta !== 0) this._data.push(JellyBFRangeEntry.makeFromTerm(index, JellyBFLinearTerm.makeConstant(delta)));
+ } else if (JellyBFRangeEntry.IsEqualIndex(this._data[dataIndex], index)) {
+ this._data[dataIndex].addTerm(JellyBFLinearTerm.makeConstant(delta));
+ if (this._data[dataIndex].isZero()) this._data.splice(dataIndex, 1);
+ } else {
+ if (delta !== 0) this._data.splice(dataIndex, 0, JellyBFRangeEntry.makeFromTerm(index, JellyBFLinearTerm.makeConstant(delta)));
+ }
+};
+
+JellyBFRangeDelta.prototype.addExitDelta = function(delta) {
+ this._exitindex += delta;
+};
+
+JellyBFRangeDelta.prototype.coalesceWith = function(jellyBFrangedelta) {
+ var that = this;
+ var exitindex_offset = this._exitindex;
+ var inputindex_offset = this._inputcount;
+ jellyBFrangedelta._data.forEach(function(rangeentry) {
+ rangeentry._index += exitindex_offset;
+ rangeentry._combination._terms.forEach(function(linearterm) {
+ linearterm._parts.forEach(function(linearpart) {
+ linearpart.addShift(exitindex_offset, inputindex_offset);
+ });
+ });
+ });
+ jellyBFrangedelta._outputs.forEach(function(linearcombination) {
+ linearcombination._terms.forEach(function(linearterm) {
+ linearterm._parts.forEach(function(linearpart) {
+ linearpart.addShift(exitindex_offset, inputindex_offset);
+ });
+ });
+ });
+ var entries_to_add = [];
+ jellyBFrangedelta._data.forEach(function(entry) {
+ entry._combination.expandState(that);
+ entries_to_add.push(entry);
+ });
+ jellyBFrangedelta._outputs.forEach(function(linearcombination) {
+ linearcombination.expandState(that);
+ that._outputs.push(linearcombination);
+ });
+ entries_to_add.forEach(function(entry) {
+ that.addEntry(entry);
+ });
+ for (var i = this._data.length - 1; i >= 0; --i) {
+ if (this._data[i].isZero()) this._data.splice(i, 1);
+ }
+ this._exitindex += jellyBFrangedelta._exitindex;
+ this._inputcount += jellyBFrangedelta._inputcount;
+};
+
+JellyBFRangeDelta.prototype.wrapWithLoop = function(options) {
+ if (this._exitindex === 0) {
+ var dataIndex = this._data.findIndex(JellyBFRangeEntry.FinderEqualIndex(0));
+ if (dataIndex === -1) {
+ return false;
+ } else if (JellyBFLinear.IsExactSame(this._data[dataIndex]._combination, JellyBFRangeEntry.makeFromTerm(0, JellyBFLinearTerm.makeConstant(-1))._combination)) {
+ var is_all_constant = true;
+ this._data.forEach(function(jellybfentry) {
+ jellybfentry._combination._terms.forEach(function(term) {
+ if (term._parts.length !== 0) is_all_constant = false;
+ });
+ });
+ if (!is_all_constant) return false;
+ this._data.forEach(function(jellybfentry) {
+ var newTerm = new JellyBFLinearTerm(1);
+ newTerm._parts.push(new JellyBFLinearStateRef(0));
+ jellybfentry.multiplyTerm(newTerm);
+ });
+ return true;
+ }
+ return false;
+ }
+ return false;
+};
+
+JellyBFRangeDelta.prototype.writeCode = function(codeWriter) {};
+
+var JellyBFPossibleStateEntry = function(index, value) {
+ this._index = index;
+ this._value = value;
+};
+
+JellyBFPossibleStateEntry.FinderLowIndex = function(index) {
+ return function(arg) {
+ return arg._index >= index;
+ };
+};
+
+var JellyBFPossibleState = function(emptyIsZero) {
+ if (emptyIsZero !== true && emptyIsZero !== false) debugger;
+ this.emptyIsZero = emptyIsZero;
+ this._data = [];
+};
+
+JellyBFPossibleState.prototype.getState = function(index) {
+ var dataIndex = this._data.findIndex(JellyBFPossibleStateEntry.FinderLowIndex(index));
+ if (dataIndex === -1) {
+ if (this.emptyIsZero) {
+ return 0;
+ } else {
+ return undefined;
+ }
+ }
+ return this._data[dataIndex]._value;
+};
+
+JellyBFPossibleState.prototype.setState = function(index, value) {
+ var dataIndex = this._data.findIndex(JellyBFPossibleStateEntry.FinderLowIndex(index));
+ if (dataIndex === -1) {
+ if (this.emptyIsZero && value !== 0 || !this.emptyIsZero && value !== undefined) {
+ this._data.splice(dataIndex, 0, new JellyBFPossibleStateEntry(index, value));
+ }
+ } else {
+ if (this.emptyIsZero && value === 0 || !this.emptyIsZero && value === undefined) {
+ this._data.splice(dataIndex, 1);
+ } else {
+ this._data[dataIndex]._value = value;
+ }
+ }
+};
+
+var JellyBF_InsertAndAttemptCoalesceDeltas = function(codeChunks, newDelta) {
+ if (codeChunks.length > 0 && codeChunks[codeChunks.length - 1] instanceof JellyBFRangeDelta) {
+ codeChunks[codeChunks.length - 1].coalesceWith(newDelta);
+ } else {
+ codeChunks.push(newDelta);
+ }
+};
+
+var JellyBF_CloseAndAttemptUnrollLoop = function(codeChunks, options) {
+ if (codeChunks.length > 0 && codeChunks[codeChunks.length - 1] === "[") {
+ if (options.infiniteloops) {
+ codeChunks.push("]");
+ } else {
+ codeChunks.pop();
+ }
+ } else if (codeChunks.length > 1 && codeChunks[codeChunks.length - 1] instanceof JellyBFRangeDelta && codeChunks[codeChunks.length - 2] === "[") {
+ var chunk = codeChunks.pop();
+ if (chunk.wrapWithLoop(options)) {
+ codeChunks.pop();
+ JellyBF_InsertAndAttemptCoalesceDeltas(codeChunks, chunk);
+ } else {
+ codeChunks.push(chunk);
+ codeChunks.push("]");
+ }
+ } else {
+ codeChunks.push("]");
+ }
+};
+
+var JellyBFSync = {
+ compile: function(str, options) {
+ return WebAssembly.Module(JellyBFCompiler.compile(str, options));
+ },
+ execute: function(module, inputuint8array, options) {
+ options.eof_value = options.eof_value || 0;
+ var inputindex = 0;
+ var outputdata = new ResizableUint8Array();
+ var get_input = function() {
+ if (inputindex < inputuint8array.length) {
+ return inputuint8array[inputindex++];
+ } else {
+ return options.eof_value;
+ }
+ };
+ var put_output = function(byte) {
+ outputdata.push(byte);
+ };
+ var instance = WebAssembly.Instance(module, {
+ interaction: {
+ input: get_input,
+ output: put_output
+ }
+ });
+ instance.exports.main();
+ return outputdata.toUint8Array();
+ },
+ executeInteractive: function(module, inputuint8array, outputuint8array, inputwaitint32array, outputwaitint32array, options) {
+ var WaitArrayId = {
+ READ_HEAD: 0,
+ WRITE_HEAD: 1,
+ TERMINATED_FLAG: 2
+ };
+ options.bufferlength = options.bufferlength || 1024;
+ options.eof_value = options.eof_value || 0;
+ var input_read_head = 0, input_write_head = 0, input_terminated = false;
+ var get_input = function() {
+ if (input_read_head === input_write_head) {
+ Atomics.wait(inputwaitint32array, WaitArrayId.WRITE_HEAD, input_write_head);
+ input_write_head = Atomics.load(inputwaitint32array, WaitArrayId.WRITE_HEAD);
+ if (!input_terminated) {
+ input_terminated = Atomics.load(inputwaitint32array, WaitArrayId.TERMINATED_FLAG) !== 0;
+ }
+ }
+ if (!input_terminated || input_read_head + 1 < input_write_head) {
+ var val = Atomics.load(inputuint8array, input_read_head++ % options.bufferlength);
+ Atomics.store(inputwaitint32array, WaitArrayId.READ_HEAD, input_read_head);
+ return val;
+ } else {
+ return options.eof_value;
+ }
+ };
+ var output_read_head = 0, output_write_head = 0, output_terminated = false;
+ var put_output = function(byte) {
+ if (output_read_head + options.bufferlength === output_write_head) {
+ Atomics.wait(outputwaitint32array, WaitArrayId.READ_HEAD, output_read_head);
+ output_read_head = Atomics.load(outputwaitint32array, WaitArrayId.READ_HEAD);
+ }
+ Atomics.store(outputuint8array, output_write_head++ % options.bufferlength, byte);
+ Atomics.store(outputwaitint32array, WaitArrayId.WRITE_HEAD, output_write_head);
+ };
+ var terminate_output = function() {
+ if (output_read_head + options.bufferlength === output_write_head) {
+ Atomics.wait(outputwaitint32array, WaitArrayId.READ_HEAD, output_read_head);
+ output_read_head = Atomics.load(outputwaitint32array, WaitArrayId.READ_HEAD);
+ }
+ Atomics.store(outputwaitint32array, WaitArrayId.TERMINATED_FLAG, 1);
+ Atomics.store(outputwaitint32array, WaitArrayId.WRITE_HEAD, output_write_head + 1);
+ };
+ var instance = WebAssembly.Instance(module, {
+ interaction: {
+ input: get_input,
+ output: put_output
+ }
+ });
+ instance.exports.main();
+ terminate_output();
+ return true;
+ }
+};
+
+(function() {
+ var module = undefined;
+ self.addEventListener("message", function(e) {
+ var message = e.data;
+ switch (message.type) {
+ case "compile":
+ var sourcecode = message.sourcecode;
+ var options = message.options;
+ module = JellyBFSync.compile(sourcecode, options);
+ self.postMessage({
+ type: "compiled"
+ });
+ break;
+
+ case "execute-interactive":
+ var inputbuffer = message.inputbuffer;
+ var outputbuffer = message.outputbuffer;
+ 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"
+ });
+ 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 ]);
+ break;
+ }
+ });
+ self.postMessage({
+ type: "ready"
+ });
+})();
\ No newline at end of file
diff --git a/jelly-bf-worker.min.js b/jelly-bf-worker.min.js
new file mode 100644
index 0000000..9d9fe5c
--- /dev/null
+++ b/jelly-bf-worker.min.js
@@ -0,0 +1 @@
+var t=function(){this._buffer=new ArrayBuffer(8),this._data=new Uint8Array(this._buffer),this._size=0};t.prototype.size=function(){return this._size},t.prototype.get=function(t){return this._data[t]},t.prototype.set=function(t,n){this._data[t]=n},t.prototype.reserve_extra=function(t){if(this._size+t>this._data.length){for(var n=new ArrayBuffer(Math.max(2*this._data.length,this._size+t)),e=new Uint8Array(n),i=0;this._size>i;++i)e[i]=this._data[i];this._buffer=n,this._data=e}},t.prototype.push=function(t){this.reserve_extra(1),this._data[this._size++]=t},t.prototype.append=function(t){this.reserve_extra(t.length);for(var n=0;t.length>n;++n)this._data[this._size++]=t[n]},t.prototype.pop=function(){return this._data[--this._size]},t.prototype.insert_arr=function(t,n){this.reserve_extra(n.length);for(var e=this._size-1;e>=t;--e)this._data[e+n.length]=this._data[e];for(var e=0;n.length>e;++e)this._data[t+e]=n[e];this._size+=n.length},t.prototype.toUint8Array=function(){for(var t=new Uint8Array(this._size),n=0;this._size>n;++n)t[n]=this._data[n];return t};var n=function(t){return(new TextEncoder).encode(t)},e={};e.encodeUInt=function(n){0>n||n!==Math.floor(n);for(var e=new t;;){var i=n%128;if(n=Math.floor(n/128),0>=n){e.push(i);break}e.push(128+i)}return e.toUint8Array()},e.encodeInt=function(n){n!==Math.floor(n);var e=new t,i=0>n;for(i&&(n=-n-1);;){var r=n%128;if(n=Math.floor(n/128),0>=n&&64>r){e.push(i?127&~r:r);break}e.push(i?255&~r:128+r)}return e.toUint8Array()};var i={i32:127,i64:126,f32:125,f64:124,anyfunc:112,func:96,none:64},r={function:0,table:1,memory:2,global:3},o=function(t,n){this._param_types=t?t:[],this._result_types=n?n:[]};o.prototype.toUint8Array=function(){var n=new t;n.push(i.func),n.append(e.encodeUInt(this._param_types.length));for(var r=0;this._param_types.length>r;++r)n.push(this._param_types[r]);n.append(e.encodeUInt(this._result_types.length));for(var r=0;this._result_types.length>r;++r)n.push(this._result_types[r]);return n.toUint8Array()};var s=function(t){this._type=t};s.prototype.toUint8Array=function(){var n=new t;return n.append(e.encodeUInt(this._type)),n.toUint8Array()};var a=function(n){this._localTypes=n?n:[],this._data=new t,this._functionlinks=[]};a.prototype.setName=function(t){this._functionname=t},a.prototype.setType=function(t){this._functiontype=t},a.prototype.setLocalTypes=function(t){this._localTypes=t?t:[]},a.instruction={unreachable:0,nop:1,block:2,loop:3,if:4,else:5,end:11,br:12,br_if:13,br_table:14,return:15,call:16,call_indirect:17,drop:26,select:27,get_local:32,set_local:33,tee_local:34,get_global:35,set_global:36,i32_load:40,i64_load:41,f32_load:42,f64_load:43,i32_load8_s:44,i32_load8_u:45,i32_load16_s:46,i32_load16_u:47,i64_load8_s:48,i64_load8_u:49,i64_load16_s:50,i64_load16_u:51,i64_load32_s:52,i64_load32_u:53,i32_store:54,i64_store:55,f32_store:56,f64_store:57,i32_store8:58,i32_store16:59,i64_store8:60,i64_store16:61,i64_store32:62,current_memory:63,grow_memory:64,i32_const:65,i64_const:66,f32_const:67,f64_const:68,i32_eqz:69,i32_eq:70,i32_ne:71,i32_add:106,i32_sub:107,i32_mul:108},a.prototype.writeRawBytes=function(){for(var t=0;arguments.length>t;++t)this._data.push(arguments[t])},a.prototype.writeUint8Array=function(t){this._data.append(t)},a.prototype.unreachable=function(){this.writeRawBytes(a.instruction.unreachable)},a.prototype.nop=function(){this.writeRawBytes(a.instruction.nop)},a.prototype.block=function(t){this.writeRawBytes(a.instruction.block,t)},a.prototype.loop=function(t){this.writeRawBytes(a.instruction.loop,t)},a.prototype.if=function(t){this.writeRawBytes(a.instruction.if,t)},a.prototype.else=function(){this.writeRawBytes(a.instruction.else)},a.prototype.end=function(){this.writeRawBytes(a.instruction.end)},a.prototype.br=function(t){this.writeRawBytes(a.instruction.br),this.writeUint8Array(e.encodeUInt(t))},a.prototype.br_if=function(t){this.writeRawBytes(a.instruction.br_if),this.writeUint8Array(e.encodeUInt(t))},a.prototype.return=function(){this.writeRawBytes(a.instruction.return)},a.prototype.call=function(t){"number"==typeof t?(this.writeRawBytes(a.instruction.call),this.writeUint8Array(e.encodeUInt(t))):(this.writeRawBytes(a.instruction.call),this._functionlinks.push({location:this._data.size(),name:t}))},a.prototype.drop=function(){this.writeRawBytes(a.instruction.drop)},a.prototype.select=function(){this.writeRawBytes(a.instruction.select)},a.prototype.get_local=function(t){this.writeRawBytes(a.instruction.get_local),this.writeUint8Array(e.encodeUInt(t))},a.prototype.set_local=function(t){this.writeRawBytes(a.instruction.set_local),this.writeUint8Array(e.encodeUInt(t))},a.prototype.tee_local=function(t){this.writeRawBytes(a.instruction.tee_local),this.writeUint8Array(e.encodeUInt(t))},a.prototype.i32_load=function(t,n){n=n||0,this.writeRawBytes(a.instruction.i32_load),this.writeUint8Array(e.encodeUInt(n)),this.writeUint8Array(e.encodeUInt(t))},a.prototype.i64_load=function(t,n){n=n||0,this.writeRawBytes(a.instruction.i64_load),this.writeUint8Array(e.encodeUInt(n)),this.writeUint8Array(e.encodeUInt(t))},a.prototype.f32_load=function(t,n){n=n||0,this.writeRawBytes(a.instruction.f32_load),this.writeUint8Array(e.encodeUInt(n)),this.writeUint8Array(e.encodeUInt(t))},a.prototype.f64_load=function(t,n){n=n||0,this.writeRawBytes(a.instruction.f64_load),this.writeUint8Array(e.encodeUInt(n)),this.writeUint8Array(e.encodeUInt(t))},a.prototype.i32_load8_s=function(t,n){n=n||0,this.writeRawBytes(a.instruction.i32_load8_s),this.writeUint8Array(e.encodeUInt(n)),this.writeUint8Array(e.encodeUInt(t))},a.prototype.i32_load8_u=function(t,n){n=n||0,this.writeRawBytes(a.instruction.i32_load8_u),this.writeUint8Array(e.encodeUInt(n)),this.writeUint8Array(e.encodeUInt(t))},a.prototype.i32_load16_s=function(t,n){n=n||0,this.writeRawBytes(a.instruction.i32_load16_s),this.writeUint8Array(e.encodeUInt(n)),this.writeUint8Array(e.encodeUInt(t))},a.prototype.i32_load16_u=function(t,n){n=n||0,this.writeRawBytes(a.instruction.i32_load16_u),this.writeUint8Array(e.encodeUInt(n)),this.writeUint8Array(e.encodeUInt(t))},a.prototype.i64_load8_s=function(t,n){n=n||0,this.writeRawBytes(a.instruction.i64_load8_s),this.writeUint8Array(e.encodeUInt(n)),this.writeUint8Array(e.encodeUInt(t))},a.prototype.i64_load8_u=function(t,n){n=n||0,this.writeRawBytes(a.instruction.i64_load8_u),this.writeUint8Array(e.encodeUInt(n)),this.writeUint8Array(e.encodeUInt(t))},a.prototype.i64_load16_s=function(t,n){n=n||0,this.writeRawBytes(a.instruction.i64_load16_s),this.writeUint8Array(e.encodeUInt(n)),this.writeUint8Array(e.encodeUInt(t))},a.prototype.i64_load16_u=function(t,n){n=n||0,this.writeRawBytes(a.instruction.i64_load16_u),this.writeUint8Array(e.encodeUInt(n)),this.writeUint8Array(e.encodeUInt(t))},a.prototype.i64_load32_s=function(t,n){n=n||0,this.writeRawBytes(a.instruction.i64_load32_s),this.writeUint8Array(e.encodeUInt(n)),this.writeUint8Array(e.encodeUInt(t))},a.prototype.i64_load32_u=function(t,n){n=n||0,this.writeRawBytes(a.instruction.i64_load32_u),this.writeUint8Array(e.encodeUInt(n)),this.writeUint8Array(e.encodeUInt(t))},a.prototype.i32_store=function(t,n){n=n||0,this.writeRawBytes(a.instruction.i32_store),this.writeUint8Array(e.encodeUInt(n)),this.writeUint8Array(e.encodeUInt(t))},a.prototype.i64_store=function(t,n){n=n||0,this.writeRawBytes(a.instruction.i64_store),this.writeUint8Array(e.encodeUInt(n)),this.writeUint8Array(e.encodeUInt(t))},a.prototype.f32_store=function(t,n){n=n||0,this.writeRawBytes(a.instruction.f32_store),this.writeUint8Array(e.encodeUInt(n)),this.writeUint8Array(e.encodeUInt(t))},a.prototype.f64_store=function(t,n){n=n||0,this.writeRawBytes(a.instruction.f64_store),this.writeUint8Array(e.encodeUInt(n)),this.writeUint8Array(e.encodeUInt(t))},a.prototype.i32_store8=function(t,n){n=n||0,this.writeRawBytes(a.instruction.i32_store8),this.writeUint8Array(e.encodeUInt(n)),this.writeUint8Array(e.encodeUInt(t))},a.prototype.i32_store16=function(t,n){n=n||0,this.writeRawBytes(a.instruction.i32_store16),this.writeUint8Array(e.encodeUInt(n)),this.writeUint8Array(e.encodeUInt(t))},a.prototype.i64_store8=function(t,n){n=n||0,this.writeRawBytes(a.instruction.i64_store8),this.writeUint8Array(e.encodeUInt(n)),this.writeUint8Array(e.encodeUInt(t))},a.prototype.i64_store16=function(t,n){n=n||0,this.writeRawBytes(a.instruction.i64_store16),this.writeUint8Array(e.encodeUInt(n)),this.writeUint8Array(e.encodeUInt(t))},a.prototype.i64_store32=function(t,n){n=n||0,this.writeRawBytes(a.instruction.i64_store32),this.writeUint8Array(e.encodeUInt(n)),this.writeUint8Array(e.encodeUInt(t))},a.prototype.current_memory=function(){this.writeRawBytes(a.instruction.current_memory,0)},a.prototype.grow_memory=function(){this.writeRawBytes(a.instruction.grow_memory,0)},a.prototype.i32_const=function(t){this.writeRawBytes(a.instruction.i32_const),this.writeUint8Array(e.encodeInt(t))},a.prototype.i64_const=function(t){this.writeRawBytes(a.instruction.i64_const),this.writeUint8Array(e.encodeInt(t))},a.prototype.i32_eqz=function(){this.writeRawBytes(a.instruction.i32_eqz)},a.prototype.i32_eq=function(){this.writeRawBytes(a.instruction.i32_eq)},a.prototype.i32_ne=function(){this.writeRawBytes(a.instruction.i32_ne)},a.prototype.i32_add=function(){this.writeRawBytes(a.instruction.i32_add)},a.prototype.i32_sub=function(){this.writeRawBytes(a.instruction.i32_sub)},a.prototype.i32_mul=function(){this.writeRawBytes(a.instruction.i32_mul)},a.prototype.toUint8Array=function(){var n=new t;n.append(e.encodeUInt(this._localTypes.length));for(var i=0;this._localTypes.length>i;++i)n.push(1),n.push(this._localTypes[i]);return n.append(this._data.toUint8Array()),n.insert_arr(0,e.encodeUInt(n.size())),n.toUint8Array()};var c=function(t,n,e){this._field=t,this._kind=n,this._index=e};c.prototype.setName=function(t){this._functionname=t},c.prototype.toUint8Array=function(){var i=new t,r=n(this._field);return i.append(e.encodeUInt(r.length)),i.append(r),i.push(this._kind),i.append(e.encodeUInt(this._index)),i.toUint8Array()};var u=function(t,n,e){this._module=t,this._field=n,this._kind=e};u.prototype.setName=function(t){this._functionname=t},u.prototype.setType=function(t){this._functiontype=t},u.prototype.toUint8Array=function(){var i=new t,r=n(this._module),o=n(this._field);return i.push(e.encodeUInt(r.length)),i.append(r),i.push(e.encodeUInt(o.length)),i.append(o),i.push(this._kind),i.append(e.encodeUInt(this._type)),i.toUint8Array()};var _=function(t,n){this._initial_pages=t,n&&(this._maximum_pages=n)};_.prototype.toUint8Array=function(){var n=new t;return this._maximum_pages?(n.push(1),n.append(e.encodeUInt(this._initial_pages)),n.append(e.encodeUInt(this._maximum_pages))):(n.push(0),n.append(e.encodeUInt(this._initial_pages))),n.toUint8Array()};var h=function(){this._types=[],this._imports=[],this._functions=[],this._memory=[],this._exports=[],this._codes=[]};h.sectionCode={TYPE:1,IMPORT:2,FUNCTION:3,TABLE:4,MEMORY:5,GLOBAL:6,EXPORT:7,START:8,ELEMENT:9,CODE:10,DATA:11},h.prototype.setMemory=function(t){this._memory=[t]},h.prototype.exportFunction=function(t,n){n=n||t;var e=new c(n,r.function);e.setName(t),this._exports.push(e)},h.prototype.importFunction=function(t,n,e,i){var o=new u(e,i,r.function);o.setName(t),o.setType(n),this._imports.push(o)},h.prototype.addFunction=function(t,n,e){e.setName(t),e.setType(n),this._codes.push(e)},h.prototype.generateModule=function(){var n=[],i=this._types.length,r=function(t){return function(n){if(n.length!=t.length)return!1;for(var e=0;n.length>e;++e)if(n[e]!=t[e])return!1;return!0}},o=[],a=this._functions.length;this._imports.forEach(function(t){var n=t._functionname;if(n){if(o.findIndex(function(t){return t.name===n})!==-1)throw'Repeated function "'+n+'".';o.push({name:n,funcType:t._functiontype})}}),this._codes.forEach(function(t){var n=t._functionname;if(n){if(o.findIndex(function(t){return t.name===n})!==-1)throw'Repeated function "'+n+'".';o.push({name:n,funcType:t._functiontype})}}),o.forEach(function(t){n.findIndex(r(t.funcType))===-1&&n.push(t.funcType)});var c=this;n.forEach(function(t){c._types.push(t)});var c=this;this._codes.forEach(function(t){if(t._functiontype){var e=n.findIndex(r(t._functiontype))+i;if(e===-1)throw"Weird assembler bug.";c._functions.push(new s(e))}}),this._imports.forEach(function(t){var e=t._functiontype;if(e){var o=n.findIndex(r(e))+i;if(o===-1)throw"Weird assembler bug.";t._type=o}}),this._codes.forEach(function(t){var n=t._functionlinks;n.sort(function(t,n){return n.location-t.location}),n.forEach(function(n){var i=o.findIndex(function(t){return t.name===n.name})+a;if(i===-1)throw'Undeclared function "'+n.name+'".';t._data.insert_arr(n.location,e.encodeUInt(i))})}),this._exports.forEach(function(t){var n=t._functionname;if(n){var e=o.findIndex(function(t){return t.name===n})+a;if(e===-1)throw'Undeclared function "'+functionLink.name+'".';t._index=e}}),this._exports.forEach(function(t){t._functionname&&(t._functionname=void 0)}),this._imports.forEach(function(t){t._functionname&&(t._functionname=void 0,t._functiontype=void 0)}),this._codes.forEach(function(t){t._functionname&&(t._functionname=void 0,t._functiontype=void 0)});var u=new t,_=new Uint8Array(8);if(_[0]=0,_[1]=97,_[2]=115,_[3]=109,_[4]=1,_[5]=0,_[6]=0,_[7]=0,u.append(_),this._types.length>0){u.push(h.sectionCode.TYPE);var p=u.size();u.append(e.encodeUInt(this._types.length));for(var f=0;this._types.length>f;++f)u.append(this._types[f]);u.insert_arr(p,e.encodeUInt(u.size()-p))}if(this._imports.length>0){u.push(h.sectionCode.IMPORT);var p=u.size();u.append(e.encodeUInt(this._imports.length));for(var f=0;this._imports.length>f;++f)u.append(this._imports[f].toUint8Array());u.insert_arr(p,e.encodeUInt(u.size()-p))}if(this._functions.length>0){u.push(h.sectionCode.FUNCTION);var p=u.size();u.append(e.encodeUInt(this._functions.length));for(var f=0;this._functions.length>f;++f)u.append(this._functions[f].toUint8Array());u.insert_arr(p,e.encodeUInt(u.size()-p))}if(this._memory.length>0){u.push(h.sectionCode.MEMORY);var p=u.size();u.append(e.encodeUInt(this._memory.length));for(var f=0;this._memory.length>f;++f)u.append(this._memory[f].toUint8Array());u.insert_arr(p,e.encodeUInt(u.size()-p))}if(this._exports.length>0){u.push(h.sectionCode.EXPORT);var p=u.size();u.append(e.encodeUInt(this._exports.length));for(var f=0;this._exports.length>f;++f)u.append(this._exports[f].toUint8Array());u.insert_arr(p,e.encodeUInt(u.size()-p))}if(this._codes.length>0){u.push(h.sectionCode.CODE);var p=u.size();u.append(e.encodeUInt(this._codes.length));for(var f=0;this._codes.length>f;++f)u.append(this._codes[f].toUint8Array());u.insert_arr(p,e.encodeUInt(u.size()-p))}return u.toUint8Array()};var p={};p.compile=function(t,n){if(void 0===n.wraparound&&(n.wraparound=!0),void 0===n.infiniteloops&&(n.infiniteloops=!0),void 0===n.bitwidth&&(n.bitwidth=8),8===n.bitwidth||16===n.bitwidth||32===n.bitwidth){for(var e=[],i=0;t.length>i;++i)switch(t[i]){case"+":var r=new g;r.addDelta(0,1),R(e,r);break;case"-":var r=new g;r.addDelta(0,-1),R(e,r);break;case">":var r=new g;r.addExitDelta(1),R(e,r);break;case"<":var r=new g;r.addExitDelta(-1),R(e,r);break;case"[":e.push("[");break;case"]":T(e,n);break;case",":e.push(",");break;case".":e.push(".")}for(var i=(new b(!0),0);e.length>i;++i);return f(e)}};var f=function(t){var n=new h;n.setMemory(new _(16,16));var e=new a([i.i32]);e.i32_const(524288),e.set_local(0);for(var r=1,s=0;t.length>s;++s)if(t[s]instanceof g){var c=t[s];if(c._data.length>0){var u=1,p=[];c._data.forEach(function(t){t._combination.isZero(),t._combination._terms.forEach(function(t){t._parts.forEach(function(t){if(t instanceof w){var n=p.findIndex(function(n){return n>=t._index});n===-1?p.push(t._index):p[n]!==t._index&&p.splice(n,0,t._index)}})})});var f=Math.min(c._data[0]._index,c._exitindex);p.length>0&&(f=Math.min(f,p[0])),0!==f&&(e.get_local(0),e.i32_const(f),e.i32_add(),e.set_local(0)),p.forEach(function(t,n){var i=u+n,r=t-f;e.get_local(0),e.i32_load8_u(r),e.set_local(i)}),c._data.forEach(function(t){t._combination.isZero();var n=t._index-f;e.get_local(0),e.get_local(0),e.i32_load8_u(n),t._combination._terms.forEach(function(t){if(1===t._parts.length&&1===t._coefficient){var n=t._parts[0];n instanceof w&&e.get_local(u+p.findIndex(function(t){return t>=n._index}))}else e.i32_const(t._coefficient),t._parts.forEach(function(t){t instanceof w&&(e.get_local(u+p.findIndex(function(n){return n>=t._index})),e.i32_mul())});e.i32_add()}),e.i32_store8(n)}),c._exitindex-f!==0&&(e.get_local(0),e.i32_const(c._exitindex-f),e.i32_add(),e.set_local(0)),r=Math.max(r,u+p.length)}else 0!==c._exitindex&&(e.get_local(0),e.i32_const(t[s]._exitindex),e.i32_add(),e.set_local(0))}else switch(t[s]){case"[":e.get_local(0),e.i32_load8_u(0),e.if(i.none),e.loop(i.none);break;case"]":e.get_local(0),e.i32_load8_u(0),e.br_if(0),e.end(),e.end();break;case",":e.get_local(0),e.call("input"),e.i32_store8(0);break;case".":e.get_local(0),e.i32_load8_u(0),e.call("output")}e.end();for(var d=[],s=0;r>s;++s)d.push(i.i32);return e.setLocalTypes(d),n.addFunction("main",new o([],[]).toUint8Array(),e),n.exportFunction("main","main"),n.importFunction("input",new o([],[i.i32]).toUint8Array(),"interaction","input"),n.importFunction("output",new o([i.i32],[]).toUint8Array(),"interaction","output"),n.generateModule()},d=function(t,n){this._index=t,this._delta=n},l=function(){this._data=[],this._exitindex=0};l.prototype.applyDelta=function(t,n){var e=this._data.findIndex(function(n){return n._index>=t});e===-1?0!==n&&this._data.push(new d(t,n)):this._data[e]._index===t?(this._data[e]._delta+=n,0===this._data[e]._delta&&this._data.splice(e,1)):0!==n&&this._data.splice(e,0,new d(t,n))},l.prototype.applyExitDelta=function(t){this._exitindex+=t},l.prototype.coalesceWith=function(t){var n=this;t._data.forEach(function(t){n.applyDelta(n._exitindex+t._index,t._delta)}),this._exitindex+=t._exitindex};var y=function(t,n){if(n>t){var e=t;t=n,n=e}return 0===n?t:y(n,t%n)},m=function(t,n){this._sgn=0>t,this._num=Math.abs(t),this._den=n};m.prototype.reduce=function(){var t=y(this._num,this._den);this._num/=t,this._den/=t},m.prototype.multiplyWith=function(t){t instanceof m?(this._sgn=this._sgn!==t._sgn,this._num*=t._num,this._den*=t._den,this.reduce()):(this._sgn=this.sgn!==0>t,this.num*=Math.abs(t),this.reduce())};var w=function(t){this._index=t};w.sortOrder=1,w.Comparer=function(t,n){return t._index-n._index},w.prototype.addShift=function(t){this._index+=t},w.prototype.clone=function(){return new w(this._index)};var U=function(t){this._index=t};U.sortOrder=2,U.Comparer=function(t,n){return t._index-n._index},U.prototype.addShift=function(t,n){this._index+=n},U.prototype.clone=function(){return new U(this._index)};var v={};v.Comparer=function(t,n){var e=t.constructor,i=n.constructor;return e!==i?e.sortOrder-i.sortOrder:e.Comparer(t,n)},v.FinderLow=function(t){return function(n){return v.Comparer(n,t)>=0}};var I=function(t){this._parts=[],this._coefficient=t};I.makeConstant=function(t){var n=new I;return n._coefficient=t,n},I.makeFromPart=function(t){var n=new I(1);return n._parts=[t],n},I.Comparer=function(t,n){for(var e=Math.max(t._parts.length,n._parts.length),i=0;e>i;++i){if(i>=t._parts.length)return-1;if(i>=n._parts.length)return 1;var r=v.Comparer(t._parts[i],n._parts[i]);if(0!==r)return r}return 0},I.FinderLow=function(t){return function(n){return I.Comparer(n,t)>=0}},I.IsEqual=function(t,n){if(t._parts.length!==n._parts.length)return!1;for(var e=t._parts.length,i=0;e>i;++i)if(0!==v.Comparer(t._parts[i],n._parts[i]))return!1;return!0},I.prototype.addWith=function(t){this._coefficient+=t._coefficient},I.prototype.multiplyWith=function(t){t.isZero();var n=this._parts;t._parts.forEach(function(t){var e=n.findIndex(v.FinderLow(t));e===-1?n.push(t):n.splice(e,0,t)}),this._coefficient*=t._coefficient},I.prototype.isZero=function(){return 0===this._coefficient},I.prototype.clone=function(){var t=new I(this._coefficient);return this._parts.forEach(function(n){t._parts.push(n.clone())}),t};var x=function(){this._terms=[]};x.prototype.addTerm=function(t){t.isZero();var n=this._terms.findIndex(I.FinderLow(t));n===-1?this._terms.push(t):I.IsEqual(this._terms[n],t)?(this._terms[n].addWith(t),this._terms[n].isZero()&&this._terms.splice(n,1)):this._terms.splice(n,0,t)},x.prototype.multiplyTerm=function(t){t.isZero(),this._terms.forEach(function(n){n.multiplyWith(t.clone())})},x.prototype.multiplyLinear=function(t){var n=this._terms,e=[];t._terms.forEach(function(t){n.forEach(function(n){var i=n.clone();i.multiplyWith(t.clone()),e.push(i)})}),e.sort(I.Comparer),this._terms=e},x.prototype.isZero=function(){return 0===this._terms.length},x.prototype.clone=function(){var t=new x;return this._terms.forEach(function(n){t._terms.push(n.clone())}),t},x.prototype.coalesceWith=function(t){var n=this;t._terms.forEach(function(t){n.addTerm(t)})},x.prototype.expandState=function(t){var n=[];this._terms.forEach(function(e){var i=[],r=new I(e._coefficient);e._parts.forEach(function(t){t instanceof w?i.push(t._index):t instanceof JellyBFLinearOutputRef&&r.push(t)});var o=new x;o.addTerm(I.makeConstant(1)),i.forEach(function(n){var e=t._data.findIndex(A.FinderEqualIndex(n)),i=new x;i.addTerm(I.makeFromPart(new w(n))),e!==-1&&i.coalesceWith(t._data[e]._combination.clone()),o.multiplyLinear(i)}),o.multiplyTerm(r),o._terms.forEach(function(t){n.push(t)})}),this._terms=[];var e=this;n.forEach(function(t){e.addTerm(t)})},x.IsExactSame=function(t,n){if(t._terms.length!==n._terms.length)return!1;for(var e=t._terms.length,i=0;e>i;++i){if(!I.IsEqual(t._terms[i],n._terms[i]))return!1;if(t._terms[i]._coefficient!==n._terms[i]._coefficient)return!1}return!0};var A=function(t){this._index=t,this._combination=new x};A.Comparer=function(t,n){return t._index-n._index},A.FinderLow=function(t){return function(n){return n._index>=t._index}},A.FinderLowIndex=function(t){return function(n){return n._index>=t}},A.FinderEqual=function(t){return function(n){return n._index===t._index}},A.FinderEqualIndex=function(t){return function(n){return n._index===t}},A.IsEqual=function(t,n){return t._index===n._index},A.IsEqualIndex=function(t,n){return t._index===n},A.prototype.addTerm=function(t){this._combination.addTerm(t)},A.prototype.multiplyTerm=function(t){this._combination.multiplyTerm(t)},A.prototype.isZero=function(){return this._combination.isZero()},A.prototype.coalesceWith=function(t){this._combination.coalesceWith(t._combination)},A.makeFromTerm=function(t,n){var e=new A(t);return e.addTerm(n),e};var g=function(){this._data=[],this._outputs=[],this._exitindex=0,this._inputcount=0};g.prototype.addEntry=function(t){var n=this._data.findIndex(A.FinderLow(t));n===-1?this._data.push(t):A.IsEqual(this._data[n],t)?(this._data[n].coalesceWith(t),this._data[n].isZero()&&this._data.splice(n,1)):this._data.splice(n,0,t)},g.prototype.addDelta=function(t,n){var e=this._data.findIndex(A.FinderLowIndex(t));e===-1?0!==n&&this._data.push(A.makeFromTerm(t,I.makeConstant(n))):A.IsEqualIndex(this._data[e],t)?(this._data[e].addTerm(I.makeConstant(n)),this._data[e].isZero()&&this._data.splice(e,1)):0!==n&&this._data.splice(e,0,A.makeFromTerm(t,I.makeConstant(n)))},g.prototype.addExitDelta=function(t){this._exitindex+=t},g.prototype.coalesceWith=function(t){var n=this,e=this._exitindex,i=this._inputcount;t._data.forEach(function(t){t._index+=e,t._combination._terms.forEach(function(t){t._parts.forEach(function(t){t.addShift(e,i)})})}),t._outputs.forEach(function(t){t._terms.forEach(function(t){t._parts.forEach(function(t){t.addShift(e,i)})})});var r=[];t._data.forEach(function(t){t._combination.expandState(n),r.push(t)}),t._outputs.forEach(function(t){t.expandState(n),n._outputs.push(t)}),r.forEach(function(t){n.addEntry(t)});for(var o=this._data.length-1;o>=0;--o)this._data[o].isZero()&&this._data.splice(o,1);this._exitindex+=t._exitindex,this._inputcount+=t._inputcount},g.prototype.wrapWithLoop=function(){if(0===this._exitindex){var t=this._data.findIndex(A.FinderEqualIndex(0));if(t===-1)return!1;if(x.IsExactSame(this._data[t]._combination,A.makeFromTerm(0,I.makeConstant(-1))._combination)){var n=!0;return this._data.forEach(function(t){t._combination._terms.forEach(function(t){0!==t._parts.length&&(n=!1)})}),!!n&&(this._data.forEach(function(t){var n=new I(1);n._parts.push(new w(0)),t.multiplyTerm(n)}),!0)}return!1}return!1},g.prototype.writeCode=function(){};var E=function(t,n){this._index=t,this._value=n};E.FinderLowIndex=function(t){return function(n){return n._index>=t}};var b=function(t){this.emptyIsZero=t,this._data=[]};b.prototype.getState=function(t){var n=this._data.findIndex(E.FinderLowIndex(t));return n===-1?this.emptyIsZero?0:void 0:this._data[n]._value},b.prototype.setState=function(t,n){var e=this._data.findIndex(E.FinderLowIndex(t));e===-1?(this.emptyIsZero&&0!==n||!this.emptyIsZero&&void 0!==n)&&this._data.splice(e,0,new E(t,n)):this.emptyIsZero&&0===n||!this.emptyIsZero&&void 0===n?this._data.splice(e,1):this._data[e]._value=n};var R=function(t,n){t.length>0&&t[t.length-1]instanceof g?t[t.length-1].coalesceWith(n):t.push(n)},T=function(t,n){if(t.length>0&&"["===t[t.length-1])n.infiniteloops?t.push("]"):t.pop();else if(t.length>1&&t[t.length-1]instanceof g&&"["===t[t.length-2]){var e=t.pop();e.wrapWithLoop(n)?(t.pop(),R(t,e)):(t.push(e),t.push("]"))}else t.push("]")},B={compile:function(t,n){return WebAssembly.Module(p.compile(t,n))},execute:function(n,e,i){i.eof_value=i.eof_value||0;var r=0,o=new t,s=function(){return e.length>r?e[r++]:i.eof_value},a=function(t){o.push(t)};return WebAssembly.instantiate(n,{interaction:{input:s,output:a}}).exports.main(),o.toUint8Array()},executeInteractive:function(t,n,e,i,r,o){var s={READ_HEAD:0,WRITE_HEAD:1,TERMINATED_FLAG:2};o.bufferlength=o.bufferlength||1024,o.eof_value=o.eof_value||0;var a=0,c=0,u=!1,_=function(){if(a===c&&(Atomics.wait(i,s.WRITE_HEAD,c),c=Atomics.load(i,s.WRITE_HEAD),u||(u=0!==Atomics.load(i,s.TERMINATED_FLAG))),!u||c>a+1){var t=Atomics.load(n,a++%o.bufferlength);return Atomics.store(i,s.READ_HEAD,a),t}return o.eof_value},h=0,p=0,f=function(t){h+o.bufferlength===p&&(Atomics.wait(r,s.READ_HEAD,h),h=Atomics.load(r,s.READ_HEAD)),Atomics.store(e,p++%o.bufferlength,t),Atomics.store(r,s.WRITE_HEAD,p)},d=function(){h+o.bufferlength===p&&(Atomics.wait(r,s.READ_HEAD,h),h=Atomics.load(r,s.READ_HEAD)),Atomics.store(r,s.TERMINATED_FLAG,1),Atomics.store(r,s.WRITE_HEAD,p+1)};return WebAssembly.instantiate(t,{interaction:{input:_,output:f}}).exports.main(),d(),!0}};!function(){self.addEventListener("message",function(t){var n=t.data;switch(n.type){case"compile":var e=n.sourcecode,i=n.options,r=B.compile(e,i);self.postMessage({type:"compiled",module:r},[r]);break;case"execute-interactive":var r=n.module,o=n.inputbuffer,s=n.outputbuffer,a=n.inputwaitbuffer,c=n.outputwaitbuffer,i=n.options;B.executeInteractive(r,UInt8Array(o),UInt8Array(s),Int32Array(a),Int32Array(c),i),self.postMessage({type:"executed"});break;case"execute":var r=n.module,u=n.inputuint8array,i=n.options,_=B.execute(r,u,i);self.postMessage({type:"executed",outputuint8array:_},[_])}}),self.postMessage({type:"ready"})}();
\ No newline at end of file
diff --git a/join-worker.bat b/join-worker.bat
new file mode 100644
index 0000000..4c644fe
--- /dev/null
+++ b/join-worker.bat
@@ -0,0 +1 @@
+call uglifyjs wasm32codegen.max.js jelly-bf-compiler.js jelly-bf-sync.js jelly-bf-worker.js --beautify --output jelly-bf-worker.max.js
\ No newline at end of file
diff --git a/main-old.js b/main-old.js
new file mode 100644
index 0000000..f839a00
--- /dev/null
+++ b/main-old.js
@@ -0,0 +1,30 @@
+window.addEventListener("load",function(){
+ if(!window.WebAssembly){
+ alert("This browser does not support WebAssembly. Chrome 57+, Firefox 52+ and Opera 44+ are great browsers that do support WebAssembly, and they're free!");
+ return;
+ }
+ 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;
+ outputTextbox.value="";
+ var startTime=Date.now();
+ JellyBF.compileOptimized(codestr,{infiniteloops:false},function(compiledModule){
+ var compiledTime=Date.now();
+ console.log("Compiled in "+Math.round(compiledTime-startTime)+" ms.");
+ compiledTime=Date.now();
+ JellyBF.execute(compiledModule,instr,function(outstr){
+ var executedTime=Date.now();
+ console.log("Executed in "+Math.round(executedTime-compiledTime)+" ms.");
+ outputTextbox.value=outstr;
+ });
+ });
+ });
+ clearOutputButton.addEventListener("click",function(){
+ outputTextbox.value="";
+ });
+});
\ No newline at end of file
diff --git a/main.js b/main.js
index f839a00..e11b850 100644
--- a/main.js
+++ b/main.js
@@ -8,12 +8,50 @@ window.addEventListener("load",function(){
var outputTextbox=document.getElementById("outputtextbox");
var codeButton=document.getElementById("codebutton");
var clearOutputButton=document.getElementById("clearoutputbutton");
+
+
+ var wait_for_message=function(worker,type,callback){
+ var message_handler=function(e){
+ switch(e.data.type){
+ case type:
+ worker.removeEventListener("message",message_handler);
+ callback(e.data);
+ break;
+ }
+ };
+ worker.addEventListener("message",message_handler);
+ };
+
+
+ var initworker=function(callback){
+ var worker=new Worker("jelly-bf-worker.max.js");
+ wait_for_message(worker,"ready",function(){
+ callback(worker);
+ });
+ };
+
+ var compile=function(worker,sourcecode,options,callback){
+ var module=new Uint8Array(100);
+ worker.postMessage({type:"compile",sourcecode:sourcecode,options:options,module:module},[module.buffer]);
+ wait_for_message(worker,"compiled",function(message){
+ callback();
+ });
+ };
+
+ var execute=function(worker,inputstr,options,callback){
+ var encodedinput=new TextEncoder().encode(inputstr);
+ worker.postMessage({type:"execute",inputuint8array:encodedinput,options:options},[encodedinput.buffer]);
+ wait_for_message(worker,"executed",function(message){
+ callback(new TextDecoder().decode(message.outputuint8array));
+ });
+ };
+
codeButton.addEventListener("click",function(){
var codestr=codeTextbox.value;
var instr=inputTextbox.value;
outputTextbox.value="";
- var startTime=Date.now();
- JellyBF.compileOptimized(codestr,{infiniteloops:false},function(compiledModule){
+
+ /*JellyBF.compileOptimized(codestr,{infiniteloops:false},function(compiledModule){
var compiledTime=Date.now();
console.log("Compiled in "+Math.round(compiledTime-startTime)+" ms.");
compiledTime=Date.now();
@@ -22,7 +60,20 @@ window.addEventListener("load",function(){
console.log("Executed in "+Math.round(executedTime-compiledTime)+" ms.");
outputTextbox.value=outstr;
});
+ });*/
+ initworker(function(worker){
+ var startTime=Date.now();
+ compile(worker, codestr,{},function(){
+ var compiledTime=Date.now();
+ console.log("Compiled in "+Math.round(compiledTime-startTime)+" ms.");
+ execute(worker,instr,{},function(outstr){
+ var executedTime=Date.now();
+ console.log("Executed in "+Math.round(executedTime-compiledTime)+" ms.");
+ outputTextbox.value=outstr;
+ });
+ });
});
+
});
clearOutputButton.addEventListener("click",function(){
outputTextbox.value="";
diff --git a/uglify-worker.bat b/uglify-worker.bat
new file mode 100644
index 0000000..e02a929
--- /dev/null
+++ b/uglify-worker.bat
@@ -0,0 +1 @@
+call uglifyjs wasm32codegen.max.js jelly-bf-compiler.js jelly-bf-sync.js jelly-bf-worker.js --mangle toplevel --compress sequences,unsafe,comparisons,unsafe_comps,pure_getters,collapse_vars,reduce_vars,keep_fargs=false,passes=5 --screw-ie8 --output jelly-bf-worker.min.js
\ No newline at end of file