Skip to content

Commit

Permalink
[#304] Support custom code emitters.
Browse files Browse the repository at this point in the history
  • Loading branch information
kosarev committed May 23, 2020
1 parent 3d275f9 commit 00aee2e
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 20 deletions.
4 changes: 4 additions & 0 deletions outfmt/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from .binary import BinaryEmitter
from .codeemitter import CodeEmitter
from .tzx import TZX
from .tap import TAP


__all__ = [
'BinaryEmitter',
'CodeEmitter',
'TZX',
'TAP',
]
25 changes: 25 additions & 0 deletions outfmt/binary.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# --------------------------------------------
# KopyLeft (K) 2008
# by Jose M. Rodriguez de la Rosa
#
# This program is licensed under the
# GNU Public License v.3.0
#
# The code emission interface.
# --------------------------------------------

from .codeemitter import CodeEmitter


class BinaryEmitter(CodeEmitter):
""" Writes compiled code as raw binary data.
"""
def emit(self, output_filename, program_name, loader_bytes, entry_point,
program_bytes, aux_bin_blocks, aux_headless_bin_blocks):
""" Emits resulting binary file.
"""
with open(output_filename, 'wb') as f:
f.write(bytearray(program_bytes))
19 changes: 19 additions & 0 deletions outfmt/codeemitter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# --------------------------------------------
# KopyLeft (K) 2008
# by Jose M. Rodriguez de la Rosa
#
# This program is licensed under the
# GNU Public License v.3.0
#
# The code emission interface.
# --------------------------------------------


class CodeEmitter(object):
""" The base code emission interface.
"""

pass
20 changes: 19 additions & 1 deletion outfmt/tzx.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
# --------------------------------------------


class TZX(object):
from .codeemitter import CodeEmitter


class TZX(CodeEmitter):
""" Class to represent tzx data
"""
VERSION_MAJOR = 1
Expand Down Expand Up @@ -131,6 +134,21 @@ def save_program(self, title, bytes, line=32768):
bytes = [self.BLOCK_TYPE_DATA] + [(int(x) & 0xFF) for x in bytes] # & 0xFF truncates to bytes
self.standard_block(bytes)

def emit(self, output_filename, program_name, loader_bytes, entry_point,
program_bytes, aux_bin_blocks, aux_headless_bin_blocks):
""" Emits resulting tape file.
"""
if loader_bytes is not None:
self.save_program('loader', loader_bytes, line=1) # Put line 0 to protect against MERGE

self.save_code(program_name, entry_point, program_bytes)
for name, block in aux_bin_blocks:
self.save_code(name, 0, block)
for block in aux_headless_bin_blocks:
self.standard_block(block)

self.dump(output_filename)


if __name__ == '__main__':
""" Sample test if invoked from command line
Expand Down
1 change: 1 addition & 0 deletions zxb/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@
# the GNU General License
# ----------------------------------------------------------------------

from outfmt import CodeEmitter # noqa
from .zxb import main # noqa
5 changes: 3 additions & 2 deletions zxb/zxb.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def output(memory, ofile=None):
ofile.write('%s\n' % m)


def main(args=None):
def main(args=None, emitter=None):
""" Entry point when executed from command line.
You can use zxb.py as a module with import, and this
function won't be executed.
Expand Down Expand Up @@ -352,7 +352,8 @@ def main(args=None):
fout.close()
asmparse.generate_binary(OPTIONS.outputFileName.value, OPTIONS.output_file_type.value,
binary_files=options.append_binary,
headless_binary_files=options.append_headless_binary)
headless_binary_files=options.append_headless_binary,
emitter=emitter)
if gl.has_errors:
return 5 # Error in assembly

Expand Down
36 changes: 19 additions & 17 deletions zxbasm/asmparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -1467,7 +1467,8 @@ def assemble(input_):
return gl.has_errors


def generate_binary(outputfname, format_, progname='', binary_files=None, headless_binary_files=None):
def generate_binary(outputfname, format_, progname='', binary_files=None, headless_binary_files=None,
emitter=None):
""" Outputs the memory binary to the
output filename using one of the given
formats: tap, tzx or bin
Expand Down Expand Up @@ -1512,23 +1513,24 @@ def generate_binary(outputfname, format_, progname='', binary_files=None, headle
else:
program.add_line([['REM'], ['RANDOMIZE', program.token('USR'), AUTORUN_ADDR]])

if format_ in ('tap', 'tzx'):
t = {'tap': outfmt.TAP, 'tzx': outfmt.TZX}[format_]()

if OPTIONS.use_loader.value:
t.save_program('loader', program.bytes, line=1) # Put line 0 to protect against MERGE

t.save_code(progname, org, binary)
for name, block in bin_blocks:
t.save_code(name, 0, block)
for block in headless_bin_blocks:
t.standard_block(block)

t.dump(outputfname)
if emitter is None:
if format_ in ('tap', 'tzx'):
emitter = {'tap': outfmt.TAP, 'tzx': outfmt.TZX}[format_]()
else:
emitter = outfmt.BinaryEmitter()

else:
with open(outputfname, 'wb') as f:
f.write(bytearray(binary))
loader_bytes = None
if OPTIONS.use_loader.value:
loader_bytes = program.bytes

assert isinstance(emitter, outfmt.CodeEmitter)
emitter.emit(output_filename=outputfname,
program_name=progname,
loader_bytes=loader_bytes,
entry_point=AUTORUN_ADDR,
program_bytes=binary,
aux_bin_blocks=bin_blocks,
aux_headless_bin_blocks=headless_bin_blocks)


def main(argv):
Expand Down

0 comments on commit 00aee2e

Please sign in to comment.