diff --git a/assembler/assembler.py b/assembler/assembler.py index 4d36209..8302f94 100644 --- a/assembler/assembler.py +++ b/assembler/assembler.py @@ -3,7 +3,7 @@ from collections import deque from .context import FileContext from .tokenize import Tokenizer, WHITESPACE from .opcodes import make_opcodes -from .util import can_be_mark, can_convert_to_int, autoint +from .util import can_be_mark, can_convert_to_int, autoint, int16_2_bytes from .directives import SetDirective class ParsingError(Exception): @@ -92,7 +92,14 @@ class Assembler(object): # FIXME: # Make this work for tons of data. # Or is that necessary? - return file_.write(bytes(self._code_objects)) + # TODO: + # Figure out whether/what improovements are necessary here + length = int16_2_bytes(len(self._code_objects)) + if(len(self._code_objects).bit_length() > 16): + raise ValueError("Program size excceeds 2^16.") + file_.write(length) + for word in self._code_objects: + file_.write(int16_2_bytes(word)) def parse_mark(self, token): diff --git a/assembler/util.py b/assembler/util.py index 60d043b..e5d4630 100644 --- a/assembler/util.py +++ b/assembler/util.py @@ -1,6 +1,7 @@ """ Utility functions used for parsing. """ +import struct def can_be_mark(argument): @@ -83,3 +84,11 @@ def autoint(value): return int(value) +def int16_2_bytes(value): + """ + Return the bytes representation of a 16bit unsigned + integer in 8bit words. + """ + if(value < 0): + return struct.pack("