Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
59d33d5
Rename to avoid overload
ATherkel May 14, 2024
56929d4
Initial codewriter work
ATherkel May 14, 2024
6b7d18d
Update parser.py
ATherkel May 14, 2024
a919093
Clean up
ATherkel May 15, 2024
db10a76
Clean up
ATherkel May 15, 2024
df7ff27
Test
ATherkel May 15, 2024
9e1f74f
Corrected pointer
ATherkel May 15, 2024
db4e6ed
Simplify
ATherkel May 15, 2024
028a81a
writePushPop work
ATherkel May 15, 2024
7a9707b
Ignore created asm files
ATherkel May 16, 2024
08d80b0
Test with constant
ATherkel May 16, 2024
e8e44c9
Create pushConstant.asm
ATherkel May 16, 2024
d33c54d
Correct pushSegment.asm
ATherkel May 16, 2024
4131992
Update segment in dict.py
ATherkel May 16, 2024
e9fc652
Move class call inside `main`
ATherkel May 16, 2024
2d67dda
Update codewriter.writePushPop
ATherkel May 16, 2024
40ed9bc
Segment handling
ATherkel May 16, 2024
195655b
VMinstruction correction.
ATherkel May 16, 2024
10ed314
VMinstruction correction
ATherkel May 16, 2024
5a5d316
Update writePushPop
ATherkel May 16, 2024
e43f12e
Create arithmetic asm files
ATherkel May 16, 2024
bfe12df
Update VMTranslator
ATherkel May 16, 2024
3a484e7
Update VMTranslator
ATherkel May 16, 2024
9377149
Update codewriter, create processCommands
ATherkel May 16, 2024
ff10599
Update dict.py
ATherkel May 16, 2024
c239eec
Create test_arithmetic.py
ATherkel May 16, 2024
250356d
Update test_arithmetic.py
ATherkel May 16, 2024
bea7c01
Change for Python debugger
ATherkel May 17, 2024
4ae24d8
Python debugger
ATherkel May 17, 2024
d3a9feb
Fix vwriteArithmetic
ATherkel May 17, 2024
582e054
Create test scripts
ATherkel May 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Python Debugger: Current File",
"type": "debugpy",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal",
"cwd": "${workspaceFolder}\\nand2tetris\\projects\\7\\VMTranslator",
"env": {
"PYTHONPATH": "${workspaceFolder}\\nand2tetris\\projects\\7\\VMTranslator"
}
},
{
"name": "Python Debugger: Python File",
"type": "debugpy",
"request": "launch",
"program": "${file}"
}
]
}
1 change: 1 addition & 0 deletions nand2tetris/projects/7/StackArithmetic/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.asm
131 changes: 36 additions & 95 deletions nand2tetris/projects/7/VMTranslator/VMTranslator.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,15 @@
#### ---- import ----
# https://stackoverflow.com/a/37867717/3560695

import importlib.util
import sys
import re

## Import parser
## We have to use import_module since the path contains an illegal directory name (7).
parser_module = importlib.import_module("nand2tetris.projects.7.VMTranslator.src.parser.parser")
Parser = parser_module.parser

writer_module = importlib.import_module("nand2tetris.projects.7.VMTranslator.src.codewriter.codewriter")
codewriter = writer_module.codewriter


# parser_module = importlib.import_module("src.parser.parser")
import src.parser.parser as p

# writer_module = importlib.import_module("src.codewriter.codewriter")
import src.codewriter.codewriter as cw


#### ---- main ----
Expand All @@ -35,113 +30,59 @@ def main(filename):
filename_write = re.sub(regex, r"\1\2.asm", filename)


Parser = p.parser
codewriter = cw.codewriter

with open(filename, 'r') as file, open(filename_write, "w") as file_write:
parser = Parser(file)
writer = codewriter(file_write)

while parser.hasMoreCommands(): ## As long as file has more lines, do:
parser.advance() ## Go to the next line in the file.
parser.getinstruction() ## sets parser.instruction to current instruction
parser.getinstruction()
if not parser.instruction: ## If instruction is blank, skip. Line consisted only of a comment.
continue
print(f"---- Line {parser.lineNo} ----")
print(f"instruction = {parser.instruction}")
print(f"commandType() = {parser.commandType()}")
print(f"arg1() = {parser.arg1()}")
print(f"arg2() = {parser.arg2()}")
parser.getVMinstruction() ## sets parser.VMinstruction to current instruction

# print(f"---- Line {parser.lineNo} ----")
# print(f"instruction = {parser.instruction}")
# print(f"commandType() = {parser.commandType()}, type = {type(parser.commandType())}")
# print(f"arg1() = {parser.arg1()}")
# print(f"arg2() = {parser.arg2()}")


