Compare commits
14 Commits
shyam_ragh
...
mplamann
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e0529a1e0 | ||
|
|
44f10cb5c6 | ||
|
|
d035346d2b | ||
|
|
5bee4d90c5 | ||
|
|
c742d5ed74 | ||
| 609b6e17d4 | |||
| 81a08cb9f8 | |||
| f4b3c06f79 | |||
| 88b006cbcc | |||
| ddf1d00f1b | |||
| 739005289e | |||
|
|
349fd6ff78 | ||
|
|
6138821c3a | ||
|
|
d39df5314d |
BIN
instructions/Thumbs.db
Normal file
BIN
instructions/Thumbs.db
Normal file
Binary file not shown.
0
logo.png
Executable file → Normal file
0
logo.png
Executable file → Normal file
|
Before Width: | Height: | Size: 345 KiB After Width: | Height: | Size: 345 KiB |
0
progress_report/lit_review.tex
Executable file → Normal file
0
progress_report/lit_review.tex
Executable file → Normal file
0
proposal/letter.pdf
Executable file → Normal file
0
proposal/letter.pdf
Executable file → Normal file
0
proposal/letter.tex
Executable file → Normal file
0
proposal/letter.tex
Executable file → Normal file
0
proposal/proposal.pdf
Executable file → Normal file
0
proposal/proposal.pdf
Executable file → Normal file
0
proposal/proposal.tex
Executable file → Normal file
0
proposal/proposal.tex
Executable file → Normal file
@@ -1,4 +1,7 @@
|
|||||||
FILES = c0vm.js bytecode-parser.js byte-stream.js opcodes.js index.js
|
FILES = c0vm.js bytecode-parser.js byte-stream.js opcodes.js c0ffi.js index.js
|
||||||
|
|
||||||
all: $(FILES)
|
all: $(FILES)
|
||||||
browserify $(FILES) -o vm.js
|
browserify $(FILES) -o vm.js
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f vm.js
|
||||||
|
|||||||
0
public/vm/byte-stream.js
Executable file → Normal file
0
public/vm/byte-stream.js
Executable file → Normal file
@@ -4,21 +4,8 @@ byte_stream = require("./byte-stream");
|
|||||||
// This is a simple, kinda hacky bytecode parser for .bc0 files
|
// This is a simple, kinda hacky bytecode parser for .bc0 files
|
||||||
// Now takes in raw bytecode
|
// Now takes in raw bytecode
|
||||||
function getBytes(data) {
|
function getBytes(data) {
|
||||||
/*
|
|
||||||
var data = fs.readFileSync(filename);
|
|
||||||
|
|
||||||
if (data == null) {
|
|
||||||
if (err["code"] === "ENOENT")
|
|
||||||
console.log("Error: file " + filename + " does not exist.");
|
|
||||||
else
|
|
||||||
console.log("Error: " + err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Data contains our file, but we want it as a string
|
// Data contains our file, but we want it as a string
|
||||||
var string_data = data.toString();
|
var string_data = data.toString();
|
||||||
console.log(string_data);
|
|
||||||
|
|
||||||
// Strip all the comments for easier parsing
|
// Strip all the comments for easier parsing
|
||||||
var without_comments = string_data.replace(new RegExp("#.*", "gi"), "");
|
var without_comments = string_data.replace(new RegExp("#.*", "gi"), "");
|
||||||
@@ -33,15 +20,37 @@ function getBytes(data) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// We now have an array of bytes. That's probably everything we need, right?
|
// We now have an array of bytes. That's probably everything we need, right?
|
||||||
console.log(bytes);
|
|
||||||
return bytes;
|
return bytes;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getLineNumbers(data) {
|
||||||
|
var string_data = data.toString();
|
||||||
|
|
||||||
|
// Strip all the comments for easier parsing
|
||||||
|
var without_comments = string_data.replace(new RegExp("#.*", "gi"), "");
|
||||||
|
|
||||||
|
// Each byte should now be a pair of two hex digits.
|
||||||
|
// Put all these in an array.
|
||||||
|
var lines = without_comments.split("\n");
|
||||||
|
var line_numbers = [];
|
||||||
|
for (var line_number = 0; line_number < lines.length; line_number++ ) {
|
||||||
|
lines[line_number].replace(
|
||||||
|
new RegExp("([0123456789ABCDEF][0123456789ABCDEF])", "gi"),
|
||||||
|
function(next_byte) {
|
||||||
|
// +1 because lines start at 1, for some weird reason.
|
||||||
|
// Who doesn't start counting at 0?
|
||||||
|
line_numbers.push(line_number+1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return line_numbers;
|
||||||
|
}
|
||||||
|
|
||||||
var FunctionInfo = function (stream) {
|
var FunctionInfo = function (stream) {
|
||||||
this.num_args = stream.get_u2();
|
this.num_args = stream.get_u2();
|
||||||
this.num_vars = stream.get_u2();
|
this.num_vars = stream.get_u2();
|
||||||
this.code_length = stream.get_u2();
|
this.code_length = stream.get_u2();
|
||||||
|
this.code_byte_offset = stream.index;
|
||||||
this.code = stream.get_bytes(this.code_length);
|
this.code = stream.get_bytes(this.code_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,8 +59,9 @@ var NativeInfo = function (stream) {
|
|||||||
this.function_table_index = stream.get_u2();
|
this.function_table_index = stream.get_u2();
|
||||||
}
|
}
|
||||||
|
|
||||||
var Bc0File = function (filename) {
|
var Bc0File = function (bytecode) {
|
||||||
var file = getBytes(filename);
|
var file = getBytes(bytecode);
|
||||||
|
this.line_numbers = getLineNumbers(bytecode);
|
||||||
var stream = new byte_stream.ByteStream(file);
|
var stream = new byte_stream.ByteStream(file);
|
||||||
|
|
||||||
var magic = stream.get_u4();
|
var magic = stream.get_u4();
|
||||||
@@ -90,6 +100,7 @@ var Bc0File = function (filename) {
|
|||||||
this.function_pool = [];
|
this.function_pool = [];
|
||||||
for (var i = 0; i < this.function_count; i++) {
|
for (var i = 0; i < this.function_count; i++) {
|
||||||
this.function_pool.push(new FunctionInfo(stream));
|
this.function_pool.push(new FunctionInfo(stream));
|
||||||
|
this.function_pool[i].function_id = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.native_count = stream.get_u2();
|
this.native_count = stream.get_u2();
|
||||||
@@ -108,9 +119,50 @@ Bc0File.prototype.string_from_index = function (i) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parse(filename) {
|
Bc0File.prototype.line_for_indices = function(function_index, byte_offset) {
|
||||||
return new Bc0File(filename);
|
var offset_in_file = this.function_pool[function_index].code_byte_offset +
|
||||||
|
byte_offset;
|
||||||
|
return this.line_numbers[offset_in_file];
|
||||||
|
}
|
||||||
|
|
||||||
|
Bc0File.prototype.indicies_for_line = function(line) {
|
||||||
|
// Performs a linear search through the (bytecode to line number) map
|
||||||
|
// to find the bytecode offsets corresponding to a line number
|
||||||
|
var function_index = 0;
|
||||||
|
while (function_index < this.function_pool.length - 1) {
|
||||||
|
var function_start = this.function_pool[function_index + 1].code_byte_offset;
|
||||||
|
if (this.line_numbers[function_start] > line) break;
|
||||||
|
function_start++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// function_index should now be set to the index of the function containing our line
|
||||||
|
var f = this.function_pool[function_index];
|
||||||
|
var offset = 0;
|
||||||
|
while (offset < f.code.length - 1) {
|
||||||
|
if (this.line_numbers[f.code_byte_offset + offset] > line) break;
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
return [function_index, offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
function parse(bytecode) {
|
||||||
|
return new Bc0File(bytecode);
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseFile(filename) {
|
||||||
|
var data = fs.readFileSync(filename);
|
||||||
|
|
||||||
|
if (data == null) {
|
||||||
|
if (err["code"] === "ENOENT")
|
||||||
|
console.log("Error: file " + filename + " does not exist.");
|
||||||
|
else
|
||||||
|
console.log("Error: " + err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parse(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.getBytes = getBytes;
|
exports.getBytes = getBytes;
|
||||||
exports.parse = parse;
|
exports.parse = parse;
|
||||||
|
exports.parseFile = parseFile;
|
||||||
|
|||||||
@@ -108,3 +108,46 @@ exports.NATIVE_STRING_TERMINATED = 92
|
|||||||
exports.NATIVE_STRING_TO_CHARARRAY = 93
|
exports.NATIVE_STRING_TO_CHARARRAY = 93
|
||||||
exports.NATIVE_STRING_TOLOWER = 94
|
exports.NATIVE_STRING_TOLOWER = 94
|
||||||
|
|
||||||
|
callbacks = {};
|
||||||
|
callbacks[exports.NATIVE_STRING_LENGTH] =
|
||||||
|
function(args) {
|
||||||
|
return args[0].length;
|
||||||
|
};
|
||||||
|
|
||||||
|
callbacks[exports.NATIVE_STRING_TO_CHARARRAY] =
|
||||||
|
function(args, vm) {
|
||||||
|
var address = vm.heap.length;
|
||||||
|
vm.heap.push(args[0].length+1);
|
||||||
|
vm.heap.push(1);
|
||||||
|
for (var i = 0; i < args[0].length; i++) {
|
||||||
|
vm.heap.push(args[0][i]);
|
||||||
|
}
|
||||||
|
vm.heap.push(0);
|
||||||
|
return address;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
callbacks[exports.NATIVE_STRING_FROM_CHARARRAY] =
|
||||||
|
function(args, vm) {
|
||||||
|
var i = args[0] + 2;
|
||||||
|
var result = "";
|
||||||
|
while (vm.heap[i] !== 0) {
|
||||||
|
result += vm.heap[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
callbacks[exports.NATIVE_CHAR_CHR] =
|
||||||
|
function(args) {
|
||||||
|
return String.fromCharCode(args[0]);
|
||||||
|
};
|
||||||
|
|
||||||
|
callbacks[exports.NATIVE_CHAR_ORD] =
|
||||||
|
function(args) {
|
||||||
|
if (typeof args[0] == "string")
|
||||||
|
return args[0].charCodeAt(0);
|
||||||
|
return args[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.default_callbacks = callbacks;
|
||||||
|
|||||||
118
public/vm/c0vm.js
Executable file → Normal file
118
public/vm/c0vm.js
Executable file → Normal file
@@ -42,6 +42,7 @@ var StackFrame = function(file, f) {
|
|||||||
this.stack = [];
|
this.stack = [];
|
||||||
this.pc = 0;
|
this.pc = 0;
|
||||||
this.program = f.code;
|
this.program = f.code;
|
||||||
|
this.function_id = f.function_id;
|
||||||
this.variables = [];
|
this.variables = [];
|
||||||
for (var i = 0; i < f.num_vars; i++)
|
for (var i = 0; i < f.num_vars; i++)
|
||||||
this.variables.push(0);
|
this.variables.push(0);
|
||||||
@@ -69,6 +70,8 @@ var ProgramState = function(parsed_file, callback_dict) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.breakpoints = [];
|
||||||
|
|
||||||
// Memory is just a big array of bytes, right?
|
// Memory is just a big array of bytes, right?
|
||||||
// "Allocation" is appending onto this array
|
// "Allocation" is appending onto this array
|
||||||
// A pointer to memory is an index into this array.
|
// A pointer to memory is an index into this array.
|
||||||
@@ -112,9 +115,10 @@ ProgramState.prototype.doIf = function(f) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ProgramState.prototype.step = function() {
|
ProgramState.prototype.step = function() {
|
||||||
|
this.maintain_line_numbers();
|
||||||
var opcode = this.frame.program[this.frame.pc]
|
var opcode = this.frame.program[this.frame.pc]
|
||||||
log("0x" + this.frame.pc.toString(16) + " Running opcode " +
|
log("0x" + this.frame.pc.toString(16) + " Running opcode " +
|
||||||
op.lookup_table[opcode]);
|
op.lookup_table[opcode] + " at line " + this.bytecode_line);
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
// Stack manipulation
|
// Stack manipulation
|
||||||
case op.POP:
|
case op.POP:
|
||||||
@@ -341,7 +345,7 @@ ProgramState.prototype.step = function() {
|
|||||||
}
|
}
|
||||||
log("Calling native function with index " + index + " with arguments " +
|
log("Calling native function with index " + index + " with arguments " +
|
||||||
arg_array);
|
arg_array);
|
||||||
this.push(native_function(arg_array));
|
this.push(native_function(arg_array, this));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Memory allocation operations:
|
// Memory allocation operations:
|
||||||
@@ -470,8 +474,89 @@ ProgramState.prototype.step = function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Takes in a parsed .bc0 file and runs it
|
ProgramState.prototype.maintain_line_numbers = function() {
|
||||||
function execute(file, callbacks, v) {
|
this.bytecode_line = this.file.line_for_indices(this.frame.function_id,
|
||||||
|
this.frame.pc);
|
||||||
|
// this.c0_line = SOMEHOW GET THE LINE IN THE c0 FILE
|
||||||
|
}
|
||||||
|
|
||||||
|
ProgramState.prototype.remove_breakpoint = function(opcode_index) {
|
||||||
|
if (opcode_index < 0){
|
||||||
|
console.log("Error: negative opcode_index" + opcode_index.toString());
|
||||||
|
throw "Error - negative opcode index";
|
||||||
|
}
|
||||||
|
else if (opcode_index >= this.frame.program.length) {
|
||||||
|
console.log("Error: opcode index larger than max index:"
|
||||||
|
+ opcode_index.toString());
|
||||||
|
throw "Error - opcode index too large";
|
||||||
|
}
|
||||||
|
for (i = 0; i < this.breakpoints.length; i++) {
|
||||||
|
if (this.breakpoints[i][1] == opcode_index){
|
||||||
|
var index = i;
|
||||||
|
array.splice(index,1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log("Error: non-breakpoint opcode index" + opcode_index.toString());
|
||||||
|
throw "Error - non-breakpoint opcode index";
|
||||||
|
}
|
||||||
|
|
||||||
|
ProgramState.prototype.set_breakpoint = function(function_index, opcode_index) {
|
||||||
|
if (opcode_index < 0) {
|
||||||
|
console.log("Error: negative opcode_index" + opcode_index.toString());
|
||||||
|
throw "Error - negative opcode index";
|
||||||
|
}
|
||||||
|
else if (opcode_index >= this.frame.program.length) {
|
||||||
|
console.log("Error: opcode index larger than max index:"
|
||||||
|
+ opcode_index.toString());
|
||||||
|
throw "Error - opcode index too large";
|
||||||
|
}
|
||||||
|
this.breakpoints.push([function_index, opcode_index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ProgramState.prototype.set_breakpoint_bytecode_line = function(line) {
|
||||||
|
var indicies = this.file.indicies_for_line(line);
|
||||||
|
if (indicies === null || indicies.length < 2) {
|
||||||
|
console.log("Error - indicies_for_line returned an invalid result.");
|
||||||
|
}
|
||||||
|
this.set_breakpoint(indicies[0], indicies[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ProgramState.prototype.run = function() {
|
||||||
|
while (true) {
|
||||||
|
for (var i = 0; i < this.breakpoints.length; i++) {
|
||||||
|
var breakpoint = this.breakpoints[i];
|
||||||
|
|
||||||
|
if (this.frame.function_id == breakpoint[0] &&
|
||||||
|
this.frame.pc == breakpoint[1] &&
|
||||||
|
this.stopped_at !== breakpoint) {
|
||||||
|
log("Breakpoint reached!");
|
||||||
|
this.stopped_at = breakpoint;
|
||||||
|
|
||||||
|
this.maintain_line_numbers();
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.stopped_at = undefined;
|
||||||
|
|
||||||
|
var val = this.step();
|
||||||
|
if (val !== undefined) return val;
|
||||||
|
|
||||||
|
if (verbose) {
|
||||||
|
console.log("Machine this:");
|
||||||
|
console.log(" Current Stack Frame:");
|
||||||
|
console.log(" Stack: " + this.frame.stack);
|
||||||
|
console.log(" PC: " + this.frame.pc);
|
||||||
|
console.log(" Vars: " + this.frame.variables);
|
||||||
|
// console.log(" Code: " + this.frame.program);
|
||||||
|
console.log(" Heap: " + this.heap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function initialize_vm(file, callbacks, v) {
|
||||||
verbose = typeof v !== 'undefined' ? v : true;
|
verbose = typeof v !== 'undefined' ? v : true;
|
||||||
log("Initializing with file " + file);
|
log("Initializing with file " + file);
|
||||||
|
|
||||||
@@ -481,25 +566,14 @@ function execute(file, callbacks, v) {
|
|||||||
|
|
||||||
log("Beginning execution");
|
log("Beginning execution");
|
||||||
|
|
||||||
while (true) {
|
return state;
|
||||||
var val = state.step();
|
}
|
||||||
if (val !== undefined) return val;
|
|
||||||
|
|
||||||
if (verbose) {
|
// Takes in a parsed .bc0 file and runs it
|
||||||
console.log("Machine state:");
|
function execute(file, callbacks, v) {
|
||||||
console.log(" Current Stack Frame:");
|
var state = initialize_vm(file, callbacks, v);
|
||||||
console.log(" Stack: " + state.frame.stack);
|
return state.run();
|
||||||
console.log(" PC: " + state.frame.pc);
|
|
||||||
console.log(" Vars: " + state.frame.variables);
|
|
||||||
// console.log(" Code: " + state.frame.program);
|
|
||||||
console.log(" Heap: " + state.heap);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (at_breakpoint) {
|
|
||||||
// save state (maybe in a global in this file?)
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.execute = execute;
|
exports.execute = execute;
|
||||||
|
exports.initialize_vm = initialize_vm;
|
||||||
|
|||||||
0
public/vm/cc0.cgi
Executable file → Normal file
0
public/vm/cc0.cgi
Executable file → Normal file
@@ -16,7 +16,7 @@ function print(arg) {
|
|||||||
$("#output").append(arg);
|
$("#output").append(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
callbacks = {};
|
callbacks = c0ffi.default_callbacks;
|
||||||
callbacks[c0ffi.NATIVE_PRINT] = function(args) {
|
callbacks[c0ffi.NATIVE_PRINT] = function(args) {
|
||||||
print(args[0]);
|
print(args[0]);
|
||||||
print("<br />");
|
print("<br />");
|
||||||
@@ -33,6 +33,9 @@ console.log(callbacks);
|
|||||||
|
|
||||||
$("#run").click(function() {
|
$("#run").click(function() {
|
||||||
var input = $("#bytecode").html().replace(/(\r\n|\n|\r)/gm,"");
|
var input = $("#bytecode").html().replace(/(\r\n|\n|\r)/gm,"");
|
||||||
|
|
||||||
|
$("#output").text("");
|
||||||
|
|
||||||
var file = parser.parse($("#bytecode").text());
|
var file = parser.parse($("#bytecode").text());
|
||||||
print("<br />");
|
print("<br />");
|
||||||
print(c0vm.execute(file, callbacks));
|
print(c0vm.execute(file, callbacks));
|
||||||
|
|||||||
113
public/vm/vm.js
113
public/vm/vm.js
@@ -131,6 +131,7 @@ var Bc0File = function (filename) {
|
|||||||
this.function_pool = [];
|
this.function_pool = [];
|
||||||
for (var i = 0; i < this.function_count; i++) {
|
for (var i = 0; i < this.function_count; i++) {
|
||||||
this.function_pool.push(new FunctionInfo(stream));
|
this.function_pool.push(new FunctionInfo(stream));
|
||||||
|
this.function_pool[i].function_id = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.native_count = stream.get_u2();
|
this.native_count = stream.get_u2();
|
||||||
@@ -267,6 +268,49 @@ exports.NATIVE_STRING_TERMINATED = 92
|
|||||||
exports.NATIVE_STRING_TO_CHARARRAY = 93
|
exports.NATIVE_STRING_TO_CHARARRAY = 93
|
||||||
exports.NATIVE_STRING_TOLOWER = 94
|
exports.NATIVE_STRING_TOLOWER = 94
|
||||||
|
|
||||||
|
callbacks = {};
|
||||||
|
callbacks[exports.NATIVE_STRING_LENGTH] =
|
||||||
|
function(args) {
|
||||||
|
return args[0].length;
|
||||||
|
};
|
||||||
|
|
||||||
|
callbacks[exports.NATIVE_STRING_TO_CHARARRAY] =
|
||||||
|
function(args, vm) {
|
||||||
|
var address = vm.heap.length;
|
||||||
|
vm.heap.push(args[0].length+1);
|
||||||
|
vm.heap.push(1);
|
||||||
|
for (var i = 0; i < args[0].length; i++) {
|
||||||
|
vm.heap.push(args[0][i]);
|
||||||
|
}
|
||||||
|
vm.heap.push(0);
|
||||||
|
return address;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
callbacks[exports.NATIVE_STRING_FROM_CHARARRAY] =
|
||||||
|
function(args, vm) {
|
||||||
|
var i = args[0] + 2;
|
||||||
|
var result = "";
|
||||||
|
while (vm.heap[i] !== 0) {
|
||||||
|
result += vm.heap[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
callbacks[exports.NATIVE_CHAR_CHR] =
|
||||||
|
function(args) {
|
||||||
|
return String.fromCharCode(args[0]);
|
||||||
|
};
|
||||||
|
|
||||||
|
callbacks[exports.NATIVE_CHAR_ORD] =
|
||||||
|
function(args) {
|
||||||
|
if (typeof args[0] == "string")
|
||||||
|
return args[0].charCodeAt(0);
|
||||||
|
return args[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.default_callbacks = callbacks;
|
||||||
|
|
||||||
},{}],4:[function(require,module,exports){
|
},{}],4:[function(require,module,exports){
|
||||||
op = require("./opcodes");
|
op = require("./opcodes");
|
||||||
@@ -299,7 +343,6 @@ function i32_to_array(i32) {
|
|||||||
((i32 >> 8) & 0xFF),
|
((i32 >> 8) & 0xFF),
|
||||||
((i32 >> 16) & 0xFF),
|
((i32 >> 16) & 0xFF),
|
||||||
((i32 >> 24) & 0xFF)];
|
((i32 >> 24) & 0xFF)];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function array_to_i32(array) {
|
function array_to_i32(array) {
|
||||||
@@ -314,6 +357,7 @@ var StackFrame = function(file, f) {
|
|||||||
this.stack = [];
|
this.stack = [];
|
||||||
this.pc = 0;
|
this.pc = 0;
|
||||||
this.program = f.code;
|
this.program = f.code;
|
||||||
|
this.function_id = f.function_id;
|
||||||
this.variables = [];
|
this.variables = [];
|
||||||
for (var i = 0; i < f.num_vars; i++)
|
for (var i = 0; i < f.num_vars; i++)
|
||||||
this.variables.push(0);
|
this.variables.push(0);
|
||||||
@@ -334,13 +378,15 @@ var ProgramState = function(parsed_file, callback_dict) {
|
|||||||
try {
|
try {
|
||||||
this.natives[i] = callback_dict[i];
|
this.natives[i] = callback_dict[i];
|
||||||
} catch (key_not_found) {
|
} catch (key_not_found) {
|
||||||
this.natives[i] = function (arg) {
|
this.natives[i] = function (arg) {
|
||||||
console.log("Native function " + name + " called, ran method stub.");
|
console.log("Native function " + name + " called, ran method stub.");
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.breakpoints = [];
|
||||||
|
|
||||||
// Memory is just a big array of bytes, right?
|
// Memory is just a big array of bytes, right?
|
||||||
// "Allocation" is appending onto this array
|
// "Allocation" is appending onto this array
|
||||||
// A pointer to memory is an index into this array.
|
// A pointer to memory is an index into this array.
|
||||||
@@ -409,7 +455,7 @@ ProgramState.prototype.step = function() {
|
|||||||
case op.BIPUSH:
|
case op.BIPUSH:
|
||||||
this.frame.pc += 2;
|
this.frame.pc += 2;
|
||||||
var val = this.frame.program[this.frame.pc-1];
|
var val = this.frame.program[this.frame.pc-1];
|
||||||
|
|
||||||
// Do sign extension if necessary
|
// Do sign extension if necessary
|
||||||
if ((val & 0x80) != 0)
|
if ((val & 0x80) != 0)
|
||||||
val = -0x80 + (val & 0x7F);
|
val = -0x80 + (val & 0x7F);
|
||||||
@@ -611,9 +657,9 @@ ProgramState.prototype.step = function() {
|
|||||||
};
|
};
|
||||||
console.log("Unknown native function index " + f.function_table_index);
|
console.log("Unknown native function index " + f.function_table_index);
|
||||||
}
|
}
|
||||||
log("Calling native function with index " + index + " with arguments " +
|
log("Calling native function with index " + index + " with arguments " +
|
||||||
arg_array);
|
arg_array);
|
||||||
this.push(native_function(arg_array));
|
this.push(native_function(arg_array, this));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Memory allocation operations:
|
// Memory allocation operations:
|
||||||
@@ -623,7 +669,7 @@ ProgramState.prototype.step = function() {
|
|||||||
var address = this.heap.length;
|
var address = this.heap.length;
|
||||||
|
|
||||||
for (var i = 0; i < size; i++) this.heap.push(0);
|
for (var i = 0; i < size; i++) this.heap.push(0);
|
||||||
|
|
||||||
this.push(address);
|
this.push(address);
|
||||||
this.frame.pc += 2;
|
this.frame.pc += 2;
|
||||||
break;
|
break;
|
||||||
@@ -636,7 +682,7 @@ ProgramState.prototype.step = function() {
|
|||||||
|
|
||||||
this.heap.push(num_elements);
|
this.heap.push(num_elements);
|
||||||
this.heap.push(size);
|
this.heap.push(size);
|
||||||
|
|
||||||
for (var i = 0; i < num_elements; i++) {
|
for (var i = 0; i < num_elements; i++) {
|
||||||
for (var j = 0; j < size; j++)
|
for (var j = 0; j < size; j++)
|
||||||
this.heap.push(0);
|
this.heap.push(0);
|
||||||
@@ -742,8 +788,11 @@ ProgramState.prototype.step = function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Takes in a parsed .bc0 file and runs it
|
ProgramState.prototype.set_breakpoint = function(function_index, opcode_index) {
|
||||||
function execute(file, callbacks, v) {
|
this.breakpoints.push([function_index, opcode_index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function initialize_vm(file, callbacks, v) {
|
||||||
verbose = typeof v !== 'undefined' ? v : true;
|
verbose = typeof v !== 'undefined' ? v : true;
|
||||||
log("Initializing with file " + file);
|
log("Initializing with file " + file);
|
||||||
|
|
||||||
@@ -752,29 +801,48 @@ function execute(file, callbacks, v) {
|
|||||||
if (verbose) log(file);
|
if (verbose) log(file);
|
||||||
|
|
||||||
log("Beginning execution");
|
log("Beginning execution");
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_vm(vm) {
|
||||||
while (true) {
|
while (true) {
|
||||||
var val = state.step();
|
for (breakpoint in vm.breakpoints) {
|
||||||
|
if (vm.frame.function_id == breakpoint[0] &&
|
||||||
|
vm.frame.pc == breakpoint[1]) {
|
||||||
|
console.log("Breakpoint reached!");
|
||||||
|
return vm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var val = vm.step();
|
||||||
if (val !== undefined) return val;
|
if (val !== undefined) return val;
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
console.log("Machine state:");
|
console.log("Machine vm:");
|
||||||
console.log(" Current Stack Frame:");
|
console.log(" Current Stack Frame:");
|
||||||
console.log(" Stack: " + state.frame.stack);
|
console.log(" Stack: " + vm.frame.stack);
|
||||||
console.log(" PC: " + state.frame.pc);
|
console.log(" PC: " + vm.frame.pc);
|
||||||
console.log(" Vars: " + state.frame.variables);
|
console.log(" Vars: " + vm.frame.variables);
|
||||||
// console.log(" Code: " + state.frame.program);
|
// console.log(" Code: " + vm.frame.program);
|
||||||
console.log(" Heap: " + state.heap);
|
console.log(" Heap: " + vm.heap);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if (at_breakpoint) {
|
// if (at_breakpoint) {
|
||||||
// save state (maybe in a global in this file?)
|
// save state (maybe in a global in this file?)
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
}
|
// Takes in a parsed .bc0 file and runs it
|
||||||
|
function execute(file, callbacks, v) {
|
||||||
|
var state = initialize_vm(file, callbacks, v);
|
||||||
|
return run_vm(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.execute = execute;
|
exports.execute = execute;
|
||||||
|
exports.initialize_vm = initialize_vm;
|
||||||
|
exports.run_vm = run_vm;
|
||||||
|
|
||||||
},{"./opcodes":6}],5:[function(require,module,exports){
|
},{"./opcodes":6}],5:[function(require,module,exports){
|
||||||
parser = require("./bytecode-parser");
|
parser = require("./bytecode-parser");
|
||||||
@@ -795,7 +863,7 @@ function print(arg) {
|
|||||||
$("#output").append(arg);
|
$("#output").append(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
callbacks = {};
|
callbacks = c0ffi.default_callbacks;
|
||||||
callbacks[c0ffi.NATIVE_PRINT] = function(args) {
|
callbacks[c0ffi.NATIVE_PRINT] = function(args) {
|
||||||
print(args[0]);
|
print(args[0]);
|
||||||
print("<br />");
|
print("<br />");
|
||||||
@@ -812,6 +880,9 @@ console.log(callbacks);
|
|||||||
|
|
||||||
$("#run").click(function() {
|
$("#run").click(function() {
|
||||||
var input = $("#bytecode").html().replace(/(\r\n|\n|\r)/gm,"");
|
var input = $("#bytecode").html().replace(/(\r\n|\n|\r)/gm,"");
|
||||||
|
|
||||||
|
$("#output").text("");
|
||||||
|
|
||||||
var file = parser.parse($("#bytecode").text());
|
var file = parser.parse($("#bytecode").text());
|
||||||
print("<br />");
|
print("<br />");
|
||||||
print(c0vm.execute(file, callbacks));
|
print(c0vm.execute(file, callbacks));
|
||||||
@@ -926,4 +997,4 @@ exports.lookup_table = {
|
|||||||
|
|
||||||
},{}],7:[function(require,module,exports){
|
},{}],7:[function(require,module,exports){
|
||||||
|
|
||||||
},{}]},{},[4,2,1,6,5]);
|
},{}]},{},[4,2,1,6,3,5]);
|
||||||
|
|||||||
110
src/c0ffi.js
110
src/c0ffi.js
@@ -1,110 +0,0 @@
|
|||||||
exports.NATIVE_FADD = 0
|
|
||||||
exports.NATIVE_FDIV = 1
|
|
||||||
exports.NATIVE_FLESS = 2
|
|
||||||
exports.NATIVE_FMUL = 3
|
|
||||||
exports.NATIVE_FSUB = 4
|
|
||||||
exports.NATIVE_FTOI = 5
|
|
||||||
exports.NATIVE_ITOF = 6
|
|
||||||
exports.NATIVE_PRINT_FPT = 7
|
|
||||||
exports.NATIVE_PRINT_HEX = 8
|
|
||||||
exports.NATIVE_PRINT_INT = 9
|
|
||||||
|
|
||||||
/* args */
|
|
||||||
exports.NATIVE_ARGS_FLAG = 10
|
|
||||||
exports.NATIVE_ARGS_INT = 11
|
|
||||||
exports.NATIVE_ARGS_PARSE = 12
|
|
||||||
exports.NATIVE_ARGS_STRING = 13
|
|
||||||
|
|
||||||
/* conio */
|
|
||||||
exports.NATIVE_EOF = 14
|
|
||||||
exports.NATIVE_FLUSH = 15
|
|
||||||
exports.NATIVE_PRINT = 16
|
|
||||||
exports.NATIVE_PRINTBOOL = 17
|
|
||||||
exports.NATIVE_PRINTCHAR = 18
|
|
||||||
exports.NATIVE_PRINTINT = 19
|
|
||||||
exports.NATIVE_PRINTLN = 20
|
|
||||||
exports.NATIVE_READLINE = 21
|
|
||||||
|
|
||||||
/* curses */
|
|
||||||
exports.NATIVE_C_ADDCH = 22
|
|
||||||
exports.NATIVE_C_CBREAK = 23
|
|
||||||
exports.NATIVE_C_CURS_SET = 24
|
|
||||||
exports.NATIVE_C_DELCH = 25
|
|
||||||
exports.NATIVE_C_ENDWIN = 26
|
|
||||||
exports.NATIVE_C_ERASE = 27
|
|
||||||
exports.NATIVE_C_GETCH = 28
|
|
||||||
exports.NATIVE_C_INITSCR = 29
|
|
||||||
exports.NATIVE_C_KEYPAD = 30
|
|
||||||
exports.NATIVE_C_MOVE = 31
|
|
||||||
exports.NATIVE_C_NOECHO = 32
|
|
||||||
exports.NATIVE_C_REFRESH = 33
|
|
||||||
exports.NATIVE_C_SUBWIN = 34
|
|
||||||
exports.NATIVE_C_WADDCH = 35
|
|
||||||
exports.NATIVE_C_WADDSTR = 36
|
|
||||||
exports.NATIVE_C_WCLEAR = 37
|
|
||||||
exports.NATIVE_C_WERASE = 38
|
|
||||||
exports.NATIVE_C_WMOVE = 39
|
|
||||||
exports.NATIVE_C_WREFRESH = 40
|
|
||||||
exports.NATIVE_C_WSTANDEND = 41
|
|
||||||
exports.NATIVE_C_WSTANDOUT = 42
|
|
||||||
exports.NATIVE_CC_GETBEGX = 43
|
|
||||||
exports.NATIVE_CC_GETBEGY = 44
|
|
||||||
exports.NATIVE_CC_GETMAXX = 45
|
|
||||||
exports.NATIVE_CC_GETMAXY = 46
|
|
||||||
exports.NATIVE_CC_GETX = 47
|
|
||||||
exports.NATIVE_CC_GETY = 48
|
|
||||||
exports.NATIVE_CC_HIGHLIGHT = 49
|
|
||||||
exports.NATIVE_CC_KEY_IS_BACKSPACE = 50
|
|
||||||
exports.NATIVE_CC_KEY_IS_DOWN = 51
|
|
||||||
exports.NATIVE_CC_KEY_IS_ENTER = 52
|
|
||||||
exports.NATIVE_CC_KEY_IS_LEFT = 53
|
|
||||||
exports.NATIVE_CC_KEY_IS_RIGHT = 54
|
|
||||||
exports.NATIVE_CC_KEY_IS_UP = 55
|
|
||||||
exports.NATIVE_CC_WBOLDOFF = 56
|
|
||||||
exports.NATIVE_CC_WBOLDON = 57
|
|
||||||
exports.NATIVE_CC_WDIMOFF = 58
|
|
||||||
exports.NATIVE_CC_WDIMON = 59
|
|
||||||
exports.NATIVE_CC_WREVERSEOFF = 60
|
|
||||||
exports.NATIVE_CC_WREVERSEON = 61
|
|
||||||
exports.NATIVE_CC_WUNDEROFF = 62
|
|
||||||
exports.NATIVE_CC_WUNDERON = 63
|
|
||||||
|
|
||||||
/* file */
|
|
||||||
exports.NATIVE_FILE_CLOSE = 64
|
|
||||||
exports.NATIVE_FILE_CLOSED = 65
|
|
||||||
exports.NATIVE_FILE_EOF = 66
|
|
||||||
exports.NATIVE_FILE_READ = 67
|
|
||||||
exports.NATIVE_FILE_READLINE = 68
|
|
||||||
|
|
||||||
/* img */
|
|
||||||
exports.NATIVE_IMAGE_CLONE = 69
|
|
||||||
exports.NATIVE_IMAGE_CREATE = 70
|
|
||||||
exports.NATIVE_IMAGE_DATA = 71
|
|
||||||
exports.NATIVE_IMAGE_DESTROY = 72
|
|
||||||
exports.NATIVE_IMAGE_HEIGHT = 73
|
|
||||||
exports.NATIVE_IMAGE_LOAD = 74
|
|
||||||
exports.NATIVE_IMAGE_SAVE = 75
|
|
||||||
exports.NATIVE_IMAGE_SUBIMAGE = 76
|
|
||||||
exports.NATIVE_IMAGE_WIDTH = 77
|
|
||||||
|
|
||||||
/* parse */
|
|
||||||
exports.NATIVE_PARSE_BOOL = 78
|
|
||||||
exports.NATIVE_PARSE_INT = 79
|
|
||||||
|
|
||||||
/* string */
|
|
||||||
exports.NATIVE_CHAR_CHR = 80
|
|
||||||
exports.NATIVE_CHAR_ORD = 81
|
|
||||||
exports.NATIVE_STRING_CHARAT = 82
|
|
||||||
exports.NATIVE_STRING_COMPARE = 83
|
|
||||||
exports.NATIVE_STRING_EQUAL = 84
|
|
||||||
exports.NATIVE_STRING_FROM_CHARARRAY = 85
|
|
||||||
exports.NATIVE_STRING_FROMBOOL = 86
|
|
||||||
exports.NATIVE_STRING_FROMCHAR = 87
|
|
||||||
exports.NATIVE_STRING_FROMINT = 88
|
|
||||||
exports.NATIVE_STRING_JOIN = 89
|
|
||||||
exports.NATIVE_STRING_LENGTH = 90
|
|
||||||
exports.NATIVE_STRING_SUB = 91
|
|
||||||
exports.NATIVE_STRING_TERMINATED = 92
|
|
||||||
exports.NATIVE_STRING_TO_CHARARRAY = 93
|
|
||||||
exports.NATIVE_STRING_TOLOWER = 94
|
|
||||||
|
|
||||||
0
test/abort.c0.ex
Executable file → Normal file
0
test/abort.c0.ex
Executable file → Normal file
0
test/arith.c0.ex
Executable file → Normal file
0
test/arith.c0.ex
Executable file → Normal file
0
test/arrays.c0.ex
Executable file → Normal file
0
test/arrays.c0.ex
Executable file → Normal file
0
test/dsquared.c0.ex
Executable file → Normal file
0
test/dsquared.c0.ex
Executable file → Normal file
0
test/easyMath.c0.ex
Executable file → Normal file
0
test/easyMath.c0.ex
Executable file → Normal file
0
test/hellosir.c0.ex
Executable file → Normal file
0
test/hellosir.c0.ex
Executable file → Normal file
0
test/iadd.c0
Executable file → Normal file
0
test/iadd.c0
Executable file → Normal file
0
test/iadd.c0.bc0
Executable file → Normal file
0
test/iadd.c0.bc0
Executable file → Normal file
0
test/iadd.c0.ex
Executable file → Normal file
0
test/iadd.c0.ex
Executable file → Normal file
0
test/ishr.c0.ex
Executable file → Normal file
0
test/ishr.c0.ex
Executable file → Normal file
0
test/isqrt.c0.ex
Executable file → Normal file
0
test/isqrt.c0.ex
Executable file → Normal file
0
test/mid.c0.ex
Executable file → Normal file
0
test/mid.c0.ex
Executable file → Normal file
0
test/moreArrays.c0.ex
Executable file → Normal file
0
test/moreArrays.c0.ex
Executable file → Normal file
0
test/piazza1.c0.ex
Executable file → Normal file
0
test/piazza1.c0.ex
Executable file → Normal file
0
test/sample2.5.c0.ex
Executable file → Normal file
0
test/sample2.5.c0.ex
Executable file → Normal file
0
test/strings.c0.ex
Executable file → Normal file
0
test/strings.c0.ex
Executable file → Normal file
0
test/structs.c0.ex
Executable file → Normal file
0
test/structs.c0.ex
Executable file → Normal file
0
test/testError.c0.ex
Executable file → Normal file
0
test/testError.c0.ex
Executable file → Normal file
0
test/testif.c0.ex
Executable file → Normal file
0
test/testif.c0.ex
Executable file → Normal file
@@ -1,8 +1,9 @@
|
|||||||
parser = require("../src/bytecode-parser.js");
|
parser = require("../public/vm/bytecode-parser.js");
|
||||||
c0vm = require("../src/c0vm.js");
|
c0vm = require("../public/vm/c0vm.js");
|
||||||
c0ffi = require("../src/c0ffi.js");
|
c0ffi = require("../public/vm/c0ffi.js");
|
||||||
|
|
||||||
var callbacks = {}
|
var callbacks = c0ffi.default_callbacks;
|
||||||
|
console.log("Initial callbacks: " + callbacks[c0ffi.NATIVE_STRING_LENGTH](["hi"]));
|
||||||
var printout = "";
|
var printout = "";
|
||||||
|
|
||||||
callbacks[c0ffi.NATIVE_PRINT] = function(args) {
|
callbacks[c0ffi.NATIVE_PRINT] = function(args) {
|
||||||
@@ -20,33 +21,9 @@ callbacks[c0ffi.NATIVE_PRINTLN] = function(args) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
callbacks[c0ffi.NATIVE_STRING_LENGTH] = function(args) {
|
|
||||||
return args[0].length;
|
|
||||||
}
|
|
||||||
|
|
||||||
callbacks[c0ffi.NATIVE_STRING_TO_CHARARRAY] = function(args) {
|
|
||||||
return args[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
callbacks[c0ffi.NATIVE_STRING_FROM_CHARARRAY] = function(args) {
|
|
||||||
console.log("string_from_chararray: " + args);
|
|
||||||
return args[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
callbacks[c0ffi.NATIVE_CHAR_CHR] = function(args) {
|
|
||||||
return String.fromCharCode(args[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
callbacks[c0ffi.NATIVE_CHAR_ORD] = function(args) {
|
|
||||||
console.log("native_car_ord: " + args);
|
|
||||||
if (typeof args[0] == "string")
|
|
||||||
return args[0].charCodeAt(0);
|
|
||||||
return args[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
function doTest(filename, expected_result) {
|
function doTest(filename, expected_result) {
|
||||||
return function(test) {
|
return function(test) {
|
||||||
var result = c0vm.execute(parser.parse(filename), callbacks, false);
|
var result = c0vm.execute(parser.parseFile(filename), callbacks, false);
|
||||||
test.ok(result == expected_result,
|
test.ok(result == expected_result,
|
||||||
filename + " - did not get expected result " + expected_result +
|
filename + " - did not get expected result " + expected_result +
|
||||||
", instead got " + result);
|
", instead got " + result);
|
||||||
@@ -58,7 +35,7 @@ exports.testIADD = doTest("iadd.c0.bc0", -2);
|
|||||||
|
|
||||||
exports.testPrint = function(test) {
|
exports.testPrint = function(test) {
|
||||||
printout = "";
|
printout = "";
|
||||||
var result = c0vm.execute(parser.parse("test.bc0"), callbacks, false);
|
var result = c0vm.execute(parser.parseFile("test.bc0"), callbacks, false);
|
||||||
test.ok(printout == "Hello, world.\nYou don't look so good.\n",
|
test.ok(printout == "Hello, world.\nYou don't look so good.\n",
|
||||||
"test.bc0 - Did not print to screen correctly: output was " + printout);
|
"test.bc0 - Did not print to screen correctly: output was " + printout);
|
||||||
test.done();
|
test.done();
|
||||||
@@ -73,7 +50,7 @@ exports.testMID = doTest("mid.c0.bc0", 155);
|
|||||||
// This one should throw an exception because an assertion fails
|
// This one should throw an exception because an assertion fails
|
||||||
exports.testSample25 = function(test) {
|
exports.testSample25 = function(test) {
|
||||||
test.throws(function () {
|
test.throws(function () {
|
||||||
c0vm.execute(parser.parse("sample2.5.c0.bc0"), callbacks, false)
|
c0vm.execute(parser.parseFile("sample2.5.c0.bc0"), callbacks, false)
|
||||||
});
|
});
|
||||||
test.done();
|
test.done();
|
||||||
}
|
}
|
||||||
@@ -84,14 +61,14 @@ exports.testDSQUARED = doTest("dsquared.c0.bc0", 17068);
|
|||||||
|
|
||||||
exports.testArrays = function(test) {
|
exports.testArrays = function(test) {
|
||||||
test.throws(function () {
|
test.throws(function () {
|
||||||
c0vm.execute(parser.parse("arrays.c0.bc0"), callbacks, false)
|
c0vm.execute(parser.parseFile("arrays.c0.bc0"), callbacks, false)
|
||||||
});
|
});
|
||||||
test.done();
|
test.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.testMoreArray = function(test) {
|
exports.testMoreArray = function(test) {
|
||||||
printout = "";
|
printout = "";
|
||||||
var result = c0vm.execute(parser.parse("moreArrays.c0.bc0"), callbacks, false);
|
var result = c0vm.execute(parser.parseFile("moreArrays.c0.bc0"), callbacks, false);
|
||||||
test.ok(printout == "2312",
|
test.ok(printout == "2312",
|
||||||
"moreArrays.c0.bc0 - Did not print to screen correctly, result was " +
|
"moreArrays.c0.bc0 - Did not print to screen correctly, result was " +
|
||||||
printout);
|
printout);
|
||||||
@@ -100,7 +77,7 @@ exports.testMoreArray = function(test) {
|
|||||||
|
|
||||||
exports.testStructs = function(test) {
|
exports.testStructs = function(test) {
|
||||||
printout = "";
|
printout = "";
|
||||||
var result = c0vm.execute(parser.parse("structs.c0.bc0"), callbacks, false);
|
var result = c0vm.execute(parser.parseFile("structs.c0.bc0"), callbacks, false);
|
||||||
test.ok(printout == "potato chip123",
|
test.ok(printout == "potato chip123",
|
||||||
"structs.c0.bc0 - Did not print to screen correctly, result was " +
|
"structs.c0.bc0 - Did not print to screen correctly, result was " +
|
||||||
printout);
|
printout);
|
||||||
@@ -109,14 +86,14 @@ exports.testStructs = function(test) {
|
|||||||
|
|
||||||
exports.testAbort = function(test) {
|
exports.testAbort = function(test) {
|
||||||
test.throws(function () {
|
test.throws(function () {
|
||||||
c0vm.execute(parser.parse("abort.c0.bc0"), callbacks, false);
|
c0vm.execute(parser.parseFile("abort.c0.bc0"), callbacks, false);
|
||||||
});
|
});
|
||||||
test.done();
|
test.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.testArith = function(test) {
|
exports.testArith = function(test) {
|
||||||
printout = "";
|
printout = "";
|
||||||
var result = c0vm.execute(parser.parse("arith.c0.bc0"), callbacks, false);
|
var result = c0vm.execute(parser.parseFile("arith.c0.bc0"), callbacks, false);
|
||||||
test.ok(printout == "-2147483648 2147483647 -375 -2147483648 -9 -1 12 \n-12 12 Modulus testing 11-1 5 1 Testing constants -251 Testing inequalities \ny1 y2 y3 n4 n5 n6 y7 Testing bitwise operators \n992000 1045310 53250 -12083 Testing bit shifting\n-2147483648 7360588088-31-19\n",
|
test.ok(printout == "-2147483648 2147483647 -375 -2147483648 -9 -1 12 \n-12 12 Modulus testing 11-1 5 1 Testing constants -251 Testing inequalities \ny1 y2 y3 n4 n5 n6 y7 Testing bitwise operators \n992000 1045310 53250 -12083 Testing bit shifting\n-2147483648 7360588088-31-19\n",
|
||||||
"arith.c0.bc0 - Did not print to screen correctly, result was " +
|
"arith.c0.bc0 - Did not print to screen correctly, result was " +
|
||||||
printout);
|
printout);
|
||||||
@@ -127,9 +104,29 @@ exports.testPIAZZA1 = doTest("piazza1.c0.bc0", 18);
|
|||||||
|
|
||||||
exports.testSTRINGS = function(test) {
|
exports.testSTRINGS = function(test) {
|
||||||
printout = "";
|
printout = "";
|
||||||
var result = c0vm.execute(parser.parse("strings.c0.bc0"), callbacks, false);
|
var result = c0vm.execute(parser.parseFile("strings.c0.bc0"), callbacks, false);
|
||||||
test.ok(printout == "hello there!?",
|
test.ok(printout == "hello there!?",
|
||||||
"strings.c0.bc0 - Did not print to screen correctly, result was " +
|
"strings.c0.bc0 - Did not print to screen correctly, result was " +
|
||||||
printout);
|
printout);
|
||||||
test.done();
|
test.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.testBREAKPOINT1 = function(test) {
|
||||||
|
var vm = c0vm.initialize_vm(parser.parseFile("easyMath.c0.bc0"),
|
||||||
|
callbacks, false);
|
||||||
|
vm.set_breakpoint(0, 4);
|
||||||
|
var result = vm.run();
|
||||||
|
test.ok(result === vm,
|
||||||
|
"VM did not stop at breakpoint, instead returned " + result);
|
||||||
|
test.ok(vm.frame.stack[0] == 23 &&
|
||||||
|
vm.frame.stack[1] == 19,
|
||||||
|
"VM stack incorrect");
|
||||||
|
|
||||||
|
test.ok(vm.bytecode_line == 19,
|
||||||
|
"VM reports incorrect line in bytecode: " + vm.bytecode_line);
|
||||||
|
|
||||||
|
result = vm.run();
|
||||||
|
test.ok(result == 1748,
|
||||||
|
"VM did not resume operation correctly, gave result " + result);
|
||||||
|
test.done();
|
||||||
|
}
|
||||||
|
|||||||
@@ -47,15 +47,14 @@ block script
|
|||||||
|
|
||||||
function compile() {
|
function compile() {
|
||||||
var code = encodeURIComponent($("#inputCode").val());
|
var code = encodeURIComponent($("#inputCode").val());
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: "POST",
|
type: "POST",
|
||||||
async: true,
|
async: true,
|
||||||
url: "http://www.contrib.andrew.cmu.edu/~amgutier/cc0.cgi",
|
url: "http://www.contrib.andrew.cmu.edu/~amgutier/cc0.cgi",
|
||||||
dataType: "jsonp",
|
dataType: "json",
|
||||||
data: {
|
data: {
|
||||||
data: code
|
data: code
|
||||||
},
|
},
|
||||||
jsonpCallback: "callback"
|
success: callback
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user