diff --git a/lang/bytecode.c b/lang/bytecode.c index 647a656..389601d 100644 --- a/lang/bytecode.c +++ b/lang/bytecode.c @@ -18,18 +18,12 @@ // clang-format off static const unsigned char bytecode[] = { - OP_NUM, 0xaa, 0xaa, 0xaa, 0xaa, - OP_NUM, 0xbb, 0xbb, 0xbb, 0xbb, - OP_NUM, 0xcc, 0xcc, 0xcc, 0xcc, - OP_NUM, 0x69, 0x02, 0x00, 0x00, - OP_NULL, - OP_GET, 0x4, - OP_GET, 0x4, - OP_CALL, 0x2, 'A', 'd', 'd', '\0', - OP_DROP, 0x1, - OP_SET, 0x0, - OP_DROP, 0x4, - OP_RET +0x05, 0x05, 0x05, 0x01, 0x6a, 0x02, 0x00, 0x00, 0x07, 0x01, +0x05, 0x06, 0x01, 0x06, 0x01, 0x04, 0x02, 0x41, 0x64, 0x64, +0x00, 0x08, 0x01, 0x07, 0x02, 0x05, 0x01, 0x02, 0x00, 0x00, +0x00, 0x06, 0x02, 0x04, 0x02, 0x4d, 0x69, 0x6e, 0x75, 0x73, +0x00, 0x08, 0x01, 0x07, 0x03, 0x06, 0x03, 0x07, 0x00, 0x08, +0x03, 0x03, }; // clang-format on diff --git a/lang/compile.py b/lang/compile.py index 4673531..aa4353e 100755 --- a/lang/compile.py +++ b/lang/compile.py @@ -321,7 +321,7 @@ def replace_variables(ir, variables): new_ir = [] - var_count = len(variables) + var_count = len(variables) - 1 # Ignore Return new_ir.append(IRAllocate(var_count)) for node in ir: if isinstance(node, IRLoad): @@ -356,6 +356,61 @@ new_ir.append(sub_ir) return new_ir +## Bytecode generation + +def generate_bytecode_function(ir): + bytes = b"" + for node in ir.statements: + if isinstance(node, IRNumber): + bytes += b"\x01" # OP_NUM + bytes += node.number.to_bytes(4, 'little') + elif isinstance(node, IRAllocate): + for i in range(0, node.size): + bytes += b"\x05" # OP_NULL + elif isinstance(node, IRDrop): + bytes += b"\x08" # OP_DROP + bytes += node.size.to_bytes(1) + elif isinstance(node, IRLoad): + index = int(node.variable) + bytes += b"\x06" # OP_GET + bytes += index.to_bytes(1) + elif isinstance(node, IRStore): + index = int(node.variable) + bytes += b"\x07" # OP_SET + bytes += index.to_bytes(1) + elif isinstance(node, IRCall): + bytes += b"\x04" # OP_CALL + bytes += (node.args + 1).to_bytes(1) + bytes += node.name.encode('utf-8') + bytes += b"\x00" # NULL terminator + elif isinstance(node, IRReturn): + bytes += b"\x03" # OP_RET + else: + print("Unknown bytecode node: %s" % (node)) + return None + return bytes + +def generate_c_file(ir): + output = "" + for node in ir: + sub_bytes = None + if isinstance(node, IRFunction): + sub_bytes = generate_bytecode_function(node) + output += "static const unsigned char\n" + output += "bytecode_func_%s [] = {\n" % (node.name) + col = 0 + for b in sub_bytes: + output += "0x%02x, " % (b) + col += 1 + if col == 10: + output += "\n" + col = 0 + output += "\n};" + if sub_bytes is None: + print("Unknown bytecode node: %s" % (node)) + return None + return output + ## Tests code = """ @@ -372,3 +427,5 @@ ir = generate_ir(ast) ir_reg = registers_allocate(ir) print(ir_reg) +bytecode = generate_c_file(ir_reg) +print(bytecode)