161 lines
No EOL
3.6 KiB
Python
161 lines
No EOL
3.6 KiB
Python
from .sonnum import Sonnum
|
|
from .activity import Activity
|
|
|
|
|
|
class SonnumCompiler:
|
|
|
|
def __init__(self):
|
|
|
|
self.sonnum = Sonnum(self) # {order: name}
|
|
self.activities = []
|
|
|
|
def list_activities(self):
|
|
|
|
print('ACTIVITY LISTING')
|
|
for activity in self.activities:
|
|
print(activity)
|
|
|
|
def list_bytecode(self):
|
|
|
|
print('BYTECODE LISTING')
|
|
for activity in self.activities:
|
|
print(list(activity.to_bytes()))
|
|
|
|
def add_activity(self, name, tick_start, tick_end, src_node, trg_node, operands):
|
|
|
|
a = Activity(self.sonnum, name, tick_start, tick_end, src_node, trg_node, operands)
|
|
self.activities.append(a)
|
|
|
|
def transpile_snm_to_py(self, snm_src):
|
|
return snm_src
|
|
|
|
py_src = []
|
|
|
|
for ln in snm_src.split('\n'):
|
|
|
|
tablevel = 0
|
|
|
|
while ln.startswith('\t'):
|
|
|
|
tablevel += 1
|
|
ln = ln[1:]
|
|
|
|
if ln.startswith(';'):
|
|
|
|
if ln.endswith('*'):
|
|
|
|
name = self.sanitize_operand(ln[1:-1])
|
|
ln = f"i_create_simple(self, self.sonnum, '{name}')"
|
|
|
|
elif ln.endswith('!'):
|
|
|
|
ticklen = self.sanitize_operand(ln[1:-1])
|
|
ln = f"i_end_tick(self, self.sonnum, {ticklen})"
|
|
|
|
elif ln.endswith('@'):
|
|
|
|
name = self.sanitize_operand(ln[1:-1])
|
|
ln = f"i_create_relay(self, self.sonnum, '{name}')"
|
|
|
|
elif '=>' in ln:
|
|
name_src, name_trg = ln[1:].split('=>')
|
|
ln = f"i_wire(self, self.sonnum, '{name_src}', '{name_trg}')"
|
|
|
|
elif '->' in ln:
|
|
name_src, name_trg = ln[1:].split('->')
|
|
ln = f"i_air(self, self.sonnum, '{name_src}', '{name_trg}')"
|
|
|
|
else:
|
|
|
|
if '; ' in ln:
|
|
|
|
tickdata, ln = ln[1:].split('; ',1)
|
|
|
|
if '-' in tickdata:
|
|
starttick, endtick = tickdata.split('-', 1)
|
|
else:
|
|
starttick = tickdata
|
|
endtick = starttick
|
|
|
|
starttick = self.sanitize_operand(starttick)
|
|
endtick = self.sanitize_operand(endtick)
|
|
|
|
lst = ln.split(' ')
|
|
src_node_name = lst.pop(0)
|
|
instr = lst.pop(0)
|
|
operands = [self.sanitize_operand(op) for op in lst]
|
|
ln = f"i_{instr}(self, self.sonnum, {starttick}, {endtick}, '{src_node_name}', "+', '.join(operands)+")"
|
|
else:
|
|
pass
|
|
|
|
ln = tablevel*'\t' + ln
|
|
py_src.append(ln)
|
|
|
|
else:
|
|
ln = tablevel*'\t' + ln
|
|
py_src.append(ln)
|
|
|
|
return '\n'.join(py_src)
|
|
|
|
def run_transpiled_code(self, py_src):
|
|
|
|
c = self
|
|
s = self.sonnum
|
|
exec(py_src)
|
|
|
|
def sort_activities(self):
|
|
|
|
new = []
|
|
|
|
to_delete = []
|
|
for activity in self.activities:
|
|
|
|
if activity.name == 'endtick':
|
|
new.append(activity)
|
|
to_delete.append(activity)
|
|
|
|
for activity in to_delete:
|
|
self.activities.remove(activity)
|
|
|
|
to_delete = []
|
|
for activity in self.activities:
|
|
|
|
if activity.name == 'create':
|
|
new.append(activity)
|
|
to_delete.append(activity)
|
|
|
|
for activity in to_delete:
|
|
self.activities.remove(activity)
|
|
|
|
to_delete = []
|
|
for activity in self.activities:
|
|
|
|
if activity.name in ('wire','air'):
|
|
new.append(activity)
|
|
to_delete.append(activity)
|
|
|
|
for activity in to_delete:
|
|
self.activities.remove(activity)
|
|
|
|
self.activities.sort(key=lambda x: x.tick_start, reverse = False)
|
|
new.extend(self.activities)
|
|
self.activities = new
|
|
|
|
def compile_to_smnb(self, snm_src, fn):
|
|
|
|
py_src = self.transpile_snm_to_py(snm_src)
|
|
self.run_transpiled_code(py_src)
|
|
self.sort_activities()
|
|
self.list_activities()
|
|
|
|
bytecode = []
|
|
|
|
for activity in self.activities:
|
|
bytecode.append(activity.to_bytes())
|
|
|
|
with open(fn, 'wb') as fl:
|
|
fl.write(b''.join(bytecode))
|
|
|
|
|
|
#C = SonnumCompiler()
|
|
#snm = C.compile_to_smnb(TEST, '../zigsonnum/test.snmb') |