-
Notifications
You must be signed in to change notification settings - Fork 10
/
api.py
101 lines (80 loc) · 3.4 KB
/
api.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#!/usr/bin/env python
# encoding:utf8
"""
DragonPy - Dragon 32 emulator in Python
=======================================
:created: 2014 by Jens Diemer - www.jensdiemer.de
:copyleft: 2014 by the DragonPy team, see AUTHORS for more details.
:license: GNU GPL v3 or above, see LICENSE for more details.
"""
from dragonlib.core.basic import BasicListing, RenumTool, BasicTokenUtil,\
BasicLine
from dragonlib.core.basic_parser import BASICParser
from dragonlib.dragon32.basic_tokens import DRAGON32_BASIC_TOKENS
from dragonlib.utils.logging_utils import log
DRAGON32 = "Dragon32"
class BaseAPI(object):
RENUM_REGEX = r"""
(?P<statement> GOTO|GOSUB|THEN|ELSE ) (?P<space>\s*) (?P<no>\d+)
|
(?P<on_goto_statement> ON.+?GOTO|ON.+?GOSUB ) (?P<on_goto_space>\s*) (?P<on_goto_no>[\d*,\s*]+)
"""
def __init__(self):
self.listing = BasicListing(self.BASIC_TOKENS)
self.renum_tool = RenumTool(self.RENUM_REGEX)
self.token_util = BasicTokenUtil(self.BASIC_TOKENS)
def program_dump2ascii_lines(self, dump, program_start=None):
"""
convert a memory dump of a tokensized BASIC listing into
ASCII listing list.
"""
if program_start is None:
program_start = self.DEFAULT_PROGRAM_START
return self.listing.program_dump2ascii_lines(dump, program_start)
def ascii_listing2program_dump(self, basic_program_ascii, program_start=None):
"""
convert a ASCII BASIC program listing into tokens.
This tokens list can be used to insert it into the
Emulator RAM.
"""
if program_start is None:
program_start = self.DEFAULT_PROGRAM_START
parser = BASICParser()
parsed_lines = parser.parse(basic_program_ascii)
if not parsed_lines:
log.critical("No parsed lines %s from %s ?!?" % (
repr(parsed_lines), repr(basic_program_ascii)
))
log.info("Parsed BASIC: %s", repr(parsed_lines))
basic_lines = []
for line_no, code_objects in sorted(parsed_lines.items()):
basic_line = BasicLine(self.token_util)
basic_line.code_objects_load(line_no,code_objects)
basic_lines.append(basic_line)
return self.listing.basic_lines2program_dump(basic_lines, program_start)
def pformat_tokens(self, tokens):
"""
format a tokenized BASIC program line. Useful for debugging.
returns a list of formated string lines.
"""
return self.listing.token_util.pformat_tokens(tokens)
def pformat_program_dump(self, program_dump, program_start=None):
"""
format a BASIC program dump. Useful for debugging.
returns a list of formated string lines.
"""
if program_start is None:
program_start = self.DEFAULT_PROGRAM_START
return self.listing.pformat_program_dump(program_dump, program_start)
def renum_ascii_listing(self, content):
return self.renum_tool.renum(content)
class Dragon32API(BaseAPI):
CONFIG_NAME = DRAGON32
MACHINE_NAME = "Dragon 32"
BASIC_TOKENS = DRAGON32_BASIC_TOKENS
PROGRAM_START_ADDR = 0x0019
VARIABLES_START_ADDR = 0x001B
ARRAY_START_ADDR = 0x001D
FREE_SPACE_START_ADDR = 0x001F
# Default memory location of BASIC listing start
DEFAULT_PROGRAM_START = 0x1E01