commandType = parser.commandType()
if parser.commandType() == "C_ARITHMETIC":
# Write arithmetic from arithmetic.asm
...
arg1 = parser.arg1()
lines = writer.writeArithmetic(arg1)

elif parser.commandType() in ["C_PUSH", "C_POP"]:
writer.writePushPop(parser.commandType(), parser.arg1(), parser.arg2())
arg1 = parser.arg1()
arg2 = parser.arg2()
lines = writer.writePushPop(commandType, arg1, arg2)
else:
...

## lines is now the full .asm script. Write to output asm file.
file_write.write(f'// {parser.instruction}\n')
for line in lines:
file_write.write(f'{line}\n')





## Testing
filename = '/nand2tetris/projects/7/StackArithmetic/SimpleAdd/SimpleAdd.vm'

main(filename[1:])





## Below is probably redundant





import importlib

## Testing
filename = '.../StackArithmetic/SimpleAdd/SimpleAdd.vm'
filename = '.../StackArithmetic/Stacktest/Stacktest.vm'

# https://chat.openai.com/share/40c7964c-0f2f-44d2-81c7-e88d6a1868a1
def changeExtension(string : str, newExtension : str):
"""
"""
if not isinstance(string, str):
raise TypeError("Input <string> must be a string")
if not isinstance(newExtension, str):
raise TypeError("Input <newExtension> must be a string")

# Regex pattern to capture the base name and extension
# https://regex101.com/r/SkENd5/1
regex = r"^(?P<base>[^.].*\.)(?P<extension>\w+)$|(?P<fullname>^.*$)"

# Replace the extension with the new extension
new_string = re.sub(
regex,
lambda m: (
m.group('base') + newExtension
if m.group('base')
else m.group('fullname')
),
string)

return new_string


def writelines(input_data : str | list, filename) -> None:
"""
Write the given string or list of strings to the specified file.

Args:
input_data (str | list): The string or list of strings to write to the file.
filename (str): The name of the file to write to.

Raises:
TypeError: If input_data is neither a string nor a list, or if filename is not a string.
ValueError: If filename is an empty string.
IOError: If there is an issue writing to the file.

Returns:
None
"""
# Check input types
if not isinstance(input_data, (str, list)):
raise TypeError("Input data must be a string or a list of strings")
if not isinstance(filename, str):
raise TypeError("Filename must be a string")

# Check filename is not empty
if not filename:
raise ValueError("Filename cannot be an empty string")

# Open the file in write mode
try:
with open(filename, 'w') as file:
# Write data to the file
if isinstance(input_data, str):
file.write(input_data)
else:
file.writelines(input_data)
except IOError as e:
raise IOError("Error writing to file: " + str(e))

importlib.reload(p)
importlib.reload(cw)

main(filename[1:])



Expand Down
1 change: 1 addition & 0 deletions nand2tetris/projects/7/VMTranslator/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__package__ = ''
72 changes: 72 additions & 0 deletions nand2tetris/projects/7/VMTranslator/src/Archive/deprecated.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@


# https://chat.openai.com/share/40c7964c-0f2f-44d2-81c7-e88d6a1868a1
def changeExtension(string : str, newExtension : str):
"""
"""
if not isinstance(string, str):
raise TypeError("Input <string> must be a string")
if not isinstance(newExtension, str):
raise TypeError("Input <newExtension> must be a string")

# Regex pattern to capture the base name and extension
# https://regex101.com/r/SkENd5/1
regex = r"^(?P<base>[^.].*\.)(?P<extension>\w+)$|(?P<fullname>^.*$)"

# Replace the extension with the new extension
new_string = re.sub(
regex,
lambda m: (
m.group('base') + newExtension
if m.group('base')
else m.group('fullname')
),
string)

return new_string


def writelines(input_data : str | list, filename) -> None:
"""
Write the given string or list of strings to the specified file.

Args:
input_data (str | list): The string or list of strings to write to the file.
filename (str): The name of the file to write to.

Raises:
TypeError: If input_data is neither a string nor a list, or if filename is not a string.
ValueError: If filename is an empty string.
IOError: If there is an issue writing to the file.

Returns:
None
"""
# Check input types
if not isinstance(input_data, (str, list)):
raise TypeError("Input data must be a string or a list of strings")
if not isinstance(filename, str):
raise TypeError("Filename must be a string")

# Check filename is not empty
if not filename:
raise ValueError("Filename cannot be an empty string")

# Open the file in write mode
try:
with open(filename, 'w') as file:
# Write data to the file
if isinstance(input_data, str):
file.write(input_data)
else:
file.writelines(input_data)
except IOError as e:
raise IOError("Error writing to file: " + str(e))








Loading