Skip to content

Instantly share code, notes, and snippets.

@mypy-play
Created May 8, 2024 22:19
Show Gist options
  • Save mypy-play/5c7f03f85b2a72631bb5c8f72c152f94 to your computer and use it in GitHub Desktop.
Save mypy-play/5c7f03f85b2a72631bb5c8f72c152f94 to your computer and use it in GitHub Desktop.
Shared via mypy Playground
from __future__ import annotations
from dataclasses import dataclass
import os
from n2t.core.vm_translator.writer import Writer
from n2t.core.vm_translator.vm_parser import INSTRUCTIONS, VmParser
@dataclass
class VmProgram: # TODO: your work for Projects 7 and 8 starts here
file_or_directory_name : str
@classmethod
def load_from(cls, file_or_directory_name: str) -> VmProgram:
return cls(file_or_directory_name)
def translate(self) -> None:
vm_files : list[str] = []
output_file = self.hadle_files(vm_files)
writer = Writer(output_file)
for file in vm_files:
if "Sys.vm" in file: writer.sys_command()
for file in vm_files:
vm_parser = VmParser(file)
writer.change_filename(file)
while vm_parser.has_next():
vm_parser.next()
if vm_parser.instruction_type() == INSTRUCTIONS.ARITHMETIC:
writer.write_arithmetic(vm_parser.arg1())
elif vm_parser.instruction_type() == INSTRUCTIONS.PUSH:
writer.write_push(vm_parser.arg1(), vm_parser.arg2())
elif vm_parser.instruction_type() == INSTRUCTIONS.POP:
writer.write_pop(vm_parser.arg1(), vm_parser.arg2())
elif vm_parser.instruction_type() == INSTRUCTIONS.LABEL:
writer.write_label(vm_parser.arg1())
elif vm_parser.instruction_type() == INSTRUCTIONS.GOTO:
writer.write_goto(vm_parser.arg1())
elif vm_parser.instruction_type() == INSTRUCTIONS.IF:
writer.write_if(vm_parser.arg1())
elif vm_parser.instruction_type() == INSTRUCTIONS.FUNCTION:
writer.write_function(vm_parser.arg1(), vm_parser.arg2())
elif vm_parser.instruction_type() == INSTRUCTIONS.RETURN:
writer.write_return()
elif vm_parser.instruction_type() == INSTRUCTIONS.CALL:
writer.write_call(vm_parser.arg1(), vm_parser.arg2())
writer.close()
def hadle_files (self, vm_files: list[str]) -> str:
components = os.path.normpath(self.file_or_directory_name).split(os.sep)
# file case
if self.file_or_directory_name.endswith(".vm"):
vm_files.append(self.file_or_directory_name)
output_file = ( os.path.dirname(self.file_or_directory_name) + "\\" + components[-2] + ".asm" )
# dir case
else:
output_file = self.file_or_directory_name + "\\" + components[-1] + ".asm"
for root, files in os.walk(self.file_or_directory_name):
for file in files:
if file.endswith(".vm"): vm_files.append(os.path.join(root, file))
return output_file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment