diff --git a/public/site.css b/public/site.css index 72d0847..eff7c84 100644 --- a/public/site.css +++ b/public/site.css @@ -4,6 +4,8 @@ border-radius: 4px; padding: 4px; border-color: #ddd; + max-height: 300px; + overflow-y: auto; } .brad { @@ -29,4 +31,5 @@ nav { .btm-btn { margin-bottom: 4px; + margin-top: -14px; } diff --git a/public/vm/Makefile b/public/vm/Makefile new file mode 100644 index 0000000..ea1e733 --- /dev/null +++ b/public/vm/Makefile @@ -0,0 +1,4 @@ +FILES = c0vm.js bytecode-parser.js byte-stream.js opcodes.js index.js + +all: $(FILES) + browserify $(FILES) -o vm.js diff --git a/src/byte-stream.js b/public/vm/byte-stream.js similarity index 86% rename from src/byte-stream.js rename to public/vm/byte-stream.js index fca2fa7..9cb0f50 100755 --- a/src/byte-stream.js +++ b/public/vm/byte-stream.js @@ -1,5 +1,4 @@ var ByteStream = function (byte_array) { - console.log("Instance created."); this.byte_array = byte_array; this.index = 0; }; @@ -25,7 +24,7 @@ ByteStream.prototype.get_u4 = function() { ByteStream.prototype.get_i4 = function() { var unsigned_val = this.get_u4(); var sign_mult = (unsigned_val & 0x80000000) ? -1 : 1; - return (unsigned_val & 0x7FFFFFFF) * sign_mult; + return (unsigned_val & 0x7FFFFFFF) + (unsigned_val & 0x80000000); } ByteStream.prototype.get_bytes = function(n) { diff --git a/src/bytecode-parser.js b/public/vm/bytecode-parser.js similarity index 83% rename from src/bytecode-parser.js rename to public/vm/bytecode-parser.js index 35c82de..1479957 100644 --- a/src/bytecode-parser.js +++ b/public/vm/bytecode-parser.js @@ -2,7 +2,9 @@ fs = require("fs"); byte_stream = require("./byte-stream"); // This is a simple, kinda hacky bytecode parser for .bc0 files -function getBytes(filename) { +// Now takes in raw bytecode +function getBytes(data) { + /* var data = fs.readFileSync(filename); if (data == null) { @@ -12,9 +14,11 @@ function getBytes(filename) { console.log("Error: " + err); return; } + */ // Data contains our file, but we want it as a string var string_data = data.toString(); + console.log(string_data); // Strip all the comments for easier parsing var without_comments = string_data.replace(new RegExp("#.*", "gi"), ""); @@ -29,6 +33,7 @@ function getBytes(filename) { }); // We now have an array of bytes. That's probably everything we need, right? + console.log(bytes); return bytes; } @@ -72,10 +77,11 @@ var Bc0File = function (filename) { for (var i = 0; i < this.string_count; i++) { var c = stream.get_u1(); if (c == 0) { - this.string_pool.push(current_string); - current_string = ""; + // this.string_pool.push(current_string); + // current_string = ""; + this.string_pool.push(0); } else { - current_string += String.fromCharCode(c); + this.string_pool.push(String.fromCharCode(c)); } } @@ -93,6 +99,15 @@ var Bc0File = function (filename) { } } +Bc0File.prototype.string_from_index = function (i) { + var result = ""; + while (this.string_pool[i] !== 0 && i < this.string_pool.length) { + result += this.string_pool[i]; + i++; + } + return result; +} + function parse(filename) { return new Bc0File(filename); } diff --git a/public/vm/c0ffi.js b/public/vm/c0ffi.js new file mode 100644 index 0000000..c3ce859 --- /dev/null +++ b/public/vm/c0ffi.js @@ -0,0 +1,110 @@ +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 + diff --git a/public/vm/c0vm.js b/public/vm/c0vm.js new file mode 100755 index 0000000..32ae799 --- /dev/null +++ b/public/vm/c0vm.js @@ -0,0 +1,506 @@ +op = require("./opcodes"); + +var INT_MIN = 0x80000000; +var INT_MAX = 0x7FFFFFFF; + +var verbose = false; +function log(message) { + if (verbose) console.log(message); +} + +function c0_assertion_failure(val) { + throw ("c0 assertion failure: " + val); +} + +function c0_memory_error(val) { + throw ("c0 memory error: " + val); +} + +function num_to_i32(num) { + log("num is 0x" + num.toString(16)); + log("num & 0x7FFFFFFF is " + (num & 0x7FFFFFFF)); + log("neg factor is " + ( (num & 0x80000000))); + return (num & 0x7FFFFFFF) + ((num & 0x80000000)); +} + +function i32_to_array(i32) { + return [(i32 & 0xFF), + ((i32 >> 8) & 0xFF), + ((i32 >> 16) & 0xFF), + ((i32 >> 24) & 0xFF)]; + +} + +function array_to_i32(array) { + return array[0] + + (array[1] << 8) + + (array[2] << 16) + + (array[3] << 24); +} + +var StackFrame = function(file, f) { + log("Creating stack frame"); + this.stack = []; + this.pc = 0; + this.program = f.code; + this.variables = []; + for (var i = 0; i < f.num_vars; i++) + this.variables.push(0); + this.file = file; +} + +var ProgramState = function(parsed_file, callback_dict) { + log("Creating program state with file " + parsed_file); + var main_function = parsed_file.function_pool[0]; + + this.frame = new StackFrame(parsed_file, parsed_file.function_pool[0]); + this.call_stack = []; + this.file = parsed_file; + + this.natives = {}; + + for (var i = 0; i < 95; i++) { + try { + this.natives[i] = callback_dict[i]; + } catch (key_not_found) { + this.natives[i] = function (arg) { + console.log("Native function " + name + " called, ran method stub."); + return 0; + }; + } + } + + // Memory is just a big array of bytes, right? + // "Allocation" is appending onto this array + // A pointer to memory is an index into this array. + + // Structs are stored as themselves + // Arrays are stored as an entry for the number of elements + // and then the array, byte-by-byte + this.heap = []; +} + +ProgramState.prototype.push = function(val) { + this.frame.stack.push(val); +} + +ProgramState.prototype.pop = function() { + if (this.frame.stack === []) + throw "Tried to pop from an empty stack!"; + return this.frame.stack.pop(); +} + +ProgramState.prototype.goto_offset = function() { + var c1 = this.frame.program[this.frame.pc+1]; + var c2 = this.frame.program[this.frame.pc+2] + + var address_offset = (c1 << 8) + c2; + // Handle negative values + if ((address_offset & 0x8000) != 0) + address_offset = -0x8000 + (address_offset & 0x7FFF); + + this.frame.pc += address_offset; +} + +ProgramState.prototype.doIf = function(f) { + var y = this.pop(); + var x = this.pop(); + if (f(x,y)) { + this.goto_offset(); + } else { + this.frame.pc += 3; + } +} + +ProgramState.prototype.step = function() { + var opcode = this.frame.program[this.frame.pc] + log("0x" + this.frame.pc.toString(16) + " Running opcode " + + op.lookup_table[opcode]); + switch (opcode) { + // Stack manipulation + case op.POP: + this.frame.pc++; + this.pop(); + break; + case op.DUP: + this.frame.pc++; + var v = this.pop(); + this.push(v); + this.push(v); + break; + case op.SWAP: + this.frame.pc++; + var v1 = this.pop(); + var v2 = this.pop(); + this.push(v1); + this.push(v2); + break; + case op.BIPUSH: + this.frame.pc += 2; + var val = this.frame.program[this.frame.pc-1]; + + // Do sign extension if necessary + if ((val & 0x80) != 0) + val = -0x80 + (val & 0x7F); + this.push(val); + break; + + // Returning from a function + case op.RETURN: + var retVal = this.pop(); + if (this.call_stack.length == 0) + return retVal; + + this.frame = this.call_stack.pop(); + this.push(retVal); + + break; + // Arithmetic + case op.IADD: + this.frame.pc++; + var y = this.pop(); + var x = this.pop(); + log("Adding " + x + " and " + y); + this.push(num_to_i32(x+y)); + break; + case op.ISUB: + this.frame.pc++; + var y = this.pop(); + var x = this.pop(); + log("Subtracting " + x + " and " + y); + this.push(num_to_i32(x-y)); + break; + case op.IMUL: + this.frame.pc++; + var y = this.pop(); + var x = this.pop(); + this.push(num_to_i32(x*y)); + break; + case op.IDIV: + this.frame.pc++; + var y = this.pop(); + var x = this.pop(); + if (y == 0) c0_arith_error("Divide by zero"); + if (x == INT_MIN && y == -1) c0_arith_error("Arithmetic overflow"); + + // This does int division. + // As I understand it, the ~~ is treated as the identity on integers + // which forces the type to int, not float + this.push(~~(x/y)); + break; + case op.IREM: + this.frame.pc++; + var y = this.pop(); + var x = this.pop(); + if (y == 0) c0_arith_error("Divide by zero"); + if (x == INT_MIN && y == -1) c0_arith_error("Arithmetic overflow"); + this.push(x%y); + break; + case op.IAND: + this.frame.pc++; + var y = this.pop(); + var x = this.pop(); + this.push(x&y); + break; + case op.IOR: + this.frame.pc++; + var y = this.pop(); + var x = this.pop(); + this.push(x|y); + break; + case op.IXOR: + this.frame.pc++; + var y = this.pop(); + var x = this.pop(); + this.push(x^y); + break; + case op.ISHL: + this.frame.pc++; + var y = this.pop(); + var x = this.pop(); + if (y < 0 || y > 31) c0_arith_error("Shifting by too many bits"); + this.push(x< 31) c0_arith_error("Shifting by too many bits"); + this.push(x>>y); + break; + + // Operations on local variables + + case op.VLOAD: + this.frame.pc += 2; + var index = this.frame.program[this.frame.pc-1]; + this.push(this.frame.variables[index]); + break; + case op.VSTORE: + this.frame.pc += 2; + var index = this.frame.program[this.frame.pc-1]; + var val = this.pop(); + this.frame.variables[index] = val; + log("Set variable " + index + " to value " + val); + break; + case op.ACONST_NULL: + this.frame.pc++; + this.push(0); + break; + case op.ILDC: + this.frame.pc += 3; + var c1 = this.frame.program[this.frame.pc-2]; + var c2 = this.frame.program[this.frame.pc-1]; + var index = (c1 * 0x1000) + c2; + + this.push(this.file.int_pool[index]); + break; + case op.ALDC: + this.frame.pc += 3; + var c1 = this.frame.program[this.frame.pc-2]; + var c2 = this.frame.program[this.frame.pc-1]; + var index = (c1 * 0x1000) + c2; + + this.push(this.file.string_from_index(index)); + break; + + // Control flow + case op.NOP: + this.frame.pc++; + break; + case op.IF_CMPEQ: + this.doIf(function (x,y) {return y == x;}); + break; + case op.IF_CMPNE: + this.doIf(function (x,y) {return y != x;}); + break; + case op.IF_ICMPLT: + this.doIf(function (x,y) {return y > x;}); + break; + case op.IF_ICMPGE: + this.doIf(function (x,y) {return y <= x;}); + break; + case op.IF_ICMPGT: + this.doIf(function (x,y) {return y < x;}); + break; + case op.IF_ICMPLE: + this.doIf(function (x,y) {return y >= x;}); + break; + case op.GOTO: + this.goto_offset(); + break; + case op.ATHROW: + this.frame.pc++; + c0_user_error(this.pop()); + break; + case op.ASSERT: + this.frame.pc++; + var a = this.pop(); + if (this.pop() == 0) + c0_assertion_failure(a); + break; + + // Function call operations + + case op.INVOKESTATIC: + var c1 = this.frame.program[this.frame.pc+1]; + var c2 = this.frame.program[this.frame.pc+2]; + this.frame.pc += 3; + + var index = (c1 << 8) + c2; + + var f = this.file.function_pool[index]; + var newFrame = new StackFrame(this.file, f); + for (var i = f.num_args - 1; i >= 0; i--) { + newFrame.variables[i] = this.pop(); + } + + this.call_stack.push(this.frame); + this.frame = newFrame; + break; + + case op.INVOKENATIVE: + var c1 = this.frame.program[this.frame.pc+1]; + var c2 = this.frame.program[this.frame.pc+2]; + this.frame.pc += 3; + + var index = (c1 << 8) + c2; + + var f = this.file.native_pool[index]; + var arg_array = []; + for (var i = f.num_args - 1; i >= 0; i--) + arg_array[i] = this.pop(); + + var native_function = this.natives[f.function_table_index]; + if (native_function === undefined) { + native_function = function (ignored) { + console.log("Could not find native function with index " + + f.function_table_index); + return 0; + }; + console.log("Unknown native function index " + f.function_table_index); + } + log("Calling native function with index " + index + " with arguments " + + arg_array); + this.push(native_function(arg_array)); + break; + + // Memory allocation operations: + + case op.NEW: + var size = this.frame.program[this.frame.pc+1]; + var address = this.heap.length; + + for (var i = 0; i < size; i++) this.heap.push(0); + + this.push(address); + this.frame.pc += 2; + break; + + case op.NEWARRAY: + var size = this.frame.program[this.frame.pc+1]; + var address = this.heap.length; + var num_elements = this.pop(); + if (num_elements < 0) c0_memory_error("Array size must be nonnegative"); + + this.heap.push(num_elements); + this.heap.push(size); + + for (var i = 0; i < num_elements; i++) { + for (var j = 0; j < size; j++) + this.heap.push(0); + } + + this.push(address); + this.frame.pc += 2; + break; + + case op.ARRAYLENGTH: + var pointer = this.pop(); + this.push(this.heap[pointer]); + break; + + // Memory access operations: + + case op.AADDF: + // Read offset into a struct + var offset = this.frame.program[this.frame.pc + 1]; + var index = this.pop(); + this.push(index + offset); + this.frame.pc += 2; + break; + + case op.AADDS: + // Read offset into an array + var elt_index = this.pop(); + var index = this.pop(); + + if (typeof index == "string") { + this.push(index.slice(elt_index)); + } else { + var array_length = this.heap[index]; + var elt_size = this.heap[index+1]; + if (elt_index >= array_length) + c0_memory_error("Array index out of bounds."); + this.push(index + 2 + (elt_size*elt_index)); + } + this.frame.pc++; + break; + + case op.IMLOAD: + var addr = this.pop(); + // Get int32 from bytes + var c1 = this.heap[addr]; + var c2 = this.heap[addr+1]; + var c3 = this.heap[addr+2]; + var c4 = this.heap[addr+3]; + var combined = array_to_i32([c1, c2, c3, c4]); + this.push(combined); + this.frame.pc++; + break; + + case op.IMSTORE: + var value = this.pop(); + var addr = this.pop(); + var array = i32_to_array(value); + + for (var i = 0; i < 4; i++) + this.heap[addr + i] = array[i]; + this.frame.pc++; + break; + + case op.AMLOAD: + var addr = this.pop(); + this.push(this.heap[addr]); + this.frame.pc++; + break; + + case op.AMSTORE: + var value = this.pop(); + var addr = this.pop(); + this.heap[addr] = value; + this.frame.pc++; + break; + + case op.CMLOAD: + var addr = this.pop(); + if (typeof addr == "string") + this.push(addr); + else + this.push(this.heap[addr]); + this.frame.pc++; + break; + + case op.CMSTORE: + var value = this.pop(); + var addr = this.pop(); + this.heap[addr] = value; + this.frame.pc++; + break; + + default: + var opcode_name; + try { + opcode_name = op.lookup_table[opcode]; + } catch (ignored) { + opcode_name = "UNKNOWN"; + } + console.log("Error: Unknown opcode: 0x" + opcode.toString(16) + + " (" + opcode_name + ")\n"); + throw "Error - unknown opcode"; + } +} + +// Takes in a parsed .bc0 file and runs it +function execute(file, callbacks, v) { + verbose = typeof v !== 'undefined' ? v : true; + log("Initializing with file " + file); + + var state = new ProgramState(file, callbacks); + + if (verbose) log(file); + + log("Beginning execution"); + + while (true) { + var val = state.step(); + if (val !== undefined) return val; + + if (verbose) { + console.log("Machine state:"); + console.log(" Current Stack Frame:"); + console.log(" Stack: " + state.frame.stack); + 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; diff --git a/src/cc0.cgi b/public/vm/cc0.cgi similarity index 100% rename from src/cc0.cgi rename to public/vm/cc0.cgi diff --git a/public/vm/index.js b/public/vm/index.js new file mode 100644 index 0000000..2a09301 --- /dev/null +++ b/public/vm/index.js @@ -0,0 +1,39 @@ +parser = require("./bytecode-parser"); +c0vm = require("./c0vm.js"); +c0ffi = require("./c0ffi.js"); + +// console.log("Reading in sample bytecode file:"); +// console.log(parser.getBytes("../test/test.bc0")); +// console.log("That was the sample bytecode file" + +// " -- it probably took up your whole terminal screen."); +// var file = parser.parse("../test/test.bc0"); +// console.log(file); +// console.log(file.function_pool[0].code); + +// UI interaction functions + +function print(arg) { + $("#output").append(arg); +} + +callbacks = {}; +callbacks[c0ffi.NATIVE_PRINT] = function(args) { + print(args[0]); + print("
"); + return 0; +} + +callbacks[c0ffi.NATIVE_PRINTINT] = function(args) { + print(args[0]); + print("
"); + return 0; +} + +console.log(callbacks); + +$("#run").click(function() { + var input = $("#bytecode").html().replace(/(\r\n|\n|\r)/gm,""); + var file = parser.parse($("#bytecode").text()); + print("
"); + print(c0vm.execute(file, callbacks)); +}); diff --git a/src/opcodes.js b/public/vm/opcodes.js similarity index 93% rename from src/opcodes.js rename to public/vm/opcodes.js index b0ed6eb..98ec086 100644 --- a/src/opcodes.js +++ b/public/vm/opcodes.js @@ -90,12 +90,12 @@ exports.lookup_table = { 0x13: "ILDC", 0x14: "ALDC", 0x00: "NOP", - 0x9F: "IF", - 0xA0: "IF", - 0xA1: "IF", - 0xA2: "IF", - 0xA3: "IF", - 0xA4: "IF", + 0x9F: "IF_CMPEQ", + 0xA0: "IF_CMPNE", + 0xA1: "IF_ICMPLT", + 0xA2: "IF_ICMPGE", + 0xA3: "IF_ICMPGT", + 0xA4: "IF_ICMPLE", 0xA7: "GOTO", 0xBF: "ATHROW", 0xCF: "ASSERT", diff --git a/public/vm/vm.js b/public/vm/vm.js new file mode 100644 index 0000000..47838cb --- /dev/null +++ b/public/vm/vm.js @@ -0,0 +1,929 @@ +(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o> 8) & 0xFF), + ((i32 >> 16) & 0xFF), + ((i32 >> 24) & 0xFF)]; + +} + +function array_to_i32(array) { + return array[0] + + (array[1] << 8) + + (array[2] << 16) + + (array[3] << 24); +} + +var StackFrame = function(file, f) { + log("Creating stack frame"); + this.stack = []; + this.pc = 0; + this.program = f.code; + this.variables = []; + for (var i = 0; i < f.num_vars; i++) + this.variables.push(0); + this.file = file; +} + +var ProgramState = function(parsed_file, callback_dict) { + log("Creating program state with file " + parsed_file); + var main_function = parsed_file.function_pool[0]; + + this.frame = new StackFrame(parsed_file, parsed_file.function_pool[0]); + this.call_stack = []; + this.file = parsed_file; + + this.natives = {}; + + for (var i = 0; i < 95; i++) { + try { + this.natives[i] = callback_dict[i]; + } catch (key_not_found) { + this.natives[i] = function (arg) { + console.log("Native function " + name + " called, ran method stub."); + return 0; + }; + } + } + + // Memory is just a big array of bytes, right? + // "Allocation" is appending onto this array + // A pointer to memory is an index into this array. + + // Structs are stored as themselves + // Arrays are stored as an entry for the number of elements + // and then the array, byte-by-byte + this.heap = []; +} + +ProgramState.prototype.push = function(val) { + this.frame.stack.push(val); +} + +ProgramState.prototype.pop = function() { + if (this.frame.stack === []) + throw "Tried to pop from an empty stack!"; + return this.frame.stack.pop(); +} + +ProgramState.prototype.goto_offset = function() { + var c1 = this.frame.program[this.frame.pc+1]; + var c2 = this.frame.program[this.frame.pc+2] + + var address_offset = (c1 << 8) + c2; + // Handle negative values + if ((address_offset & 0x8000) != 0) + address_offset = -0x8000 + (address_offset & 0x7FFF); + + this.frame.pc += address_offset; +} + +ProgramState.prototype.doIf = function(f) { + var y = this.pop(); + var x = this.pop(); + if (f(x,y)) { + this.goto_offset(); + } else { + this.frame.pc += 3; + } +} + +ProgramState.prototype.step = function() { + var opcode = this.frame.program[this.frame.pc] + log("0x" + this.frame.pc.toString(16) + " Running opcode " + + op.lookup_table[opcode]); + switch (opcode) { + // Stack manipulation + case op.POP: + this.frame.pc++; + this.pop(); + break; + case op.DUP: + this.frame.pc++; + var v = this.pop(); + this.push(v); + this.push(v); + break; + case op.SWAP: + this.frame.pc++; + var v1 = this.pop(); + var v2 = this.pop(); + this.push(v1); + this.push(v2); + break; + case op.BIPUSH: + this.frame.pc += 2; + var val = this.frame.program[this.frame.pc-1]; + + // Do sign extension if necessary + if ((val & 0x80) != 0) + val = -0x80 + (val & 0x7F); + this.push(val); + break; + + // Returning from a function + case op.RETURN: + var retVal = this.pop(); + if (this.call_stack.length == 0) + return retVal; + + this.frame = this.call_stack.pop(); + this.push(retVal); + + break; + // Arithmetic + case op.IADD: + this.frame.pc++; + var y = this.pop(); + var x = this.pop(); + log("Adding " + x + " and " + y); + this.push(num_to_i32(x+y)); + break; + case op.ISUB: + this.frame.pc++; + var y = this.pop(); + var x = this.pop(); + log("Subtracting " + x + " and " + y); + this.push(num_to_i32(x-y)); + break; + case op.IMUL: + this.frame.pc++; + var y = this.pop(); + var x = this.pop(); + this.push(num_to_i32(x*y)); + break; + case op.IDIV: + this.frame.pc++; + var y = this.pop(); + var x = this.pop(); + if (y == 0) c0_arith_error("Divide by zero"); + if (x == INT_MIN && y == -1) c0_arith_error("Arithmetic overflow"); + + // This does int division. + // As I understand it, the ~~ is treated as the identity on integers + // which forces the type to int, not float + this.push(~~(x/y)); + break; + case op.IREM: + this.frame.pc++; + var y = this.pop(); + var x = this.pop(); + if (y == 0) c0_arith_error("Divide by zero"); + if (x == INT_MIN && y == -1) c0_arith_error("Arithmetic overflow"); + this.push(x%y); + break; + case op.IAND: + this.frame.pc++; + var y = this.pop(); + var x = this.pop(); + this.push(x&y); + break; + case op.IOR: + this.frame.pc++; + var y = this.pop(); + var x = this.pop(); + this.push(x|y); + break; + case op.IXOR: + this.frame.pc++; + var y = this.pop(); + var x = this.pop(); + this.push(x^y); + break; + case op.ISHL: + this.frame.pc++; + var y = this.pop(); + var x = this.pop(); + if (y < 0 || y > 31) c0_arith_error("Shifting by too many bits"); + this.push(x< 31) c0_arith_error("Shifting by too many bits"); + this.push(x>>y); + break; + + // Operations on local variables + + case op.VLOAD: + this.frame.pc += 2; + var index = this.frame.program[this.frame.pc-1]; + this.push(this.frame.variables[index]); + break; + case op.VSTORE: + this.frame.pc += 2; + var index = this.frame.program[this.frame.pc-1]; + var val = this.pop(); + this.frame.variables[index] = val; + log("Set variable " + index + " to value " + val); + break; + case op.ACONST_NULL: + this.frame.pc++; + this.push(0); + break; + case op.ILDC: + this.frame.pc += 3; + var c1 = this.frame.program[this.frame.pc-2]; + var c2 = this.frame.program[this.frame.pc-1]; + var index = (c1 * 0x1000) + c2; + + this.push(this.file.int_pool[index]); + break; + case op.ALDC: + this.frame.pc += 3; + var c1 = this.frame.program[this.frame.pc-2]; + var c2 = this.frame.program[this.frame.pc-1]; + var index = (c1 * 0x1000) + c2; + + this.push(this.file.string_from_index(index)); + break; + + // Control flow + case op.NOP: + this.frame.pc++; + break; + case op.IF_CMPEQ: + this.doIf(function (x,y) {return y == x;}); + break; + case op.IF_CMPNE: + this.doIf(function (x,y) {return y != x;}); + break; + case op.IF_ICMPLT: + this.doIf(function (x,y) {return y > x;}); + break; + case op.IF_ICMPGE: + this.doIf(function (x,y) {return y <= x;}); + break; + case op.IF_ICMPGT: + this.doIf(function (x,y) {return y < x;}); + break; + case op.IF_ICMPLE: + this.doIf(function (x,y) {return y >= x;}); + break; + case op.GOTO: + this.goto_offset(); + break; + case op.ATHROW: + this.frame.pc++; + c0_user_error(this.pop()); + break; + case op.ASSERT: + this.frame.pc++; + var a = this.pop(); + if (this.pop() == 0) + c0_assertion_failure(a); + break; + + // Function call operations + + case op.INVOKESTATIC: + var c1 = this.frame.program[this.frame.pc+1]; + var c2 = this.frame.program[this.frame.pc+2]; + this.frame.pc += 3; + + var index = (c1 << 8) + c2; + + var f = this.file.function_pool[index]; + var newFrame = new StackFrame(this.file, f); + for (var i = f.num_args - 1; i >= 0; i--) { + newFrame.variables[i] = this.pop(); + } + + this.call_stack.push(this.frame); + this.frame = newFrame; + break; + + case op.INVOKENATIVE: + var c1 = this.frame.program[this.frame.pc+1]; + var c2 = this.frame.program[this.frame.pc+2]; + this.frame.pc += 3; + + var index = (c1 << 8) + c2; + + var f = this.file.native_pool[index]; + var arg_array = []; + for (var i = f.num_args - 1; i >= 0; i--) + arg_array[i] = this.pop(); + + var native_function = this.natives[f.function_table_index]; + if (native_function === undefined) { + native_function = function (ignored) { + console.log("Could not find native function with index " + + f.function_table_index); + return 0; + }; + console.log("Unknown native function index " + f.function_table_index); + } + log("Calling native function with index " + index + " with arguments " + + arg_array); + this.push(native_function(arg_array)); + break; + + // Memory allocation operations: + + case op.NEW: + var size = this.frame.program[this.frame.pc+1]; + var address = this.heap.length; + + for (var i = 0; i < size; i++) this.heap.push(0); + + this.push(address); + this.frame.pc += 2; + break; + + case op.NEWARRAY: + var size = this.frame.program[this.frame.pc+1]; + var address = this.heap.length; + var num_elements = this.pop(); + if (num_elements < 0) c0_memory_error("Array size must be nonnegative"); + + this.heap.push(num_elements); + this.heap.push(size); + + for (var i = 0; i < num_elements; i++) { + for (var j = 0; j < size; j++) + this.heap.push(0); + } + + this.push(address); + this.frame.pc += 2; + break; + + case op.ARRAYLENGTH: + var pointer = this.pop(); + this.push(this.heap[pointer]); + break; + + // Memory access operations: + + case op.AADDF: + // Read offset into a struct + var offset = this.frame.program[this.frame.pc + 1]; + var index = this.pop(); + this.push(index + offset); + this.frame.pc += 2; + break; + + case op.AADDS: + // Read offset into an array + var elt_index = this.pop(); + var index = this.pop(); + + if (typeof index == "string") { + this.push(index.slice(elt_index)); + } else { + var array_length = this.heap[index]; + var elt_size = this.heap[index+1]; + if (elt_index >= array_length) + c0_memory_error("Array index out of bounds."); + this.push(index + 2 + (elt_size*elt_index)); + } + this.frame.pc++; + break; + + case op.IMLOAD: + var addr = this.pop(); + // Get int32 from bytes + var c1 = this.heap[addr]; + var c2 = this.heap[addr+1]; + var c3 = this.heap[addr+2]; + var c4 = this.heap[addr+3]; + var combined = array_to_i32([c1, c2, c3, c4]); + this.push(combined); + this.frame.pc++; + break; + + case op.IMSTORE: + var value = this.pop(); + var addr = this.pop(); + var array = i32_to_array(value); + + for (var i = 0; i < 4; i++) + this.heap[addr + i] = array[i]; + this.frame.pc++; + break; + + case op.AMLOAD: + var addr = this.pop(); + this.push(this.heap[addr]); + this.frame.pc++; + break; + + case op.AMSTORE: + var value = this.pop(); + var addr = this.pop(); + this.heap[addr] = value; + this.frame.pc++; + break; + + case op.CMLOAD: + var addr = this.pop(); + if (typeof addr == "string") + this.push(addr); + else + this.push(this.heap[addr]); + this.frame.pc++; + break; + + case op.CMSTORE: + var value = this.pop(); + var addr = this.pop(); + this.heap[addr] = value; + this.frame.pc++; + break; + + default: + var opcode_name; + try { + opcode_name = op.lookup_table[opcode]; + } catch (ignored) { + opcode_name = "UNKNOWN"; + } + console.log("Error: Unknown opcode: 0x" + opcode.toString(16) + + " (" + opcode_name + ")\n"); + throw "Error - unknown opcode"; + } +} + +// Takes in a parsed .bc0 file and runs it +function execute(file, callbacks, v) { + verbose = typeof v !== 'undefined' ? v : true; + log("Initializing with file " + file); + + var state = new ProgramState(file, callbacks); + + if (verbose) log(file); + + log("Beginning execution"); + + while (true) { + var val = state.step(); + if (val !== undefined) return val; + + if (verbose) { + console.log("Machine state:"); + console.log(" Current Stack Frame:"); + console.log(" Stack: " + state.frame.stack); + 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; + +},{"./opcodes":6}],5:[function(require,module,exports){ +parser = require("./bytecode-parser"); +c0vm = require("./c0vm.js"); +c0ffi = require("./c0ffi.js"); + +// console.log("Reading in sample bytecode file:"); +// console.log(parser.getBytes("../test/test.bc0")); +// console.log("That was the sample bytecode file" + +// " -- it probably took up your whole terminal screen."); +// var file = parser.parse("../test/test.bc0"); +// console.log(file); +// console.log(file.function_pool[0].code); + +// UI interaction functions + +function print(arg) { + $("#output").append(arg); +} + +callbacks = {}; +callbacks[c0ffi.NATIVE_PRINT] = function(args) { + print(args[0]); + print("
"); + return 0; +} + +callbacks[c0ffi.NATIVE_PRINTINT] = function(args) { + print(args[0]); + print("
"); + return 0; +} + +console.log(callbacks); + +$("#run").click(function() { + var input = $("#bytecode").html().replace(/(\r\n|\n|\r)/gm,""); + var file = parser.parse($("#bytecode").text()); + print("
"); + print(c0vm.execute(file, callbacks)); +}); + +},{"./bytecode-parser":2,"./c0ffi.js":3,"./c0vm.js":4}],6:[function(require,module,exports){ +/* arithmetic operations */ +exports.IADD = 0x60; +exports.IAND = 0x7E; +exports.IDIV = 0x6C; +exports.IMUL = 0x68; +exports.IOR = 0x80; +exports.IREM = 0x70; +exports.ISHL = 0x78; +exports.ISHR = 0x7A; +exports.ISUB = 0x64; +exports.IXOR = 0x82; + +/* stack operations */ +exports.DUP = 0x59; +exports.POP = 0x57; +exports.SWAP = 0x5F; + +/* memory allocation */ +exports.NEWARRAY = 0xBC; +exports.ARRAYLENGTH = 0xBE; +exports.NEW = 0xBB; + +/* memory access */ +exports.AADDF = 0x62; +exports.AADDS = 0x63; +exports.IMLOAD = 0x2E; +exports.AMLOAD = 0x2F; +exports.IMSTORE = 0x4E; +exports.AMSTORE = 0x4F; +exports.CMLOAD = 0x34; +exports.CMSTORE = 0x55; + +/* local variables */ +exports.VLOAD = 0x15; +exports.VSTORE = 0x36; + +/* constants */ +exports.ACONST_NULL = 0x01; +exports.BIPUSH = 0x10; +exports.ILDC = 0x13; +exports.ALDC = 0x14; + +/* control flow */ +exports.NOP = 0x00; +exports.IF_CMPEQ = 0x9F; +exports.IF_CMPNE = 0xA0; +exports.IF_ICMPLT = 0xA1; +exports.IF_ICMPGE = 0xA2; +exports.IF_ICMPGT = 0xA3; +exports.IF_ICMPLE = 0xA4; +exports.GOTO = 0xA7; +exports.ATHROW = 0xBF; +exports.ASSERT = 0xCF; + +/* function calls and returns */ +exports.INVOKESTATIC = 0xB8; +exports.INVOKENATIVE = 0xB7; +exports.RETURN = 0xB0 + + +exports.lookup_table = { + 0x60: "IADD", + 0x7E: "IAND", + 0x6C: "IDIV", + 0x68: "IMUL", + 0x80: "IOR", + 0x70: "IREM", + 0x78: "ISHL", + 0x7A: "ISHR", + 0x64: "ISUB", + 0x82: "IXOR", + 0x59: "DUP", + 0x57: "POP", + 0x5F: "SWAP", + 0xBC: "NEWARRAY", + 0xBE: "ARRAYLENGTH", + 0xBB: "NEW", + 0x62: "AADDF", + 0x63: "AADDS", + 0x2E: "IMLOAD", + 0x2F: "AMLOAD", + 0x4E: "IMSTORE", + 0x4F: "AMSTORE", + 0x34: "CMLOAD", + 0x55: "CMSTORE", + 0x15: "VLOAD", + 0x36: "VSTORE", + 0x01: "ACONST", + 0x10: "BIPUSH", + 0x13: "ILDC", + 0x14: "ALDC", + 0x00: "NOP", + 0x9F: "IF_CMPEQ", + 0xA0: "IF_CMPNE", + 0xA1: "IF_ICMPLT", + 0xA2: "IF_ICMPGE", + 0xA3: "IF_ICMPGT", + 0xA4: "IF_ICMPLE", + 0xA7: "GOTO", + 0xBF: "ATHROW", + 0xCF: "ASSERT", + 0xB8: "INVOKESTATIC", + 0xB7: "INVOKENATIVE", + 0xB0: "RETURN" +}; + +},{}],7:[function(require,module,exports){ + +},{}]},{},[4,2,1,6,5]); diff --git a/src/c0ffi.js b/src/c0ffi.js new file mode 100644 index 0000000..c3ce859 --- /dev/null +++ b/src/c0ffi.js @@ -0,0 +1,110 @@ +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 + diff --git a/src/c0vm.js b/src/c0vm.js deleted file mode 100755 index 5344309..0000000 --- a/src/c0vm.js +++ /dev/null @@ -1,243 +0,0 @@ -op = require("./opcodes"); - -var ProgramState = function(parsed_file) { - var main_function = parsed_file.function_pool[0]; - - this.stack = [] - this.pc = 0; - this.program = main_function.code; - this.variables = []; - for (var i = 0; i < main_function.num_vars; i++) - variables.push(0); - this.file = parsed_file; -} - - -ProgramState.prototype.doIf = function(shouldJump) { - if (shouldJump) { - var address_offset = (this.program[this.pc+1] * 0x1000) + - this.program[this.pc+2]; - this.pc += address_offset; - } else { - this.pc += 3; - } -} - -ProgramState.prototype.step = function() { - console.log("Running opcode " + op.lookup_table[this.program[this.pc]]); - switch (this.program[this.pc]) { - // Stack manipulation - case op.POP: - this.pc++; - this.stack.pop(); - break; - case op.DUP: - this.pc++; - var v = this.stack.pop(); - this.stack.push(v); - this.stack.push(v); - break; - case op.SWAP: - this.pc++; - var v1 = this.stack.pop(); - var v2 = this.stack.pop(); - this.stack.push(v1); - this.stack.push(v2); - break; - case op.BIPUSH: - this.pc += 2; - var val = this.program[this.pc-1]; - - // Do sign extension if necessary - if (val & 0x80 != 0) - val = -0x80 + (val & 0x7F); - this.stack.push(val); - break; - - // Returning from a function - case op.RETURN: - var retVal = this.stack.pop(); - throw retVal; - - // Arithmetic - case op.IADD: - this.pc++; - var y = this.stack.pop(); - var x = this.stack.pop(); - console.log("Adding " + x + " and " + y); - this.stack.push((x+y) % 0x100000000); - break; - case op.ISUB: - this.pc++; - var y = this.stack.pop(); - var x = this.stack.pop(); - this.stack.push((x-y) % 0x100000000); - break; - case op.IMUL: - this.pc++; - var y = this.stack.pop(); - var x = this.stack.pop(); - this.stack.push((x*y) % 0x100000000); - break; - case op.IDIV: - this.pc++; - var y = this.stack.pop(); - var x = this.stack.pop(); - if (y == 0) c0_arith_error("Divide by zero"); - if (x == INT_MIN && y == -1) c0_arith_error("Arithmetic overflow"); - - // This does int division. - // As I understand it, the ~~ is treated as the identity on integers - // which forces the type to int, not float - this.stack.push(~~(x/y)); - break; - case op.IREM: - this.pc++; - var y = this.stack.pop(); - var x = this.stack.pop(); - if (y == 0) c0_arith_error("Divide by zero"); - if (x == INT_MIN && y == -1) c0_arith_error("Arithmetic overflow"); - this.stack.push(x%y); - break; - case op.IAND: - this.pc++; - var y = this.stack.pop(); - var x = this.stack.pop(); - this.stack.push(x&y); - break; - case op.IOR: - this.pc++; - var y = this.stack.pop(); - var x = this.stack.pop(); - this.stack.push(x|y); - break; - case op.IXOR: - this.pc++; - var y = this.stack.pop(); - var x = this.stack.pop(); - this.stack.push(x^y); - break; - case op.ISHL: - this.pc++; - var y = this.stack.pop(); - var x = this.stack.pop(); - if (y < 0 || y > 31) c0_arith_error("Shifting by too many bits"); - this.stack.push(x< 31) c0_arith_error("Shifting by too many bits"); - this.stack.push(x>>y); - break; - - // Operations on local variables - - case op.VLOAD: - this.pc += 2; - var index = this.program[this.pc-1]; - this.stack.push(this.variables[index]); - break; - case op.VSTORE: - this.pc += 2; - var index = this.program[this.pc-1]; - this.variables[index] = this.stack.pop(); - break; - case op.ACONST_NULL: - this.pc++; - this.stack.push(0); - break; - case op.ILDC: - this.pc += 3; - var c1 = this.program[this.pc-2]; - var c2 = this.program[this.pc-1]; - var index = (c1 * 0x1000) + c2; - - this.stack.push(this.file.int_pool[index]); - break; - case op.ALDC: - console.log("Error: I don't know how to handle ALDC yet"); - throw "Error - can't handle ALDC"; - - // Control flow - case op.NOP: - this.pc++; - break; - case op.IF_CMPEQ: - var y = this.stack.pop(); - var x = this.stack.pop(); - this.doIf(y == x); - break; - case op.IF_CMPNE: - var y = this.stack.pop(); - var x = this.stack.pop(); - this.doIf(y != x); - break; - case op.IF_CMPLT: - var y = this.stack.pop(); - var x = this.stack.pop(); - this.doIf(y > x); - break; - case op.IF_CMPGE: - var y = this.stack.pop(); - var x = this.stack.pop(); - this.doIf(y <= x); - break; - case op.IF_CMPGT: - var y = this.stack.pop(); - var x = this.stack.pop(); - this.doIf(y < x); - break; - case op.IF_CMPLE: - var y = this.stack.pop(); - var x = this.stack.pop(); - this.doIf(y >= x); - break; - case op.GOTO: - this.doIf(true); - break; - case op.ATHROW: - this.pc++; - c0_user_error(this.stack.pop()); - break; - case op.ASSERT: - this.pc++; - var a = this.stack.pop(); - if (this.stack.pop() == 0) - c0_assertion_failure(a); - break; - - default: - console.log("Error: Unknown opcode\n"); - throw "Error - unknown opcode"; - } - return false; -} - -// Takes in a parsed .bc0 file and runs it -function execute(f) { - console.log("Beginning execution of file " + f); - - var state = new ProgramState(f); - - while (true) { - // I'm not sure how to structure this control flow yet, - // so if anyone has a better idea, let me know - try { - state.step(); - } catch (val) { - return val; - } - - // if (at_breakpoint) { - // save state (maybe in a global in this file?) - // return; - // } - } -} - -exports.execute = execute; - -// opcode definitions - diff --git a/src/index.js b/src/index.js deleted file mode 100644 index dd3b7a5..0000000 --- a/src/index.js +++ /dev/null @@ -1,13 +0,0 @@ -parser = require("./bytecode-parser"); -c0vm = require("./c0vm.js"); - -// console.log("Reading in sample bytecode file:"); -// console.log(parser.getBytes("../test/test.bc0")); -// console.log("That was the sample bytecode file" + -// " -- it probably took up your whole terminal screen."); -// var file = parser.parse("../test/test.bc0"); -// console.log(file); -// console.log(file.function_pool[0].code); - -var file = parser.parse("../test/iadd.c0.bc0"); -console.log("Result is " + c0vm.execute(file)); diff --git a/test/abort.c0 b/test/abort.c0 new file mode 100644 index 0000000..64491b4 --- /dev/null +++ b/test/abort.c0 @@ -0,0 +1,6 @@ +#use + +int main () { + error("assertion failure"); + return 0; +} diff --git a/test/abort.c0.bc0 b/test/abort.c0.bc0 new file mode 100644 index 0000000..ed14cee --- /dev/null +++ b/test/abort.c0.bc0 @@ -0,0 +1,25 @@ +C0 C0 FF EE # magic number +00 09 # version 4, arch = 1 (64 bits) + +00 00 # int pool count +# int pool + +00 12 # string pool total size +# string pool +61 73 73 65 72 74 69 6F 6E 20 66 61 69 6C 75 72 65 00 # "assertion failure" + +00 01 # function count +# function_pool + +#
+00 00 # number of arguments = 0 +00 00 # number of local variables = 0 +00 07 # code length = 7 bytes +14 00 00 # aldc 0 # s[0] = "assertion failure" +BF # athrow # error "assertion failure" +10 00 # bipush 0 # 0 +B0 # return # + +00 00 # native count +# native pool + diff --git a/test/abort.c0.bc0out b/test/abort.c0.bc0out new file mode 100644 index 0000000..e69de29 diff --git a/test/abort.c0.c0out b/test/abort.c0.c0out new file mode 100644 index 0000000..e69de29 diff --git a/test/abort.c0.ex b/test/abort.c0.ex new file mode 100755 index 0000000..7091bd6 Binary files /dev/null and b/test/abort.c0.ex differ diff --git a/test/arith.c0 b/test/arith.c0 new file mode 100644 index 0000000..4c66238 --- /dev/null +++ b/test/arith.c0 @@ -0,0 +1,129 @@ +#use + +int main() +{ + int max; int min; + int x; int y; int z; + int constant; + + //Testing overflow + max = 2147483647; + min = -2147483648; + y = max + 1; + printint(y); + print(" "); + y = min - 1; + printint(y); + print(" "); +// printint(min / -1); + + //Testing multiplication of negatives + + x = -25; + y = 15; + printint(x * y); + print(" "); + printint(-15 * -2147483648); + print(" "); + + //Divide by 0 +// println(""); +// printint(x / 0); + + //Modulus by 0 +// println(""); +// printint(x % 0); + + //Testing addition + x = -5; + y = -4; + printint(x + y); + z = x - y; + print(" "); + printint(z); + print(" "); + + + //Division truncation + x = 25; + y = 2; + z = x / y; + printint(z); + print(" "); + + println(""); + x = -25; + y = 2; + z = x / y; + printint(z); + print(" "); + x = -25; + y = -2; + z = x / y; + printint(z); + print(" "); + + //Modulus testing + print("Modulus testing "); + printint(235%32); + printint(-15%2); + print(" "); + printint(5%6); + print(" "); + printint(5%-2); + print(" "); + + //Testing constants + print("Testing constants "); + constant = -251; + printint(constant); + print(" "); + + //Testing inequalities + println("Testing inequalities "); + if(5>4) print("y1 "); else print("n1 "); + if(1>-1) print("y2 "); else print("n2 "); + if(0>=0) print("y3 "); else print("n3 "); + if(12945<-235) print("y4 "); else print("n4 "); + if(5<5) print("y5 "); else print("n5 "); + if(-5==5) print("y6 "); else print("n6 "); + if(15!=-15) print("y7 "); else print("n7 "); + + //Testing bitwise operators + println("Testing bitwise operators "); + printint(0xF232C & 0xFF2352); + print(" "); + printint(0xF232C | 0xFF232); + print(" "); + printint(0xCD25 ^ 0x1D27); + print(" "); + printint(~0x2F32); + print(" "); + + //Testing bit shifting + println("Testing bit shifting"); + printint(1<<31); + print(" "); + printint(23<<5); + print(" "); + printint(1>>5<<7); + print(" "); + printint(2352352>>2); + print(" "); + + //Default value for integers +// println("Testing default value for integers"); +// printint(default_int); +// print(" "); + + //Testing other arithmetic functions + printint(-6-25); + print(" "); + printint(6-25); + print(" "); + + + + println(""); + return 0; +} diff --git a/test/arith.c0.bc0 b/test/arith.c0.bc0 new file mode 100644 index 0000000..3a07a92 --- /dev/null +++ b/test/arith.c0.bc0 @@ -0,0 +1,430 @@ +C0 C0 FF EE # magic number +00 09 # version 4, arch = 1 (64 bits) + +00 0F # int pool count +# int pool +7F FF FF FF +80 00 00 00 +80 00 00 00 +00 00 00 EB +FF FF FF 05 +00 00 32 91 +FF FF FF 15 +00 0F 23 2C +00 FF 23 52 +00 0F 23 2C +00 0F F2 32 +00 00 CD 25 +00 00 1D 27 +00 00 2F 32 +00 23 E4 E0 + +01 16 # string pool total size +# string pool +20 20 20 00 # " " +20 20 20 00 # " " +20 20 20 00 # " " +20 20 20 00 # " " +20 20 20 00 # " " +20 20 20 00 # " " +20 20 20 00 # " " +00 # "" +20 20 20 00 # " " +20 20 20 00 # " " +4D 6F 64 75 6C 75 73 20 74 65 73 74 69 6E 67 20 20 20 00 # "Modulus testing " +20 20 20 00 # " " +20 20 20 00 # " " +20 20 20 00 # " " +54 65 73 74 69 6E 67 20 63 6F 6E 73 74 61 6E 74 73 20 20 20 00 # "Testing constants " +20 20 20 00 # " " +54 65 73 74 69 6E 67 20 69 6E 65 71 75 61 6C 69 74 69 65 73 20 20 20 00 # "Testing inequalities " +79 31 20 20 00 # "y1 " +6E 31 20 20 00 # "n1 " +79 32 20 20 00 # "y2 " +6E 32 20 20 00 # "n2 " +79 33 20 20 00 # "y3 " +6E 33 20 20 00 # "n3 " +79 34 20 20 00 # "y4 " +6E 34 20 20 00 # "n4 " +79 35 20 20 00 # "y5 " +6E 35 20 20 00 # "n5 " +79 36 20 20 00 # "y6 " +6E 36 20 20 00 # "n6 " +79 37 20 20 00 # "y7 " +6E 37 20 20 00 # "n7 " +54 65 73 74 69 6E 67 20 62 69 74 77 69 73 65 20 6F 70 65 72 61 74 6F 72 73 20 20 20 00 # "Testing bitwise operators " +20 20 20 00 # " " +20 20 20 00 # " " +20 20 20 00 # " " +20 20 20 00 # " " +54 65 73 74 69 6E 67 20 62 69 74 20 73 68 69 66 74 69 6E 67 00 # "Testing bit shifting" +20 20 20 00 # " " +20 20 20 00 # " " +20 20 20 00 # " " +20 20 20 00 # " " +20 20 20 00 # " " +20 20 20 00 # " " +00 # "" + +00 01 # function count +# function_pool + +#
+00 00 # number of arguments = 0 +00 06 # number of local variables = 6 +02 C5 # code length = 709 bytes +13 00 00 # ildc 0 # c[0] = 2147483647 +36 00 # vstore 0 # max = 2147483647; +13 00 01 # ildc 1 # c[1] = -2147483648 +36 01 # vstore 1 # min = -(-2147483648); +15 00 # vload 0 # max +10 01 # bipush 1 # 1 +60 # iadd # (max + 1) +36 03 # vstore 3 # y = (max + 1); +15 03 # vload 3 # y +B7 00 00 # invokenative 0 # printint(y) +57 # pop # (ignore result) +14 00 00 # aldc 0 # s[0] = " " +B7 00 01 # invokenative 1 # print(" ") +57 # pop # (ignore result) +15 01 # vload 1 # min +10 01 # bipush 1 # 1 +64 # isub # (min - 1) +36 03 # vstore 3 # y = (min - 1); +15 03 # vload 3 # y +B7 00 00 # invokenative 0 # printint(y) +57 # pop # (ignore result) +14 00 04 # aldc 4 # s[4] = " " +B7 00 01 # invokenative 1 # print(" ") +57 # pop # (ignore result) +10 E7 # bipush -25 # -25 +36 02 # vstore 2 # x = -(25); +10 0F # bipush 15 # 15 +36 03 # vstore 3 # y = 15; +15 02 # vload 2 # x +15 03 # vload 3 # y +68 # imul # (x * y) +B7 00 00 # invokenative 0 # printint((x * y)) +57 # pop # (ignore result) +14 00 08 # aldc 8 # s[8] = " " +B7 00 01 # invokenative 1 # print(" ") +57 # pop # (ignore result) +10 F1 # bipush -15 # -15 +13 00 02 # ildc 2 # c[2] = -2147483648 +68 # imul # (-(15) * -(-2147483648)) +B7 00 00 # invokenative 0 # printint((-(15) * -(-2147483648))) +57 # pop # (ignore result) +14 00 0C # aldc 12 # s[12] = " " +B7 00 01 # invokenative 1 # print(" ") +57 # pop # (ignore result) +10 FB # bipush -5 # -5 +36 02 # vstore 2 # x = -(5); +10 FC # bipush -4 # -4 +36 03 # vstore 3 # y = -(4); +15 02 # vload 2 # x +15 03 # vload 3 # y +60 # iadd # (x + y) +B7 00 00 # invokenative 0 # printint((x + y)) +57 # pop # (ignore result) +15 02 # vload 2 # x +15 03 # vload 3 # y +64 # isub # (x - y) +36 04 # vstore 4 # z = (x - y); +14 00 10 # aldc 16 # s[16] = " " +B7 00 01 # invokenative 1 # print(" ") +57 # pop # (ignore result) +15 04 # vload 4 # z +B7 00 00 # invokenative 0 # printint(z) +57 # pop # (ignore result) +14 00 14 # aldc 20 # s[20] = " " +B7 00 01 # invokenative 1 # print(" ") +57 # pop # (ignore result) +10 19 # bipush 25 # 25 +36 02 # vstore 2 # x = 25; +10 02 # bipush 2 # 2 +36 03 # vstore 3 # y = 2; +15 02 # vload 2 # x +15 03 # vload 3 # y +6C # idiv # (x / y) +36 04 # vstore 4 # z = (x / y); +15 04 # vload 4 # z +B7 00 00 # invokenative 0 # printint(z) +57 # pop # (ignore result) +14 00 18 # aldc 24 # s[24] = " " +B7 00 01 # invokenative 1 # print(" ") +57 # pop # (ignore result) +14 00 1C # aldc 28 # s[28] = "" +B7 00 02 # invokenative 2 # println("") +57 # pop # (ignore result) +10 E7 # bipush -25 # -25 +36 02 # vstore 2 # x = -(25); +10 02 # bipush 2 # 2 +36 03 # vstore 3 # y = 2; +15 02 # vload 2 # x +15 03 # vload 3 # y +6C # idiv # (x / y) +36 04 # vstore 4 # z = (x / y); +15 04 # vload 4 # z +B7 00 00 # invokenative 0 # printint(z) +57 # pop # (ignore result) +14 00 1D # aldc 29 # s[29] = " " +B7 00 01 # invokenative 1 # print(" ") +57 # pop # (ignore result) +10 E7 # bipush -25 # -25 +36 02 # vstore 2 # x = -(25); +10 FE # bipush -2 # -2 +36 03 # vstore 3 # y = -(2); +15 02 # vload 2 # x +15 03 # vload 3 # y +6C # idiv # (x / y) +36 04 # vstore 4 # z = (x / y); +15 04 # vload 4 # z +B7 00 00 # invokenative 0 # printint(z) +57 # pop # (ignore result) +14 00 21 # aldc 33 # s[33] = " " +B7 00 01 # invokenative 1 # print(" ") +57 # pop # (ignore result) +14 00 25 # aldc 37 # s[37] = "Modulus testing " +B7 00 01 # invokenative 1 # print("Modulus testing ") +57 # pop # (ignore result) +13 00 03 # ildc 3 # c[3] = 235 +10 20 # bipush 32 # 32 +70 # irem # (235 % 32) +B7 00 00 # invokenative 0 # printint((235 % 32)) +57 # pop # (ignore result) +10 F1 # bipush -15 # -15 +10 02 # bipush 2 # 2 +70 # irem # (-(15) % 2) +B7 00 00 # invokenative 0 # printint((-(15) % 2)) +57 # pop # (ignore result) +14 00 38 # aldc 56 # s[56] = " " +B7 00 01 # invokenative 1 # print(" ") +57 # pop # (ignore result) +10 05 # bipush 5 # 5 +10 06 # bipush 6 # 6 +70 # irem # (5 % 6) +B7 00 00 # invokenative 0 # printint((5 % 6)) +57 # pop # (ignore result) +14 00 3C # aldc 60 # s[60] = " " +B7 00 01 # invokenative 1 # print(" ") +57 # pop # (ignore result) +10 05 # bipush 5 # 5 +10 FE # bipush -2 # -2 +70 # irem # (5 % -(2)) +B7 00 00 # invokenative 0 # printint((5 % -(2))) +57 # pop # (ignore result) +14 00 40 # aldc 64 # s[64] = " " +B7 00 01 # invokenative 1 # print(" ") +57 # pop # (ignore result) +14 00 44 # aldc 68 # s[68] = "Testing constants " +B7 00 01 # invokenative 1 # print("Testing constants ") +57 # pop # (ignore result) +13 00 04 # ildc 4 # c[4] = -251 +36 05 # vstore 5 # constant = -(251); +15 05 # vload 5 # constant +B7 00 00 # invokenative 0 # printint(constant) +57 # pop # (ignore result) +14 00 59 # aldc 89 # s[89] = " " +B7 00 01 # invokenative 1 # print(" ") +57 # pop # (ignore result) +14 00 5D # aldc 93 # s[93] = "Testing inequalities " +B7 00 02 # invokenative 2 # println("Testing inequalities ") +57 # pop # (ignore result) +10 05 # bipush 5 # 5 +10 04 # bipush 4 # 4 +A3 00 06 # if_icmpgt +6 # if (5 > 4) goto <00:then> +A7 00 0D # goto +13 # goto <01:else> +# <00:then> +14 00 75 # aldc 117 # s[117] = "y1 " +B7 00 01 # invokenative 1 # print("y1 ") +57 # pop # (ignore result) +A7 00 0A # goto +10 # goto <02:endif> +# <01:else> +14 00 7A # aldc 122 # s[122] = "n1 " +B7 00 01 # invokenative 1 # print("n1 ") +57 # pop # (ignore result) +# <02:endif> +10 01 # bipush 1 # 1 +10 FF # bipush -1 # -1 +A3 00 06 # if_icmpgt +6 # if (1 > -(1)) goto <03:then> +A7 00 0D # goto +13 # goto <04:else> +# <03:then> +14 00 7F # aldc 127 # s[127] = "y2 " +B7 00 01 # invokenative 1 # print("y2 ") +57 # pop # (ignore result) +A7 00 0A # goto +10 # goto <05:endif> +# <04:else> +14 00 84 # aldc 132 # s[132] = "n2 " +B7 00 01 # invokenative 1 # print("n2 ") +57 # pop # (ignore result) +# <05:endif> +10 00 # bipush 0 # 0 +10 00 # bipush 0 # 0 +A2 00 06 # if_icmpge +6 # if (0 >= 0) goto <06:then> +A7 00 0D # goto +13 # goto <07:else> +# <06:then> +14 00 89 # aldc 137 # s[137] = "y3 " +B7 00 01 # invokenative 1 # print("y3 ") +57 # pop # (ignore result) +A7 00 0A # goto +10 # goto <08:endif> +# <07:else> +14 00 8E # aldc 142 # s[142] = "n3 " +B7 00 01 # invokenative 1 # print("n3 ") +57 # pop # (ignore result) +# <08:endif> +13 00 05 # ildc 5 # c[5] = 12945 +13 00 06 # ildc 6 # c[6] = -235 +A1 00 06 # if_icmplt +6 # if (12945 < -(235)) goto <09:then> +A7 00 0D # goto +13 # goto <10:else> +# <09:then> +14 00 93 # aldc 147 # s[147] = "y4 " +B7 00 01 # invokenative 1 # print("y4 ") +57 # pop # (ignore result) +A7 00 0A # goto +10 # goto <11:endif> +# <10:else> +14 00 98 # aldc 152 # s[152] = "n4 " +B7 00 01 # invokenative 1 # print("n4 ") +57 # pop # (ignore result) +# <11:endif> +10 05 # bipush 5 # 5 +10 05 # bipush 5 # 5 +A1 00 06 # if_icmplt +6 # if (5 < 5) goto <12:then> +A7 00 0D # goto +13 # goto <13:else> +# <12:then> +14 00 9D # aldc 157 # s[157] = "y5 " +B7 00 01 # invokenative 1 # print("y5 ") +57 # pop # (ignore result) +A7 00 0A # goto +10 # goto <14:endif> +# <13:else> +14 00 A2 # aldc 162 # s[162] = "n5 " +B7 00 01 # invokenative 1 # print("n5 ") +57 # pop # (ignore result) +# <14:endif> +10 FB # bipush -5 # -5 +10 05 # bipush 5 # 5 +9F 00 06 # if_cmpeq +6 # if (-(5) == 5) goto <15:then> +A7 00 0D # goto +13 # goto <16:else> +# <15:then> +14 00 A7 # aldc 167 # s[167] = "y6 " +B7 00 01 # invokenative 1 # print("y6 ") +57 # pop # (ignore result) +A7 00 0A # goto +10 # goto <17:endif> +# <16:else> +14 00 AC # aldc 172 # s[172] = "n6 " +B7 00 01 # invokenative 1 # print("n6 ") +57 # pop # (ignore result) +# <17:endif> +10 0F # bipush 15 # 15 +10 F1 # bipush -15 # -15 +A0 00 06 # if_cmpne +6 # if (15 != -(15)) goto <18:then> +A7 00 0D # goto +13 # goto <19:else> +# <18:then> +14 00 B1 # aldc 177 # s[177] = "y7 " +B7 00 01 # invokenative 1 # print("y7 ") +57 # pop # (ignore result) +A7 00 0A # goto +10 # goto <20:endif> +# <19:else> +14 00 B6 # aldc 182 # s[182] = "n7 " +B7 00 01 # invokenative 1 # print("n7 ") +57 # pop # (ignore result) +# <20:endif> +14 00 BB # aldc 187 # s[187] = "Testing bitwise operators " +B7 00 02 # invokenative 2 # println("Testing bitwise operators ") +57 # pop # (ignore result) +13 00 07 # ildc 7 # c[7] = 992044 +13 00 08 # ildc 8 # c[8] = 16720722 +7E # iand # (992044 & 16720722) +B7 00 00 # invokenative 0 # printint((992044 & 16720722)) +57 # pop # (ignore result) +14 00 D8 # aldc 216 # s[216] = " " +B7 00 01 # invokenative 1 # print(" ") +57 # pop # (ignore result) +13 00 09 # ildc 9 # c[9] = 992044 +13 00 0A # ildc 10 # c[10] = 1045042 +80 # ior # (992044 | 1045042) +B7 00 00 # invokenative 0 # printint((992044 | 1045042)) +57 # pop # (ignore result) +14 00 DC # aldc 220 # s[220] = " " +B7 00 01 # invokenative 1 # print(" ") +57 # pop # (ignore result) +13 00 0B # ildc 11 # c[11] = 52517 +13 00 0C # ildc 12 # c[12] = 7463 +82 # ixor # (52517 ^ 7463) +B7 00 00 # invokenative 0 # printint((52517 ^ 7463)) +57 # pop # (ignore result) +14 00 E0 # aldc 224 # s[224] = " " +B7 00 01 # invokenative 1 # print(" ") +57 # pop # (ignore result) +13 00 0D # ildc 13 # c[13] = 12082 +10 FF # bipush -1 # +82 # ixor # ~(12082) +B7 00 00 # invokenative 0 # printint(~(12082)) +57 # pop # (ignore result) +14 00 E4 # aldc 228 # s[228] = " " +B7 00 01 # invokenative 1 # print(" ") +57 # pop # (ignore result) +14 00 E8 # aldc 232 # s[232] = "Testing bit shifting" +B7 00 02 # invokenative 2 # println("Testing bit shifting") +57 # pop # (ignore result) +10 01 # bipush 1 # 1 +10 1F # bipush 31 # 31 +78 # ishl # (1 << 31) +B7 00 00 # invokenative 0 # printint((1 << 31)) +57 # pop # (ignore result) +14 00 FD # aldc 253 # s[253] = " " +B7 00 01 # invokenative 1 # print(" ") +57 # pop # (ignore result) +10 17 # bipush 23 # 23 +10 05 # bipush 5 # 5 +78 # ishl # (23 << 5) +B7 00 00 # invokenative 0 # printint((23 << 5)) +57 # pop # (ignore result) +14 01 01 # aldc 257 # s[257] = " " +B7 00 01 # invokenative 1 # print(" ") +57 # pop # (ignore result) +10 01 # bipush 1 # 1 +10 05 # bipush 5 # 5 +7A # ishr # (1 >> 5) +10 07 # bipush 7 # 7 +78 # ishl # ((1 >> 5) << 7) +B7 00 00 # invokenative 0 # printint(((1 >> 5) << 7)) +57 # pop # (ignore result) +14 01 05 # aldc 261 # s[261] = " " +B7 00 01 # invokenative 1 # print(" ") +57 # pop # (ignore result) +13 00 0E # ildc 14 # c[14] = 2352352 +10 02 # bipush 2 # 2 +7A # ishr # (2352352 >> 2) +B7 00 00 # invokenative 0 # printint((2352352 >> 2)) +57 # pop # (ignore result) +14 01 09 # aldc 265 # s[265] = " " +B7 00 01 # invokenative 1 # print(" ") +57 # pop # (ignore result) +10 FA # bipush -6 # -6 +10 19 # bipush 25 # 25 +64 # isub # (-(6) - 25) +B7 00 00 # invokenative 0 # printint((-(6) - 25)) +57 # pop # (ignore result) +14 01 0D # aldc 269 # s[269] = " " +B7 00 01 # invokenative 1 # print(" ") +57 # pop # (ignore result) +10 06 # bipush 6 # 6 +10 19 # bipush 25 # 25 +64 # isub # (6 - 25) +B7 00 00 # invokenative 0 # printint((6 - 25)) +57 # pop # (ignore result) +14 01 11 # aldc 273 # s[273] = " " +B7 00 01 # invokenative 1 # print(" ") +57 # pop # (ignore result) +14 01 15 # aldc 277 # s[277] = "" +B7 00 02 # invokenative 2 # println("") +57 # pop # (ignore result) +10 00 # bipush 0 # 0 +B0 # return # + +00 03 # native count +# native pool +00 01 00 13 # printint +00 01 00 10 # print +00 01 00 14 # println + diff --git a/test/arith.c0.bc0out b/test/arith.c0.bc0out new file mode 100644 index 0000000..673192c --- /dev/null +++ b/test/arith.c0.bc0out @@ -0,0 +1,6 @@ +-2147483648 2147483647 -375 -2147483648 -9 -1 12 +-12 12 Modulus testing 11-1 5 1 Testing constants -251 Testing inequalities +y1 y2 y3 n4 n5 n6 y7 Testing bitwise operators +992000 1045310 53250 -12083 Testing bit shifting +-2147483648 736 0 588088 -31 -19 +0 diff --git a/test/arith.c0.c0out b/test/arith.c0.c0out new file mode 100644 index 0000000..673192c --- /dev/null +++ b/test/arith.c0.c0out @@ -0,0 +1,6 @@ +-2147483648 2147483647 -375 -2147483648 -9 -1 12 +-12 12 Modulus testing 11-1 5 1 Testing constants -251 Testing inequalities +y1 y2 y3 n4 n5 n6 y7 Testing bitwise operators +992000 1045310 53250 -12083 Testing bit shifting +-2147483648 736 0 588088 -31 -19 +0 diff --git a/test/arith.c0.ex b/test/arith.c0.ex new file mode 100755 index 0000000..9f16997 Binary files /dev/null and b/test/arith.c0.ex differ diff --git a/test/arrays.c0 b/test/arrays.c0 new file mode 100644 index 0000000..116e811 --- /dev/null +++ b/test/arrays.c0 @@ -0,0 +1,12 @@ +#use + +int main() { + int[] A = alloc_array(int, -2); + A[3] = 0; + A[3] = 1; + A[3] = 2; + A[3] = 3; + + printint(A[3]); + return 0; +} diff --git a/test/arrays.c0.bc0 b/test/arrays.c0.bc0 new file mode 100644 index 0000000..9dd5a59 --- /dev/null +++ b/test/arrays.c0.bc0 @@ -0,0 +1,52 @@ +C0 C0 FF EE # magic number +00 09 # version 4, arch = 1 (64 bits) + +00 00 # int pool count +# int pool + +00 00 # string pool total size +# string pool + +00 01 # function count +# function_pool + +#
+00 00 # number of arguments = 0 +00 01 # number of local variables = 1 +00 33 # code length = 51 bytes +10 FE # bipush -2 # -2 +BC 04 # newarray 4 # alloc_array(int, -(2)) +36 00 # vstore 0 # A = alloc_array(int, -(2)); +15 00 # vload 0 # A +10 03 # bipush 3 # 3 +63 # aadds # &A[3] +10 00 # bipush 0 # 0 +4E # imstore # A[3] = 0; +15 00 # vload 0 # A +10 03 # bipush 3 # 3 +63 # aadds # &A[3] +10 01 # bipush 1 # 1 +4E # imstore # A[3] = 1; +15 00 # vload 0 # A +10 03 # bipush 3 # 3 +63 # aadds # &A[3] +10 02 # bipush 2 # 2 +4E # imstore # A[3] = 2; +15 00 # vload 0 # A +10 03 # bipush 3 # 3 +63 # aadds # &A[3] +10 03 # bipush 3 # 3 +4E # imstore # A[3] = 3; +15 00 # vload 0 # A +10 03 # bipush 3 # 3 +63 # aadds # &A[3] +2E # imload # A[3] +B7 00 00 # invokenative 0 # printint(A[3]) +57 # pop # (ignore result) +10 00 # bipush 0 # 0 +B0 # return # + +00 01 # native count +# native pool +00 01 00 10 # printint + diff --git a/test/arrays.c0.bc0out b/test/arrays.c0.bc0out new file mode 100644 index 0000000..64bb6b7 --- /dev/null +++ b/test/arrays.c0.bc0out @@ -0,0 +1 @@ +30 diff --git a/test/arrays.c0.c0out b/test/arrays.c0.c0out new file mode 100644 index 0000000..e69de29 diff --git a/test/arrays.c0.ex b/test/arrays.c0.ex new file mode 100755 index 0000000..dcc6996 Binary files /dev/null and b/test/arrays.c0.ex differ diff --git a/test/chararrays.c0 b/test/chararrays.c0 new file mode 100644 index 0000000..6d6f169 --- /dev/null +++ b/test/chararrays.c0 @@ -0,0 +1,7 @@ +#use + +int main() { + char[] A = alloc_array(char, 5); + printchar(A[3]); + return 0; +} diff --git a/test/dsquared.c0 b/test/dsquared.c0 new file mode 100644 index 0000000..860baae --- /dev/null +++ b/test/dsquared.c0 @@ -0,0 +1,23 @@ +int dsquared(int x, int y) +{ + return x*x + y*y; +} + +int main () +{ + int a1 = 15; + int b1 = 122; + int a2 = 42; + int b2 = 0; + int a3 = -7; + int b3 = -11; + int a4 = -4; + int b4 = 3; + int sum = 0; + sum = sum + dsquared(a1,b1); + sum = sum + dsquared(a2,b2); + sum = sum + dsquared(a3,b3); + sum = sum + dsquared(a4,b4); + return sum; +} + diff --git a/test/dsquared.c0.bc0 b/test/dsquared.c0.bc0 new file mode 100644 index 0000000..d95b37a --- /dev/null +++ b/test/dsquared.c0.bc0 @@ -0,0 +1,78 @@ +C0 C0 FF EE # magic number +00 09 # version 4, arch = 1 (64 bits) + +00 00 # int pool count +# int pool + +00 00 # string pool total size +# string pool + +00 02 # function count +# function_pool + +#
+00 00 # number of arguments = 0 +00 09 # number of local variables = 9 +00 57 # code length = 87 bytes +10 0F # bipush 15 # 15 +36 00 # vstore 0 # a1 = 15; +10 7A # bipush 122 # 122 +36 01 # vstore 1 # b1 = 122; +10 2A # bipush 42 # 42 +36 02 # vstore 2 # a2 = 42; +10 00 # bipush 0 # 0 +36 03 # vstore 3 # b2 = 0; +10 F9 # bipush -7 # -7 +36 04 # vstore 4 # a3 = -(7); +10 F5 # bipush -11 # -11 +36 05 # vstore 5 # b3 = -(11); +10 FC # bipush -4 # -4 +36 06 # vstore 6 # a4 = -(4); +10 03 # bipush 3 # 3 +36 07 # vstore 7 # b4 = 3; +10 00 # bipush 0 # 0 +36 08 # vstore 8 # sum = 0; +15 08 # vload 8 # sum +15 00 # vload 0 # a1 +15 01 # vload 1 # b1 +B8 00 01 # invokestatic 1 # dsquared(a1, b1) +60 # iadd # (sum + dsquared(a1, b1)) +36 08 # vstore 8 # sum = (sum + dsquared(a1, b1)); +15 08 # vload 8 # sum +15 02 # vload 2 # a2 +15 03 # vload 3 # b2 +B8 00 01 # invokestatic 1 # dsquared(a2, b2) +60 # iadd # (sum + dsquared(a2, b2)) +36 08 # vstore 8 # sum = (sum + dsquared(a2, b2)); +15 08 # vload 8 # sum +15 04 # vload 4 # a3 +15 05 # vload 5 # b3 +B8 00 01 # invokestatic 1 # dsquared(a3, b3) +60 # iadd # (sum + dsquared(a3, b3)) +36 08 # vstore 8 # sum = (sum + dsquared(a3, b3)); +15 08 # vload 8 # sum +15 06 # vload 6 # a4 +15 07 # vload 7 # b4 +B8 00 01 # invokestatic 1 # dsquared(a4, b4) +60 # iadd # (sum + dsquared(a4, b4)) +36 08 # vstore 8 # sum = (sum + dsquared(a4, b4)); +15 08 # vload 8 # sum +B0 # return # + + +# +00 02 # number of arguments = 2 +00 02 # number of local variables = 2 +00 0C # code length = 12 bytes +15 00 # vload 0 # x +15 00 # vload 0 # x +68 # imul # (x * x) +15 01 # vload 1 # y +15 01 # vload 1 # y +68 # imul # (y * y) +60 # iadd # ((x * x) + (y * y)) +B0 # return # + +00 00 # native count +# native pool + diff --git a/test/dsquared.c0.bc0out b/test/dsquared.c0.bc0out new file mode 100644 index 0000000..52d2ba8 --- /dev/null +++ b/test/dsquared.c0.bc0out @@ -0,0 +1 @@ +17068 diff --git a/test/dsquared.c0.c0out b/test/dsquared.c0.c0out new file mode 100644 index 0000000..52d2ba8 --- /dev/null +++ b/test/dsquared.c0.c0out @@ -0,0 +1 @@ +17068 diff --git a/test/dsquared.c0.ex b/test/dsquared.c0.ex new file mode 100755 index 0000000..60c7863 Binary files /dev/null and b/test/dsquared.c0.ex differ diff --git a/test/easyMath.c0 b/test/easyMath.c0 new file mode 100644 index 0000000..cc82bcb --- /dev/null +++ b/test/easyMath.c0 @@ -0,0 +1,3 @@ +int main() { + return (23 * 19)<<2; +} diff --git a/test/easyMath.c0.bc0 b/test/easyMath.c0.bc0 new file mode 100644 index 0000000..8b21ff7 --- /dev/null +++ b/test/easyMath.c0.bc0 @@ -0,0 +1,26 @@ +C0 C0 FF EE # magic number +00 09 # version 4, arch = 1 (64 bits) + +00 00 # int pool count +# int pool + +00 00 # string pool total size +# string pool + +00 01 # function count +# function_pool + +#
+00 00 # number of arguments = 0 +00 00 # number of local variables = 0 +00 09 # code length = 9 bytes +10 17 # bipush 23 # 23 +10 13 # bipush 19 # 19 +68 # imul # (23 * 19) +10 02 # bipush 2 # 2 +78 # ishl # ((23 * 19) << 2) +B0 # return # + +00 00 # native count +# native pool + diff --git a/test/easyMath.c0.bc0out b/test/easyMath.c0.bc0out new file mode 100644 index 0000000..461033f --- /dev/null +++ b/test/easyMath.c0.bc0out @@ -0,0 +1 @@ +1748 diff --git a/test/easyMath.c0.c0out b/test/easyMath.c0.c0out new file mode 100644 index 0000000..461033f --- /dev/null +++ b/test/easyMath.c0.c0out @@ -0,0 +1 @@ +1748 diff --git a/test/easyMath.c0.ex b/test/easyMath.c0.ex new file mode 100755 index 0000000..9973be0 Binary files /dev/null and b/test/easyMath.c0.ex differ diff --git a/test/hellosir.c0 b/test/hellosir.c0 new file mode 100644 index 0000000..75b6fdb --- /dev/null +++ b/test/hellosir.c0 @@ -0,0 +1,9 @@ +#use +#use + +int main () { + print("What's your name? "); + string name = readline(); + print(string_join("Hello, ", string_join(name, "!\n"))); + return 0; +} diff --git a/test/hellosir.c0.bc0 b/test/hellosir.c0.bc0 new file mode 100644 index 0000000..2b5b9da --- /dev/null +++ b/test/hellosir.c0.bc0 @@ -0,0 +1,40 @@ +C0 C0 FF EE # magic number +00 09 # version 4, arch = 1 (64 bits) + +00 00 # int pool count +# int pool + +00 1E # string pool total size +# string pool +57 68 61 74 27 73 20 79 6F 75 72 20 6E 61 6D 65 3F 20 00 # "What\'s your name\? " +48 65 6C 6C 6F 2C 20 00 # "Hello, " +21 0A 00 # "!\n" + +00 01 # function count +# function_pool + +#
+00 00 # number of arguments = 0 +00 01 # number of local variables = 1 +00 21 # code length = 33 bytes +14 00 00 # aldc 0 # s[0] = "What\'s your name\? " +B7 00 00 # invokenative 0 # print("What\'s your name\? ") +57 # pop # (ignore result) +B7 00 01 # invokenative 1 # readline() +36 00 # vstore 0 # name = readline(); +14 00 13 # aldc 19 # s[19] = "Hello, " +15 00 # vload 0 # name +14 00 1B # aldc 27 # s[27] = "!\n" +B7 00 02 # invokenative 2 # string_join(name, "!\n") +B7 00 02 # invokenative 2 # string_join("Hello, ", string_join(name, "!\n")) +B7 00 00 # invokenative 0 # print(string_join("Hello, ", string_join(name, "!\n"))) +57 # pop # (ignore result) +10 00 # bipush 0 # 0 +B0 # return # + +00 03 # native count +# native pool +00 01 00 06 # print +00 00 00 0B # readline +00 02 00 4F # string_join + diff --git a/test/hellosir.c0.bc0out b/test/hellosir.c0.bc0out new file mode 100644 index 0000000..23f1147 --- /dev/null +++ b/test/hellosir.c0.bc0out @@ -0,0 +1,2 @@ +What's your name? Hello, uo! +0 diff --git a/test/hellosir.c0.c0out b/test/hellosir.c0.c0out new file mode 100644 index 0000000..10f58e0 --- /dev/null +++ b/test/hellosir.c0.c0out @@ -0,0 +1,2 @@ +What's your name? Hello, hi! +0 diff --git a/test/hellosir.c0.ex b/test/hellosir.c0.ex new file mode 100755 index 0000000..6dc82c9 Binary files /dev/null and b/test/hellosir.c0.ex differ diff --git a/test/iadd.c0.bc0out b/test/iadd.c0.bc0out new file mode 100644 index 0000000..3fbedf6 --- /dev/null +++ b/test/iadd.c0.bc0out @@ -0,0 +1 @@ +-2 diff --git a/test/iadd.c0.c0out b/test/iadd.c0.c0out new file mode 100644 index 0000000..3fbedf6 --- /dev/null +++ b/test/iadd.c0.c0out @@ -0,0 +1 @@ +-2 diff --git a/test/iadd.c0.ex b/test/iadd.c0.ex new file mode 100755 index 0000000..7ab57f9 Binary files /dev/null and b/test/iadd.c0.ex differ diff --git a/test/ishr.c0 b/test/ishr.c0 new file mode 100644 index 0000000..884a533 --- /dev/null +++ b/test/ishr.c0 @@ -0,0 +1,3 @@ +int main () { + return -1 >> 1; /* should return -1 */ +} diff --git a/test/ishr.c0.bc0 b/test/ishr.c0.bc0 new file mode 100644 index 0000000..34f85f9 --- /dev/null +++ b/test/ishr.c0.bc0 @@ -0,0 +1,24 @@ +C0 C0 FF EE # magic number +00 09 # version 4, arch = 1 (64 bits) + +00 00 # int pool count +# int pool + +00 00 # string pool total size +# string pool + +00 01 # function count +# function_pool + +#
+00 00 # number of arguments = 0 +00 00 # number of local variables = 0 +00 06 # code length = 6 bytes +10 FF # bipush -1 # -1 +10 01 # bipush 1 # 1 +7A # ishr # (-(1) >> 1) +B0 # return # + +00 00 # native count +# native pool + diff --git a/test/ishr.c0.bc0out b/test/ishr.c0.bc0out new file mode 100644 index 0000000..3a2e3f4 --- /dev/null +++ b/test/ishr.c0.bc0out @@ -0,0 +1 @@ +-1 diff --git a/test/ishr.c0.c0out b/test/ishr.c0.c0out new file mode 100644 index 0000000..3a2e3f4 --- /dev/null +++ b/test/ishr.c0.c0out @@ -0,0 +1 @@ +-1 diff --git a/test/ishr.c0.ex b/test/ishr.c0.ex new file mode 100755 index 0000000..a8e8013 Binary files /dev/null and b/test/ishr.c0.ex differ diff --git a/test/isqrt.c0 b/test/isqrt.c0 new file mode 100644 index 0000000..b628688 --- /dev/null +++ b/test/isqrt.c0 @@ -0,0 +1,10 @@ +int main () { + int n = 15122; + int i = 0; int k = 0; + while (k <= n) { + k += 2*i + 1; + i++; + } + return i-1; +} + diff --git a/test/isqrt.c0.bc0 b/test/isqrt.c0.bc0 new file mode 100644 index 0000000..2a42549 --- /dev/null +++ b/test/isqrt.c0.bc0 @@ -0,0 +1,51 @@ +C0 C0 FF EE # magic number +00 09 # version 4, arch = 1 (64 bits) + +00 01 # int pool count +# int pool +00 00 3B 12 + +00 00 # string pool total size +# string pool + +00 01 # function count +# function_pool + +#
+00 00 # number of arguments = 0 +00 03 # number of local variables = 3 +00 34 # code length = 52 bytes +13 00 00 # ildc 0 # c[0] = 15122 +36 00 # vstore 0 # n = 15122; +10 00 # bipush 0 # 0 +36 01 # vstore 1 # i = 0; +10 00 # bipush 0 # 0 +36 02 # vstore 2 # k = 0; +# <00:loop> +15 02 # vload 2 # k +15 00 # vload 0 # n +A4 00 06 # if_icmple +6 # if (k <= n) goto <01:body> +A7 00 1A # goto +26 # goto <02:exit> +# <01:body> +15 02 # vload 2 # k +10 02 # bipush 2 # 2 +15 01 # vload 1 # i +68 # imul # (2 * i) +10 01 # bipush 1 # 1 +60 # iadd # ((2 * i) + 1) +60 # iadd # +36 02 # vstore 2 # k += ((2 * i) + 1); +15 01 # vload 1 # i +10 01 # bipush 1 # 1 +60 # iadd # +36 01 # vstore 1 # i += 1; +A7 FF E2 # goto -30 # goto <00:loop> +# <02:exit> +15 01 # vload 1 # i +10 01 # bipush 1 # 1 +64 # isub # (i - 1) +B0 # return # + +00 00 # native count +# native pool + diff --git a/test/isqrt.c0.bc0out b/test/isqrt.c0.bc0out new file mode 100644 index 0000000..e69de29 diff --git a/test/isqrt.c0.c0out b/test/isqrt.c0.c0out new file mode 100644 index 0000000..9f54fe3 --- /dev/null +++ b/test/isqrt.c0.c0out @@ -0,0 +1 @@ +122 diff --git a/test/isqrt.c0.ex b/test/isqrt.c0.ex new file mode 100755 index 0000000..40a9a81 Binary files /dev/null and b/test/isqrt.c0.ex differ diff --git a/test/mid.c0 b/test/mid.c0 new file mode 100644 index 0000000..c3efe9a --- /dev/null +++ b/test/mid.c0 @@ -0,0 +1,10 @@ +int main() +{ + int low = 0x15; + int high = 0x122; + int mid; + + mid = low + (high - low)/2; + return mid; +} + diff --git a/test/mid.c0.bc0 b/test/mid.c0.bc0 new file mode 100644 index 0000000..0d2323d --- /dev/null +++ b/test/mid.c0.bc0 @@ -0,0 +1,35 @@ +C0 C0 FF EE # magic number +00 09 # version 4, arch = 1 (64 bits) + +00 01 # int pool count +# int pool +00 00 01 22 + +00 00 # string pool total size +# string pool + +00 01 # function count +# function_pool + +#
+00 00 # number of arguments = 0 +00 03 # number of local variables = 3 +00 19 # code length = 25 bytes +10 15 # bipush 21 # 21 +36 00 # vstore 0 # low = 21; +13 00 00 # ildc 0 # c[0] = 290 +36 01 # vstore 1 # high = 290; +15 00 # vload 0 # low +15 01 # vload 1 # high +15 00 # vload 0 # low +64 # isub # (high - low) +10 02 # bipush 2 # 2 +6C # idiv # ((high - low) / 2) +60 # iadd # (low + ((high - low) / 2)) +36 02 # vstore 2 # mid = (low + ((high - low) / 2)); +15 02 # vload 2 # mid +B0 # return # + +00 00 # native count +# native pool + diff --git a/test/mid.c0.bc0out b/test/mid.c0.bc0out new file mode 100644 index 0000000..bb79365 --- /dev/null +++ b/test/mid.c0.bc0out @@ -0,0 +1 @@ +155 diff --git a/test/mid.c0.c0out b/test/mid.c0.c0out new file mode 100644 index 0000000..bb79365 --- /dev/null +++ b/test/mid.c0.c0out @@ -0,0 +1 @@ +155 diff --git a/test/mid.c0.ex b/test/mid.c0.ex new file mode 100755 index 0000000..07c414a Binary files /dev/null and b/test/mid.c0.ex differ diff --git a/test/moreArrays.c0 b/test/moreArrays.c0 new file mode 100644 index 0000000..c9c0fe0 --- /dev/null +++ b/test/moreArrays.c0 @@ -0,0 +1,10 @@ +#use + +int main() { + int[] A = alloc_array(int, 50); + A[3] = 23; + A[2] = 12; + printint(A[3]); + printint(A[2]); + return 0; +} diff --git a/test/moreArrays.c0.bc0 b/test/moreArrays.c0.bc0 new file mode 100644 index 0000000..595e47a --- /dev/null +++ b/test/moreArrays.c0.bc0 @@ -0,0 +1,48 @@ +C0 C0 FF EE # magic number +00 09 # version 4, arch = 1 (64 bits) + +00 00 # int pool count +# int pool + +00 00 # string pool total size +# string pool + +00 01 # function count +# function_pool + +#
+00 00 # number of arguments = 0 +00 01 # number of local variables = 1 +00 2D # code length = 45 bytes +10 32 # bipush 50 # 50 +BC 04 # newarray 4 # alloc_array(int, 50) +36 00 # vstore 0 # A = alloc_array(int, 50); +15 00 # vload 0 # A +10 03 # bipush 3 # 3 +63 # aadds # &A[3] +10 17 # bipush 23 # 23 +4E # imstore # A[3] = 23; +15 00 # vload 0 # A +10 02 # bipush 2 # 2 +63 # aadds # &A[2] +10 0C # bipush 12 # 12 +4E # imstore # A[2] = 12; +15 00 # vload 0 # A +10 03 # bipush 3 # 3 +63 # aadds # &A[3] +2E # imload # A[3] +B7 00 00 # invokenative 0 # printint(A[3]) +57 # pop # (ignore result) +15 00 # vload 0 # A +10 02 # bipush 2 # 2 +63 # aadds # &A[2] +2E # imload # A[2] +B7 00 00 # invokenative 0 # printint(A[2]) +57 # pop # (ignore result) +10 00 # bipush 0 # 0 +B0 # return # + +00 01 # native count +# native pool +00 01 00 13 # printint + diff --git a/test/moreArrays.c0.bc0out b/test/moreArrays.c0.bc0out new file mode 100644 index 0000000..9bd1d36 --- /dev/null +++ b/test/moreArrays.c0.bc0out @@ -0,0 +1 @@ +23120 diff --git a/test/moreArrays.c0.c0out b/test/moreArrays.c0.c0out new file mode 100644 index 0000000..9bd1d36 --- /dev/null +++ b/test/moreArrays.c0.c0out @@ -0,0 +1 @@ +23120 diff --git a/test/moreArrays.c0.ex b/test/moreArrays.c0.ex new file mode 100755 index 0000000..dca9ddf Binary files /dev/null and b/test/moreArrays.c0.ex differ diff --git a/test/piazza1.c0 b/test/piazza1.c0 new file mode 100644 index 0000000..f913ca6 --- /dev/null +++ b/test/piazza1.c0 @@ -0,0 +1,22 @@ +struct s +{ + + int x; + int y; + int[] a; + +}; + +int main() +{ + struct s* example=alloc(struct s); + example->y=5; + example->x=6; + int x = example->x + 1; + example->a=alloc_array(int,4); + example->a[0] = 5; + int y = example->a[0]; + example->a[0]=3; + //@assert(\length(example->a)==4); + return example->x + x +y; +} diff --git a/test/piazza1.c0.bc0 b/test/piazza1.c0.bc0 new file mode 100644 index 0000000..d05e12a --- /dev/null +++ b/test/piazza1.c0.bc0 @@ -0,0 +1,70 @@ +C0 C0 FF EE # magic number +00 09 # version 4, arch = 1 (64 bits) + +00 00 # int pool count +# int pool + +00 00 # string pool total size +# string pool + +00 01 # function count +# function_pool + +#
+00 00 # number of arguments = 0 +00 03 # number of local variables = 3 +00 52 # code length = 82 bytes +BB 10 # new 16 # alloc(struct s) +36 00 # vstore 0 # example = alloc(struct s); +15 00 # vload 0 # example +62 04 # aaddf 4 # &example->y +10 05 # bipush 5 # 5 +4E # imstore # example->y = 5; +15 00 # vload 0 # example +62 00 # aaddf 0 # &example->x +10 06 # bipush 6 # 6 +4E # imstore # example->x = 6; +15 00 # vload 0 # example +62 00 # aaddf 0 # &example->x +2E # imload # example->x +10 01 # bipush 1 # 1 +60 # iadd # (example->x + 1) +36 01 # vstore 1 # x = (example->x + 1); +15 00 # vload 0 # example +62 08 # aaddf 8 # &example->a +10 04 # bipush 4 # 4 +BC 04 # newarray 4 # alloc_array(int, 4) +4F # amstore # example->a = alloc_array(int, 4); +15 00 # vload 0 # example +62 08 # aaddf 8 # &example->a +2F # amload # example->a +10 00 # bipush 0 # 0 +63 # aadds # &example->a[0] +10 05 # bipush 5 # 5 +4E # imstore # example->a[0] = 5; +15 00 # vload 0 # example +62 08 # aaddf 8 # &example->a +2F # amload # example->a +10 00 # bipush 0 # 0 +63 # aadds # &example->a[0] +2E # imload # example->a[0] +36 02 # vstore 2 # y = example->a[0]; +15 00 # vload 0 # example +62 08 # aaddf 8 # &example->a +2F # amload # example->a +10 00 # bipush 0 # 0 +63 # aadds # &example->a[0] +10 03 # bipush 3 # 3 +4E # imstore # example->a[0] = 3; +15 00 # vload 0 # example +62 00 # aaddf 0 # &example->x +2E # imload # example->x +15 01 # vload 1 # x +60 # iadd # (example->x + x) +15 02 # vload 2 # y +60 # iadd # ((example->x + x) + y) +B0 # return # + +00 00 # native count +# native pool + diff --git a/test/piazza1.c0.bc0out b/test/piazza1.c0.bc0out new file mode 100644 index 0000000..3c03207 --- /dev/null +++ b/test/piazza1.c0.bc0out @@ -0,0 +1 @@ +18 diff --git a/test/piazza1.c0.c0out b/test/piazza1.c0.c0out new file mode 100644 index 0000000..3c03207 --- /dev/null +++ b/test/piazza1.c0.c0out @@ -0,0 +1 @@ +18 diff --git a/test/piazza1.c0.ex b/test/piazza1.c0.ex new file mode 100755 index 0000000..f4b1ffe Binary files /dev/null and b/test/piazza1.c0.ex differ diff --git a/test/sample2.5.c0 b/test/sample2.5.c0 new file mode 100644 index 0000000..0a6bccb --- /dev/null +++ b/test/sample2.5.c0 @@ -0,0 +1,7 @@ +int main () { + int i; int sum = 0; + for (i = 15; i <= 122; i++) + sum += i; + assert(sum == 0); + return sum; +} diff --git a/test/sample2.5.c0.bc0 b/test/sample2.5.c0.bc0 new file mode 100644 index 0000000..6a97909 --- /dev/null +++ b/test/sample2.5.c0.bc0 @@ -0,0 +1,55 @@ +C0 C0 FF EE # magic number +00 09 # version 4, arch = 1 (64 bits) + +00 00 # int pool count +# int pool + +00 25 # string pool total size +# string pool +73 61 6D 70 6C 65 32 2E 35 2E 63 30 3A 35 2E 32 2D 35 2E 31 39 3A 20 61 73 73 65 72 74 20 66 61 69 6C 65 64 00 # "sample2.5.c0:5.2-5.19: assert failed" + +00 01 # function count +# function_pool + +#
+00 00 # number of arguments = 0 +00 02 # number of local variables = 2 +00 3B # code length = 59 bytes +10 00 # bipush 0 # 0 +36 01 # vstore 1 # sum = 0; +10 0F # bipush 15 # 15 +36 00 # vstore 0 # i = 15; +# <00:loop> +15 00 # vload 0 # i +10 7A # bipush 122 # 122 +A4 00 06 # if_icmple +6 # if (i <= 122) goto <01:body> +A7 00 14 # goto +20 # goto <02:exit> +# <01:body> +15 01 # vload 1 # sum +15 00 # vload 0 # i +60 # iadd # +36 01 # vstore 1 # sum += i; +15 00 # vload 0 # i +10 01 # bipush 1 # 1 +60 # iadd # +36 00 # vstore 0 # i += 1; +A7 FF E8 # goto -24 # goto <00:loop> +# <02:exit> +15 01 # vload 1 # sum +10 00 # bipush 0 # 0 +9F 00 06 # if_cmpeq +6 # if (sum == 0) goto <03:cond_true> +A7 00 08 # goto +8 # goto <04:cond_false> +# <03:cond_true> +10 01 # bipush 1 # true +A7 00 05 # goto +5 # goto <05:cond_end> +# <04:cond_false> +10 00 # bipush 0 # false +# <05:cond_end> +14 00 00 # aldc 0 # s[0] = "sample2.5.c0:5.2-5.19: assert failed" +CF # assert # assert(sum == 0) [failure message on stack] +15 01 # vload 1 # sum +B0 # return # + +00 00 # native count +# native pool + diff --git a/test/sample2.5.c0.bc0out b/test/sample2.5.c0.bc0out new file mode 100644 index 0000000..e69de29 diff --git a/test/sample2.5.c0.c0out b/test/sample2.5.c0.c0out new file mode 100644 index 0000000..e69de29 diff --git a/test/sample2.5.c0.ex b/test/sample2.5.c0.ex new file mode 100755 index 0000000..f3055ed Binary files /dev/null and b/test/sample2.5.c0.ex differ diff --git a/test/strings.c0 b/test/strings.c0 new file mode 100644 index 0000000..ee28a66 --- /dev/null +++ b/test/strings.c0 @@ -0,0 +1,29 @@ +#use +#use + +char char_tolower(char c) { + int ccode = char_ord(c); + if (char_ord('A') <= ccode && ccode <= char_ord('Z')) { + int shift = char_ord('a') - char_ord('A'); + return char_chr(ccode + shift); + } else { + return c; + } +} + +string string_lower(string s) +//@ensures string_length(s) == string_length(\result); +{ + int len = string_length(s); + char[] A = string_to_chararray(s); + char[] B = alloc_array(char, len+1); + for (int i = 0; i < len; i++) + B[i] = char_tolower(A[i]); + B[len] = '\0'; /* redundant */ + return string_from_chararray(B); +} + +int main() { + print (string_lower("HEllo There!?")); + return 0; +} diff --git a/test/strings.c0.bc0 b/test/strings.c0.bc0 new file mode 100644 index 0000000..0b7b6c7 --- /dev/null +++ b/test/strings.c0.bc0 @@ -0,0 +1,118 @@ +C0 C0 FF EE # magic number +00 09 # version 4, arch = 1 (64 bits) + +00 00 # int pool count +# int pool + +00 0E # string pool total size +# string pool +48 45 6C 6C 6F 20 54 68 65 72 65 21 3F 00 # "HEllo There!\?" + +00 03 # function count +# function_pool + +#
+00 00 # number of arguments = 0 +00 05 # number of local variables = 5 +00 0D # code length = 13 bytes +14 00 00 # aldc 0 # s[0] = "HEllo There!\?" +B8 00 02 # invokestatic 2 # string_lower("HEllo There!\?") +B7 00 05 # invokenative 5 # print(string_lower("HEllo There!\?")) +57 # pop # (ignore result) +10 00 # bipush 0 # 0 +B0 # return # + + +# +00 01 # number of arguments = 1 +00 03 # number of local variables = 3 +00 3D # code length = 61 bytes +15 00 # vload 0 # c +B7 00 00 # invokenative 0 # char_ord(c) +36 01 # vstore 1 # ccode = char_ord(c); +10 41 # bipush 65 # 'A' +B7 00 00 # invokenative 0 # char_ord('A') +15 01 # vload 1 # ccode +A4 00 06 # if_icmple +6 # if (char_ord('A') <= ccode) goto <03:and> +A7 00 29 # goto +41 # goto <01:else> +# <03:and> +15 01 # vload 1 # ccode +10 5A # bipush 90 # 'Z' +B7 00 00 # invokenative 0 # char_ord('Z') +A4 00 06 # if_icmple +6 # if (ccode <= char_ord('Z')) goto <00:then> +A7 00 1C # goto +28 # goto <01:else> +# <00:then> +10 61 # bipush 97 # 'a' +B7 00 00 # invokenative 0 # char_ord('a') +10 41 # bipush 65 # 'A' +B7 00 00 # invokenative 0 # char_ord('A') +64 # isub # (char_ord('a') - char_ord('A')) +36 02 # vstore 2 # shift = (char_ord('a') - char_ord('A')); +15 01 # vload 1 # ccode +15 02 # vload 2 # shift +60 # iadd # (ccode + shift) +B7 00 01 # invokenative 1 # char_chr((ccode + shift)) +B0 # return # +A7 00 06 # goto +6 # goto <02:endif> +# <01:else> +15 00 # vload 0 # c +B0 # return # +# <02:endif> + + +# +00 01 # number of arguments = 1 +00 05 # number of local variables = 5 +00 4C # code length = 76 bytes +15 00 # vload 0 # s +B7 00 02 # invokenative 2 # string_length(s) +36 01 # vstore 1 # len = string_length(s); +15 00 # vload 0 # s +B7 00 03 # invokenative 3 # string_to_chararray(s) +36 02 # vstore 2 # A = string_to_chararray(s); +15 01 # vload 1 # len +10 01 # bipush 1 # 1 +60 # iadd # (len + 1) +BC 01 # newarray 1 # alloc_array(char, (len + 1)) +36 03 # vstore 3 # B = alloc_array(char, (len + 1)); +10 00 # bipush 0 # 0 +36 04 # vstore 4 # i = 0; +# <04:loop> +15 04 # vload 4 # i +15 01 # vload 1 # len +A1 00 06 # if_icmplt +6 # if (i < len) goto <05:body> +A7 00 1C # goto +28 # goto <06:exit> +# <05:body> +15 03 # vload 3 # B +15 04 # vload 4 # i +63 # aadds # &B[i] +15 02 # vload 2 # A +15 04 # vload 4 # i +63 # aadds # &A[i] +34 # cmload # A[i] +B8 00 01 # invokestatic 1 # char_tolower(A[i]) +55 # cmstore # B[i] = char_tolower(A[i]); +15 04 # vload 4 # i +10 01 # bipush 1 # 1 +60 # iadd # +36 04 # vstore 4 # i += 1; +A7 FF E0 # goto -32 # goto <04:loop> +# <06:exit> +15 03 # vload 3 # B +15 01 # vload 1 # len +63 # aadds # &B[len] +10 00 # bipush 0 # '\000' +55 # cmstore # B[len] = '\0'; +15 03 # vload 3 # B +B7 00 04 # invokenative 4 # string_from_chararray(B) +B0 # return # + +00 06 # native count +# native pool +00 01 00 51 # char_ord +00 01 00 50 # char_chr +00 01 00 5A # string_length +00 01 00 5D # string_to_chararray +00 01 00 55 # string_from_chararray +00 01 00 10 # print + diff --git a/test/strings.c0.bc0out b/test/strings.c0.bc0out new file mode 100644 index 0000000..ea4ae23 --- /dev/null +++ b/test/strings.c0.bc0out @@ -0,0 +1 @@ +hello there!?0 diff --git a/test/strings.c0.c0out b/test/strings.c0.c0out new file mode 100644 index 0000000..ea4ae23 --- /dev/null +++ b/test/strings.c0.c0out @@ -0,0 +1 @@ +hello there!?0 diff --git a/test/strings.c0.ex b/test/strings.c0.ex new file mode 100755 index 0000000..2ebe489 Binary files /dev/null and b/test/strings.c0.ex differ diff --git a/test/structs.c0 b/test/structs.c0 new file mode 100644 index 0000000..6e25968 --- /dev/null +++ b/test/structs.c0 @@ -0,0 +1,18 @@ +#use + +struct test { + int a; + string b; + int c; +}; + +int main() { + struct test* t = alloc(struct test); + t->a = 1; + t->b = "potato chip"; + t->c = 23; + print(t->b); + printint(t->a); + printint(t->c); + return 0; +} diff --git a/test/structs.c0.bc0 b/test/structs.c0.bc0 new file mode 100644 index 0000000..6183a15 --- /dev/null +++ b/test/structs.c0.bc0 @@ -0,0 +1,54 @@ +C0 C0 FF EE # magic number +00 09 # version 4, arch = 1 (64 bits) + +00 00 # int pool count +# int pool + +00 0C # string pool total size +# string pool +70 6F 74 61 74 6F 20 63 68 69 70 00 # "potato chip" + +00 01 # function count +# function_pool + +#
+00 00 # number of arguments = 0 +00 01 # number of local variables = 1 +00 38 # code length = 56 bytes +BB 18 # new 24 # alloc(struct test) +36 00 # vstore 0 # t = alloc(struct test); +15 00 # vload 0 # t +62 00 # aaddf 0 # &t->a +10 01 # bipush 1 # 1 +4E # imstore # t->a = 1; +15 00 # vload 0 # t +62 08 # aaddf 8 # &t->b +14 00 00 # aldc 0 # s[0] = "potato chip" +4F # amstore # t->b = "potato chip"; +15 00 # vload 0 # t +62 10 # aaddf 16 # &t->c +10 17 # bipush 23 # 23 +4E # imstore # t->c = 23; +15 00 # vload 0 # t +62 08 # aaddf 8 # &t->b +2F # amload # t->b +B7 00 00 # invokenative 0 # print(t->b) +57 # pop # (ignore result) +15 00 # vload 0 # t +62 00 # aaddf 0 # &t->a +2E # imload # t->a +B7 00 01 # invokenative 1 # printint(t->a) +57 # pop # (ignore result) +15 00 # vload 0 # t +62 10 # aaddf 16 # &t->c +2E # imload # t->c +B7 00 01 # invokenative 1 # printint(t->c) +57 # pop # (ignore result) +10 00 # bipush 0 # 0 +B0 # return # + +00 02 # native count +# native pool +00 01 00 10 # print +00 01 00 13 # printint + diff --git a/test/structs.c0.bc0out b/test/structs.c0.bc0out new file mode 100644 index 0000000..62b3dfa --- /dev/null +++ b/test/structs.c0.bc0out @@ -0,0 +1 @@ +potato chip1230 diff --git a/test/structs.c0.c0out b/test/structs.c0.c0out new file mode 100644 index 0000000..62b3dfa --- /dev/null +++ b/test/structs.c0.c0out @@ -0,0 +1 @@ +potato chip1230 diff --git a/test/structs.c0.ex b/test/structs.c0.ex new file mode 100755 index 0000000..617b699 Binary files /dev/null and b/test/structs.c0.ex differ diff --git a/test/swapTest.c0.bc0 b/test/swapTest.c0.bc0 new file mode 100644 index 0000000..de2932c --- /dev/null +++ b/test/swapTest.c0.bc0 @@ -0,0 +1,25 @@ +C0 C0 FF EE # magic number +00 09 # version 4, arch = 1 (64 bits) + +00 00 # int pool count +# int pool + +00 00 # string pool total size +# string pool + +00 01 # function count +# function_pool + +#
+00 00 # number of arguments = 0 +00 00 # number of local variables = 0 +00 07 # code length = 6 bytes +10 FF # bipush -1 # -1 +10 23 +5F +57 +B0 # return # + +00 00 # native count +# native pool + diff --git a/test/testError.c0 b/test/testError.c0 new file mode 100644 index 0000000..6927ce5 --- /dev/null +++ b/test/testError.c0 @@ -0,0 +1,7 @@ +#use + +int main() { + assert(2==2); + print("yolomode"); + return 1; +} diff --git a/test/testError.c0.bc0 b/test/testError.c0.bc0 new file mode 100644 index 0000000..3a5125e --- /dev/null +++ b/test/testError.c0.bc0 @@ -0,0 +1,40 @@ +C0 C0 FF EE # magic number +00 09 # version 4, arch = 1 (64 bits) + +00 00 # int pool count +# int pool + +00 2E # string pool total size +# string pool +74 65 73 74 45 72 72 6F 72 2E 63 30 3A 34 2E 33 2D 34 2E 31 36 3A 20 61 73 73 65 72 74 20 66 61 69 6C 65 64 00 # "testError.c0:4.3-4.16: assert failed" +79 6F 6C 6F 6D 6F 64 65 00 # "yolomode" + +00 01 # function count +# function_pool + +#
+00 00 # number of arguments = 0 +00 00 # number of local variables = 0 +00 1F # code length = 31 bytes +10 02 # bipush 2 # 2 +10 02 # bipush 2 # 2 +9F 00 06 # if_cmpeq +6 # if (2 == 2) goto <00:cond_true> +A7 00 08 # goto +8 # goto <01:cond_false> +# <00:cond_true> +10 01 # bipush 1 # true +A7 00 05 # goto +5 # goto <02:cond_end> +# <01:cond_false> +10 00 # bipush 0 # false +# <02:cond_end> +14 00 00 # aldc 0 # s[0] = "testError.c0:4.3-4.16: assert failed" +CF # assert # assert(2 == 2) [failure message on stack] +14 00 25 # aldc 37 # s[37] = "yolomode" +B7 00 00 # invokenative 0 # print("yolomode") +57 # pop # (ignore result) +10 01 # bipush 1 # 1 +B0 # return # + +00 01 # native count +# native pool +00 01 00 06 # print + diff --git a/test/testError.c0.bc0out b/test/testError.c0.bc0out new file mode 100644 index 0000000..46662a4 --- /dev/null +++ b/test/testError.c0.bc0out @@ -0,0 +1 @@ +yolomode1 diff --git a/test/testError.c0.c0out b/test/testError.c0.c0out new file mode 100644 index 0000000..46662a4 --- /dev/null +++ b/test/testError.c0.c0out @@ -0,0 +1 @@ +yolomode1 diff --git a/test/testError.c0.ex b/test/testError.c0.ex new file mode 100755 index 0000000..590ccef Binary files /dev/null and b/test/testError.c0.ex differ diff --git a/test/testif.c0 b/test/testif.c0 new file mode 100644 index 0000000..173b796 --- /dev/null +++ b/test/testif.c0 @@ -0,0 +1,8 @@ +int main() { + int x = 4; + if (x < 3) + x = 23; + else + x = 32; + return x; +} diff --git a/test/testif.c0.bc0 b/test/testif.c0.bc0 new file mode 100644 index 0000000..578e4be --- /dev/null +++ b/test/testif.c0.bc0 @@ -0,0 +1,36 @@ +C0 C0 FF EE # magic number +00 09 # version 4, arch = 1 (64 bits) + +00 00 # int pool count +# int pool + +00 00 # string pool total size +# string pool + +00 01 # function count +# function_pool + +#
+00 00 # number of arguments = 0 +00 01 # number of local variables = 1 +00 1C # code length = 28 bytes +10 04 # bipush 4 # 4 +36 00 # vstore 0 # x = 4; +15 00 # vload 0 # x +10 03 # bipush 3 # 3 +A1 00 06 # if_icmplt +6 # if (x < 3) goto <00:then> +A7 00 0A # goto +10 # goto <01:else> +# <00:then> +10 17 # bipush 23 # 23 +36 00 # vstore 0 # x = 23; +A7 00 07 # goto +7 # goto <02:endif> +# <01:else> +10 20 # bipush 32 # 32 +36 00 # vstore 0 # x = 32; +# <02:endif> +15 00 # vload 0 # x +B0 # return # + +00 00 # native count +# native pool + diff --git a/test/testif.c0.bc0out b/test/testif.c0.bc0out new file mode 100644 index 0000000..f5c8955 --- /dev/null +++ b/test/testif.c0.bc0out @@ -0,0 +1 @@ +32 diff --git a/test/testif.c0.c0out b/test/testif.c0.c0out new file mode 100644 index 0000000..f5c8955 --- /dev/null +++ b/test/testif.c0.c0out @@ -0,0 +1 @@ +32 diff --git a/test/testif.c0.ex b/test/testif.c0.ex new file mode 100755 index 0000000..10fa75d Binary files /dev/null and b/test/testif.c0.ex differ diff --git a/test/tests.js b/test/tests.js new file mode 100644 index 0000000..9d6a198 --- /dev/null +++ b/test/tests.js @@ -0,0 +1,135 @@ +parser = require("../src/bytecode-parser.js"); +c0vm = require("../src/c0vm.js"); +c0ffi = require("../src/c0ffi.js"); + +var callbacks = {} +var printout = ""; + +callbacks[c0ffi.NATIVE_PRINT] = function(args) { + printout += args[0]; + return 0; +} + +callbacks[c0ffi.NATIVE_PRINTINT] = function(args) { + printout += args[0]; + return 0; +} + +callbacks[c0ffi.NATIVE_PRINTLN] = function(args) { + printout += (args[0] + "\n"); + 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) { + return function(test) { + var result = c0vm.execute(parser.parse(filename), callbacks, false); + test.ok(result == expected_result, + filename + " - did not get expected result " + expected_result + + ", instead got " + result); + test.done(); + } +} + +exports.testIADD = doTest("iadd.c0.bc0", -2); + +exports.testPrint = function(test) { + printout = ""; + var result = c0vm.execute(parser.parse("test.bc0"), callbacks, false); + test.ok(printout == "Hello, world.\nYou don't look so good.\n", + "test.bc0 - Did not print to screen correctly: output was " + printout); + test.done(); +} + +exports.testISHR = doTest("ishr.c0.bc0", -1); + +exports.testISQRT = doTest("isqrt.c0.bc0", 122); + +exports.testMID = doTest("mid.c0.bc0", 155); + +// This one should throw an exception because an assertion fails +exports.testSample25 = function(test) { + test.throws(function () { + c0vm.execute(parser.parse("sample2.5.c0.bc0"), callbacks, false) + }); + test.done(); +} + +exports.testIF = doTest("testif.c0.bc0", 32); + +exports.testDSQUARED = doTest("dsquared.c0.bc0", 17068); + +exports.testArrays = function(test) { + test.throws(function () { + c0vm.execute(parser.parse("arrays.c0.bc0"), callbacks, false) + }); + test.done(); +} + +exports.testMoreArray = function(test) { + printout = ""; + var result = c0vm.execute(parser.parse("moreArrays.c0.bc0"), callbacks, false); + test.ok(printout == "2312", + "moreArrays.c0.bc0 - Did not print to screen correctly, result was " + + printout); + test.done(); +} + +exports.testStructs = function(test) { + printout = ""; + var result = c0vm.execute(parser.parse("structs.c0.bc0"), callbacks, false); + test.ok(printout == "potato chip123", + "structs.c0.bc0 - Did not print to screen correctly, result was " + + printout); + test.done(); +} + +exports.testAbort = function(test) { + test.throws(function () { + c0vm.execute(parser.parse("abort.c0.bc0"), callbacks, false); + }); + test.done(); +} + +exports.testArith = function(test) { + printout = ""; + var result = c0vm.execute(parser.parse("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", + "arith.c0.bc0 - Did not print to screen correctly, result was " + + printout); + test.done(); +} + +exports.testPIAZZA1 = doTest("piazza1.c0.bc0", 18); + +exports.testSTRINGS = function(test) { + printout = ""; + var result = c0vm.execute(parser.parse("strings.c0.bc0"), callbacks, false); + test.ok(printout == "hello there!?", + "strings.c0.bc0 - Did not print to screen correctly, result was " + + printout); + test.done(); +} diff --git a/views/.index.jade.swp b/views/.index.jade.swp deleted file mode 100644 index 8f5d625..0000000 Binary files a/views/.index.jade.swp and /dev/null differ diff --git a/views/index.jade b/views/index.jade index f8bf900..2e1ac1b 100644 --- a/views/index.jade +++ b/views/index.jade @@ -11,22 +11,32 @@ block nav block body .container - .col-md-6 - form - .form-group - label(for="inputCode") Code - button(onclick="compile()" type="button").btn.btn-default.btm-btn.pull-right Compile - #codearea - textarea.code.formControl.sh_c(rows="12" id="inputCode") + .row + .col-md-6 + form + .form-group + label(for="inputCode") Code + button(onclick="compile()" type="button").btn.btn-default.btm-btn.pull-right Compile + #codearea + textarea.code.formControl.sh_c(rows="12" id="inputCode") + + .col-md-6 + p.lbl. + Bytecode + pre#bytecode.panel.panel-default.code.sh_c. +   + .row + .col-md-12 + p.lbl. + Output + button(type="button")#run.btn.btn-default.btm-btn.pull-right Run + pre#output.panel.panel-default.code +   - .col-md-6 - p.lbl. - Bytecode - pre#bytecode.panel.panel-default.code.clearfix.sh_c. -   block script script(type="text/javascript" src="codemirror-compressed.js") + script(type="text/javascript" src="vm/vm.js") script(type='text/javascript'). var cmCodeInput = CodeMirror.fromTextArea($("#inputCode")); @@ -49,4 +59,3 @@ block script jsonpCallback: "callback" }); } -