feat: first pass clean up, code mneumoncis, started second pass

This commit is contained in:
2026-02-23 15:50:03 +01:00
parent 056464d85a
commit b968110397
4 changed files with 61 additions and 53 deletions

View File

@@ -47,9 +47,13 @@ class Assembler:
Main assembly process - coordinates first and second pass. Main assembly process - coordinates first and second pass.
Public API method that CLI will call. Public API method that CLI will call.
""" """
print("[] - Starting First Pass..")
self._first_pass() self._first_pass()
print("Symbol Table After First Pass") print("Symbol Table After First Pass")
print(self.symbol_table.symbols) print(self.symbol_table.symbols)
print("[x] - First Pass Done..")
print("[] - Starting Second Pass..")
self._second_pass()
def _trim_comments_and_whitespace(self, lines: list[str]) -> list[str]: def _trim_comments_and_whitespace(self, lines: list[str]) -> list[str]:
""" """
@@ -79,28 +83,44 @@ class Assembler:
def _first_pass(self) -> None: def _first_pass(self) -> None:
"""Build symbol table with labels""" """Build symbol table with labels"""
parser = Parser(self.cleaned_lines) self.parser = Parser(self.cleaned_lines)
instruction_address = 0 instruction_address = 0
while parser.has_more_commands(): while self.parser.has_more_commands():
parser.advance() # Move to next command self.parser.advance() # Move to next command
print(self.parser.command_type())
cmd_type = parser.command_type() cmd_type = self.parser.command_type()
if cmd_type == CommandType.L_COMMAND: if cmd_type == CommandType.L_COMMAND:
label = parser.symbol() # Extract label name label = self.parser.symbol() # Extract label name
self.symbol_table.add_entry(label, instruction_address) self.symbol_table.add_entry(label, instruction_address)
# Don't increment address # Don't increment address
else: else:
# A-command or C-command # A-command or C-command
instruction_address += 1 instruction_address += 1
self.parser.reset_index()
def _second_pass(self) -> None: def _second_pass(self) -> None:
""" """
Second pass: Translate instructions to binary. Second pass: Translate instructions to binary.
Handles A-commands, C-commands, and resolves symbols. Handles A-commands, C-commands, and resolves symbols.
""" """
raise NotImplementedError("Not implemented") print(self.cleaned_lines)
while self.parser.has_more_commands():
self.parser.advance() # Move to next command
print(self.parser.command_type())
# cmd cmd_type
cmd_type = self.parser.command_type()
if cmd_type == CommandType.L_COMMAND:
continue
elif cmd_type == CommandType.A_COMMAND:
print("....")
# Do A command things
elif cmd_type == CommandType.C_COMMAND:
print("..")
# Do C command Things
def _translate_a_command(self, symbol: str) -> str: def _translate_a_command(self, symbol: str) -> str:
""" """

View File

@@ -19,8 +19,7 @@ class Code:
KeyError: If mnemonic is invalid KeyError: If mnemonic is invalid
""" """
# Use dictionary lookup table # Use dictionary lookup table
print(mnemonic) return DEST_TABLE[mnemonic]
raise NotImplementedError("not implemented")
@staticmethod @staticmethod
def comp(mnemonic: str) -> str: def comp(mnemonic: str) -> str:
@@ -36,9 +35,8 @@ class Code:
Raises: Raises:
KeyError: If mnemonic is invalid KeyError: If mnemonic is invalid
""" """
print(mnemonic)
raise NotImplementedError("not implemented")
# Use dictionary lookup table # Use dictionary lookup table
return COMP_TABLE[mnemonic]
@staticmethod @staticmethod
def jump(mnemonic: str) -> str: def jump(mnemonic: str) -> str:
@@ -54,6 +52,5 @@ class Code:
Raises: Raises:
KeyError: If mnemonic is invalid KeyError: If mnemonic is invalid
""" """
print(mnemonic)
raise NotImplementedError("not implemented")
# Use dictionary lookup table # Use dictionary lookup table
return JUMP_TABLE[mnemonic]

View File

@@ -63,49 +63,42 @@ class Parser:
def symbol(self) -> str: def symbol(self) -> str:
"""Get symbol from A-command or L-command""" """Get symbol from A-command or L-command"""
if self.current_command.startswith("@"): if self.current_command.startswith("@"):
return self.current_command[1:] # @LOOP → LOOP return self.current_command[1:]
elif self.current_command.startswith("("): elif self.current_command.startswith("("):
return self.current_command[1:-1] # (LOOP) → LOOP return self.current_command[1:-1]
return "" return ""
def reset_index(self) -> None:
"""Resset the current index"""
self.current_index = -1
def dest(self) -> str: def dest(self) -> str:
""" """Returns the dest mnemonic in the current C-command."""
Returns the dest mnemonic in the current C-command. if "=" in self.current_command:
# Get everything up to the = sign
Should only be called when command_type () is C_COMMAND. return self.current_command[: self.current_command.index("=")]
else:
Returns: return ""
str: The dest mnemonic (e.g., "M", "MD", "AMD")
Raises:
NotImplementedError: Not yet implemented
"""
raise NotImplementedError("dest not yet implemented")
def comp(self) -> str: def comp(self) -> str:
""" """Returns the comp mnemonic in the current C-command."""
Returns the comp mnemonic in the current C-command. # Start with the full command
comp_part = self.current_command
Should only be called when commandType() is C_COMMAND. # Remove dest part (everything before and including =)
if "=" in comp_part:
comp_part = comp_part[comp_part.index("=") + 1 :]
Returns: # Remove jump part (everything from and including ;)
str: The comp mnemonic (e.g., "D+1", "M-1", "D&A") if ";" in comp_part:
comp_part = comp_part[: comp_part.index(";")]
Raises: return comp_part
NotImplementedError: Not yet implemented
"""
raise NotImplementedError("comp not yet implemented")
def jump(self) -> str: def jump(self) -> str:
""" """Returns the jump mnemonic in the current C-command."""
Returns the jump mnemonic in the current C-command. if ";" in self.current_command:
# Get everything after the ; sign
Should only be called when commandType() is C_COMMAND. return self.current_command[self.current_command.index(";") + 1 :]
else:
Returns: return ""
str: The jump mnemonic (e.g., "JGT", "JEQ", "JMP") or empty string
Raises:
NotImplementedError: Not yet implemented
"""
raise NotImplementedError("jump not yet implemented")

View File

@@ -34,11 +34,9 @@ class SymbolTable:
self.symbols[symbol] = address self.symbols[symbol] = address
def contains(self, symbol: str) -> bool: def contains(self, symbol: str) -> bool:
print(symbol)
raise NotImplementedError("contains not yet implemented")
# Check if symbol exists in dictionary # Check if symbol exists in dictionary
return symbol in self.symbols
def get_address(self, symbol: str) -> int: def get_address(self, symbol: str) -> int:
print(symbol)
raise NotImplementedError("get_address not yet implemented")
# Return address for symbol (raises KeyError if not found) # Return address for symbol (raises KeyError if not found)
return self.symbols[symbol]