def create_code(file_name, message): """Write the compile code to a class file""" code = ClassFile(file_name.capitalize(), file_name) method_bytecode = b"\x2a\xb7" + struct.pack("!h", code.add_method_to_const_pool("java/lang/Object", "<init>", "()V") ) + b"\xb1" code.add_method(0x0000, "<init>", "()V", 1, 1, method_bytecode) method_bytecode = b"\xb2" + struct.pack("!h", code.add_field_to_const_pool("java/lang/System", "out", "Ljava/io/PrintStream;")) + b"\x12" + struct.pack("B", code.add_string_ref_to_const_pool(message)) + b"\xb6" + struct.pack("!h", code.add_method_to_const_pool("java/io/PrintStream", "println", "(Ljava/lang/String;)V")) + b"\xb1" code.add_method(0x0009, "main", "([Ljava/lang/String;)V", 2, 1, method_bytecode) open(file_name.capitalize() + ".class", "wb").write(code.write_class())
class Compiler: def __init__(self, file_name, functions): self.file_name = file_name.replace(".bas","") self.class_name = self.file_name.capitalize() self.functions = functions self.code = ClassFile(self.class_name, self.file_name) self.method_bytecode = b"" self.vars = {"args": 0}; def parse(self, _fileinput): self.AST = parse_to_AST(_fileinput) self._tree_walker(self.AST) def _tree_walker(self, tree): if type(tree) == list: for node in tree: self._tree_walker(node) if type(tree) == Symbol: for function in self.functions: if function.__name__ == tree.__name__: function(self, tree.what) self._tree_walker(tree.what) def _add_var(self, var_name): if var_name in self.vars: return self.vars[var_name] idx = len(self.vars) self.vars[var_name] = idx return idx def save(self): method_bytecode = b"\x2a\xb7" + struct.pack("!h", self.code.add_method_to_const_pool("java/lang/Object", "<init>", "()V") ) + b"\xb1" self.code.add_method(0x0000, "<init>", "()V", 1, 1, method_bytecode) self.method_bytecode += b"\xb1" # TODO: Keep track of stack size self.code.add_method(0x0009, "main", "([Ljava/lang/String;)V", 100, len(self.vars), self.method_bytecode) open(self.class_name + ".class", "wb").write(self.code.write_class())