Skip to content

Commit 5aea758

Browse files
committed
Implement most of the compiler
1 parent 9c46c95 commit 5aea758

File tree

10 files changed

+1214
-229
lines changed

10 files changed

+1214
-229
lines changed

assembler.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def next_instruction(self):
8484
instr = self.read_symbol().upper()
8585
whitespace = self.skip_whitespace()
8686
if self.text and self.head not in '\n;' and not whitespace:
87-
self.syntax_error('Expected newline, got %r' % head)
87+
self.syntax_error('Expected newline, got %r' % self.head)
8888
operands = []
8989
if instr in ['CMD', 'TEST']: # special case
9090
operands.append(self.read_at_least_once(lambda c: c != '\n', 'non-newline'))
@@ -130,20 +130,23 @@ def read_ref(self):
130130
return ('symbol', self.read_symbol())
131131

132132
def read_number(self):
133+
mul = -1 if self.head == '-' else 1
134+
if mul == -1: # Read negative sign
135+
self.skip(1)
133136
if self.head == '0':
134137
type = self.peek()
135138
if type == 'x':
136139
self.skip(2)
137-
return int(self.read_at_least_once(chr_is_hex, 'hex char'), 16)
140+
return mul*int(self.read_at_least_once(chr_is_hex, 'hex char'), 16)
138141
elif type == 'b':
139142
self.skip(2)
140-
return int(self.read_at_least_once(chr_is_bin, 'bin char'), 2)
143+
return mul*int(self.read_at_least_once(chr_is_bin, 'bin char'), 2)
141144
elif type == 'o':
142145
self.skip(2)
143-
return int(self.read_at_least_once(chr_is_oct, 'oct char'), 8)
146+
return mul*int(self.read_at_least_once(chr_is_oct, 'oct char'), 8)
144147
# fall through to read as decimal number
145148

146-
return int(self.read_at_least_once(str.isdecimal, 'decimal char'))
149+
return mul*int(self.read_at_least_once(str.isdecimal, 'decimal char'))
147150

148151
def read_string(self):
149152
self.read('"')
@@ -332,6 +335,11 @@ def sub_to_func_name(self, sub_name):
332335
return 'sub_' + sub_name
333336

334337
def handle_local_label(self, name):
338+
if name.startswith('_'):
339+
if name not in ['_setup__']:
340+
raise RuntimeError('Unknown special function name: %r' % name)
341+
self.enter_subroutine('_' + name)
342+
return
335343
func_name = self.local_to_func_name(name)
336344
self.split_to_subsequence(func_name)
337345

@@ -839,6 +847,9 @@ def add_lookup_table(self, session):
839847
session.add_subsequence(prev, table)
840848

841849
def write_to_session(self, session):
850+
setup = self.subroutines.get('__setup__')
851+
if setup is not None:
852+
session.set_setup_hook(setup)
842853
session.load_subroutine_table(self.function_subsequences.keys())
843854
session.load_subroutine_table(self.included_subroutines)
844855
if self.enable_sync:

compiler/asm_extensions.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
from session import Session
2+
from assembler import Assembler
3+
from commands import *
4+
5+
class CompilerSession(Session):
6+
7+
def __init__(self, pos, writer, namespace, page_size=64, **kwargs):
8+
self.page_size = page_size
9+
super(CompilerSession, self).__init__(pos, writer, namespace, **kwargs)
10+
self.scope.variables.update({
11+
'memory_address': 'ma',
12+
'memory_buffer': 'mb',
13+
'memory_slot': ('ms_%d', range(self.page_size))
14+
})
15+
self.add_page()
16+
17+
def add_page(self):
18+
setter = Subsequence()
19+
getter = Subsequence()
20+
dump = ["["]
21+
22+
mbr = Var('memory_buffer')
23+
mar = Var('memory_address')
24+
25+
for i in range(self.page_size):
26+
slot = Var('memory_slot', i)
27+
dump.append(slot)
28+
if i != self.page_size - 1:
29+
dump.append(",")
30+
31+
setter.add_command(OpAssign(slot, mbr).where(SelEquals(mar, i)))
32+
getter.add_command(OpAssign(mbr, slot).where(SelEquals(mar, i)))
33+
34+
self.scope.add_function_names(('mem_set', 'mem_get', 'mem_dump'))
35+
self.add_subsequence('mem_set', setter)
36+
self.add_subsequence('mem_get', getter)
37+
s = Subsequence()
38+
dump.append("]")
39+
s.add_command(Tellraw(dump, 'a'))
40+
self.add_subsequence('mem_dump', s)
41+
42+
def extended_setup(self, up, down):
43+
# temp
44+
up.append(SetConst(Var('stack_pointer'), 0).resolve(self.scope))
45+
for i in range(self.page_size):
46+
slot = Var('memory_slot', i)
47+
up.append(SetConst(slot, 0).resolve(self.scope))
48+
49+
class ExtendedAssembler(Assembler):
50+
51+
def __init__(self):
52+
super(ExtendedAssembler, self).__init__()
53+
self.instructions.update({
54+
'MOVIND': self.handle_mov_ind,
55+
'MOVINDD': self.handle_mov_ind_d,
56+
'MOVINDS': self.handle_mov_ind_s
57+
})
58+
59+
def handle_mov_ind(self, src, s_off, dest, d_off):
60+
"""Move indirect src to indirect dest"""
61+
src, dest = self.get_src_dest(src, dest)
62+
s_off = self.resolve_ref(*s_off)
63+
d_off = self.resolve_ref(*d_off)
64+
assert type(s_off) == int
65+
assert type(d_off) == int
66+
self.add_command(OpAssign(Var('memory_address'), src))
67+
if s_off != 0:
68+
self.add_command(AddConst(Var('memory_address'), s_off))
69+
self.add_command(Function('mem_get'))
70+
self.add_command(OpAssign(Var('memory_address'), dest))
71+
if d_off != 0:
72+
self.add_command(AddConst(Var('memory_address'), d_off))
73+
self.add_command(Function('mem_set'))
74+
75+
def handle_mov_ind_d(self, src, dest, d_off):
76+
"""Move src to indirect dest"""
77+
src, dest = self.get_src_dest(src, dest)
78+
offset = self.resolve_ref(*d_off)
79+
assert type(offset) == int
80+
self.add_command(self.assign_op(Var('memory_buffer'), src))
81+
self.add_command(OpAssign(Var('memory_address'), dest))
82+
if offset != 0:
83+
self.add_command(AddConst(Var('memory_address'), offset))
84+
self.add_command(Function('mem_set'))
85+
86+
def handle_mov_ind_s(self, src, s_off, dest):
87+
"""Move indirect src to dest"""
88+
src, dest = self.get_src_dest(src, dest)
89+
offset = self.resolve_ref(*s_off)
90+
assert type(offset) == int
91+
self.add_command(self.assign_op(Var('memory_address'), src))
92+
if offset != 0:
93+
self.add_command(AddConst(Var('memory_address'), offset))
94+
self.add_command(Function('mem_get'))
95+
self.add_command(OpAssign(dest, Var('memory_buffer')))

0 commit comments

Comments
 (0)