Skip to content

Instantly share code, notes, and snippets.

@mouseroot
Created November 25, 2015 10:57
Show Gist options
  • Save mouseroot/a7fbd4943353856f42a6 to your computer and use it in GitHub Desktop.
Save mouseroot/a7fbd4943353856f42a6 to your computer and use it in GitHub Desktop.
//Very simple jump on 9 to next op
/*
var program = ["0","0","0","1337","9","4"];
var pc = 0;
for(var i=0;i < program.length;i++) {
switch(program[i])
{
case "0":
//Skip
break;
case "9":
i = parseInt(program[i + 1]);
i++;
break;
default:
//Skip
console.log("Default:",program[i]);
break;
}
pc = i;
}
*/
//Example
/*
var _program = [
"set","s","something",
".func","myFunc",
"set","s","something_else",
"ret",
".func","someOtherFunc",
"set","s","never_exec_me",
"ret",
".invoke","myFunc",
".invoke","someOtherFunc"
];
var program = [
"func","apples",
"set","a","Apples",
"ret",
"endfunc",
"func","bread",
"set","b","Bread",
"ret",
"endfunc",
"func","main",
"invoke","apples",
"invoke","bread",
"ret",
"endfunc",
"set","s","starting main...",
"invoke","main"
];
*/
function searchLabel(program,labelName) {
var loc = program.indexOf(":" + labelName,0);
if(loc > -1) {
return loc;
}
else {
return null;
}
}
function executeFunctionByName(str, args) {
var arr = str.split('.');
var fn = window[ arr[0] ];
for (var i = 1; i < arr.length; i++)
{
fn = fn[ arr[i] ];
}
fn.apply(window, args);
}
var slot_api = {
set: function(i, tables, program) {
var slot = program[i + 1].toUpperCase();
var value = program[i + 2];
if(slot in tables.registers) {
tables.registers[slot] = value;
}
i += 2;
},
sets: function(i, tables, program) {
var name_dst = program[i + 1].toUpperCase();
var name_src = program[i + 2].toUpperCase();
if(name_dst in tables.registers && name_src in tables.registers) {
var val = tables.registers[name_src];
tables.registers[name_dst] = val;
}
i += 2;
},
incs: function(i, tables, program) {
var name = program[i + 1].toUpperCase();
if(name in tables.registers) {
tables.registers[name] = parseInt(tables.registers[name]) + 1;
}
i += 1;
},
decs: function(i, tables, program) {
var name = program[i + 1].toUpperCase();
if(name in tables.registers) {
tables.registers[name] = parseInt(tables.registers[name]) - 1;
}
i += 1;
},
push: function(i, tables, stack, program) {
var value = program[i + 1];
stack.push(value);
i += 1;
},
pushs: function(i, tables, stack, program) {
var reg = program[i + 1].toUpperCase();
if(reg in tables.registers) {
var value = tables.registers[reg];
stack.push(value);
}
i += 1;
},
pops: function(i, tables, stack, program) {
var reg = program[i + 1].toUpperCase();
if(reg in tables.registers) {
tables.registers[reg] = stack.pop();
}
i += 1;
},
cmps: function(i, tables, program) {
var opA = program[i + 1].toUpperCase();
var opB = program[i + 2].toUpperCase();
if(opA in tables.registers && opB in tables.registers) {
var valA = tables.registers[opA];
var valB = tables.registers[opB];
if(valA == valB) {
tables.registers["F"] = 1;
}
else {
tables.registers["F"] = 0;
}
}
i += 2;
},
je: function(i, tables, program) {
var dest = program[i + 1];
if(tables.registers["F"] == 1) {
if(result = searchLabel(program,dest)) {
i = result;
}
}
else {
i += 1;
}
},
jne: function(i, tables, program) {
var dest = program[i + 1];
if(tables.registers["F"] == 0) {
if(result = searchLabel(program, dest)) {
i = result;
}
}
else {
i += 1;
}
},
loop: function(i, tables, stack, program) {
var count = parseInt(program[i + 1]);
if(program[i + 1].toUpperCase() in tables.registers) {
var reg = program[i + 1].toUpperCase();
count = parseInt(tables.registers[reg]);
//console.log("Count from register:",count);
}
else {
//console.log("Count from param");
}
stack.push(i + 1);
loop_max = count;
loop_counter = 0;
i += 1;
},
endloop: function(i, tables, stack, program) {
loop_counter += 1;
if(loop_counter == loop_max) {
//console.log("Last loop");
//console.log("Loop counter:",loop_counter);
stack.pop();
}
else {
//console.log("Still inside loop");
//console.log("Loop counter:",loop_counter);
var stackPop = stack[stack.length - 1];
i = stackPop;
//Skip for now
}
},
nop: function(i, tables, program) {
},
adds: function(i, tables, program) {
var addend = program[i + 1].toUpperCase();
var opperand = program[i + 2].toUpperCase();
if(addend in tables.registers && opperand in tables.registers) {
var valA = parseInt(tables.registers[addend]);
var valB = parseInt(tables.registers[opperand]);
tables.registers["D"] = valA + valB;
}
i += 2;
},
subs: function(i, tables, program) {
var subend = program[i + 1].toUpperCase();
var opperand = program[i + 2].toUpperCase();
if(subend in tables.registers && opperand in tables.registers) {
var valA = parseInt(tables.registers[subend]);
var valB = parseInt(tables.registers[opperand]);
tables.registers["D"] = valA - valB;
}
i += 2;
},
in: function(i, tables, program) {
var dest = program[i + 1].toUpperCase();
var input_source = program[i + 2];
var input_val = document.querySelector(input_source).value;
if(dest in tables.registers) {
tables.registers[dest] = input_val;
}
i += 2;
},
out: function(i, tables, program) {
var source = program[i + 1].toUpperCase();
var output_source = program[i + 2];
if(source in tables.registers) {
var val = tables.registers[source];
document.querySelector(output_source).value = val;
}
i += 2;
},
func: function(i, tables, program) {
var function_name = program[i + 1];
tables.functions[function_name] = i;
var end_func = program.indexOf("endfunc",i);
//var _tmp = program;
//var func_splice = _tmp.slice(i + 2,end_func);
//console.log("Function:",function_name,end_func,func_splice);
i = end_func;
},
ret: function(i, tables, stack, program) {
if(exec_flag) {
var ret = stack.pop();
if(stack.length > 0) {
//console.log("Returning to:",program[ret],ret);
exec_flag = true;
} else {
//console.log("No longer in any function:",stack);
exec_flag = false;
}
i = ret;
}
},
invoke: function(i, tables, stack, program) {
var function_name = program[i + 1];
//console.log("Pushing Iter (Return Point):",i,program[i]);
stack.push(i);
exec_flag = true;
//Lookup lands on the func decleration
var lookup = tables.functions[function_name];
//console.log("Invoking:",function_name,"Going to:",lookup,program[lookup]);
i = lookup;
},
call: function(i, tables, program) {
var func = program[i + 1];
executeFunctionByName(func,stack);
i += 1;
},
eval: function(i, tables, program) {
var prog = program[i + 1];
prog = prog.trim().replace(new RegExp('/',"g"), ',');
console.log(prog);
eval(prog);
i += 1;
},
reset: function(i, tables, program) {
var temp_i = i;
tables.registers = {
A: 0,
B: 0,
C: 0,
D: 0,
E: "ERRORSTR",
F: 0,
I: temp_i,
S: "SLOTSTR",
SP: 0
};
loop_counter = 0;
loop_max = 0;
exec_flag = false;
stack = [];
tables.functions = {};
},
jmp: function(i, tables, program) {
var dest = program[i + 1];
//Search for it
if(result = searchLabel(program, dest)) {
i = result;
}
}
}
function slot_step(tables, stack, i, program) {
switch(program[i]) {
case "set":
slot_api.set(i, tables, program);
break;
case "sets":
slot_api.sets(i, tables, program);
break;
case "incs":
slot_api.incs(i, tables, program);
break;
case "decs":
slot_api.decs(i, tables, program);
break;
case "push":
slot_api.push(i, tables, stack, program);
break;
case "pushs":
slot_api.pushs(i, tables, stack, program);
break;
case "pops":
slot_api.pops(i, tables, stack, program);
break;
case "cmps":
slot_api.cmps(i, tables, program);
break;
case "je":
slot_api.je(i, tables, program);
break;
case "jne":
slot_api.jne(i, tables, program);
break;
case "loop":
slot_api.loop(i, tables, stack, program);
break;
case "endloop":
slot_api.endloop(i, tables, stack, program);
break;
case "nop":
slot_api.nop(i, tables, program);
break;
case "adds":
slot_api.adds(i, tables, program);
break;
case "subs":
slot_api.subs(i, tables, program);
break;
case "in":
slot_api.in(i, tables, program);
break;
case "out":
slot_api.out(i, tables, program);
break;
case ".eval":
slot_api.eval(i, tables, program);
break;
case ".com":
//Skip comments
i += 1;
break;
case ".device":
var device = program[i + 1];
var handle = program[i + 2];
tables.devices[device] = document.querySelector(handle).getContext("2d");
i += 2;
break;
case ".reset":
slot_api.reset(i, tables, program);
break;
case "func":
slot_api.func(i, tables, program);
break;
case "invoke":
slot_api.invoke(i, tables, stack, program);
break;
case "call":
slot_api.call(i, tables, stack, program);
break;
case "ret":
slot_api.ret(i, tables, stack, program);
break;
case "jmp":
slot_api.jmp(i, tables, program);
break;
case ".debug":
console.log("SlotVM DEBUG:",tables,stack);
break;
case ".video":
var attr = program[i + 1];
var value = program[i + 2];
tables.devices.video[attr] = value;
i += 2;
break;
default:
//console.log("Skipping:",program[i]);
//Skip
break;
}
}
function slot_run(savestate, program) {
var exec_flag = false;
var loop_counter = 0;
var stack = [];
var tables = {
functions: {},
devices: {},
registers: {
A: 0,
B: 0,
C: 0,
D: 0,
E: "NOERROR",
F: 0,
I: 0,
S: "SLOTSTR",
SP: 0
}
}
if(savestate) {
tables = savestate;
}
for(var i=0;i < program.length;i++) {
slot_step(tables, stack, i, program);
}
}
window.slot_step = slot_step;
window.slot_run = slot_run;
window.slot_api = slot_api;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment