204 lines
No EOL
5.1 KiB
Python
204 lines
No EOL
5.1 KiB
Python
from .sonnum import Sonnum
|
|
from .activity import Activity
|
|
from .soundnode import *
|
|
|
|
import random
|
|
|
|
|
|
|
|
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):
|
|
|
|
py_src = []
|
|
|
|
for ln in snm_src.split('\n'):
|
|
|
|
tablevel = 0
|
|
|
|
while ln.startswith('\t'):
|
|
|
|
tablevel += 1
|
|
ln = ln[1:]
|
|
|
|
if ln.startswith(';'):
|
|
|
|
if '=>' in ln:
|
|
|
|
name_src, name_trg = ln[1:].split('=>')
|
|
ln = f'{name_src}.act("link", 0, 0, {name_src}, {name_trg}, [0, 1])'
|
|
|
|
elif '->' in ln:
|
|
|
|
name_src, name_trg = ln[1:].split('->')
|
|
ln = f'{name_src}.act("link", 0, 0, {name_src}, {name_trg}, [0, 2])'
|
|
|
|
elif '=/>' in ln:
|
|
|
|
name_src, name_trg = ln[1:].split('=/>')
|
|
ln = f'{name_src}.act("unlink", 0, 0, {name_src}, {name_trg}, [0, 1])'
|
|
|
|
elif '-/>' in ln:
|
|
|
|
name_src, name_trg = ln[1:].split('-/>')
|
|
ln = f'{name_src}.act("unlink", 0, 0, {name_src}, {name_trg}, [0, 2])'
|
|
|
|
elif '>>' in ln:
|
|
|
|
name_src, name_trg = ln[1:].split('>>')
|
|
name_src, pin_src = name_src.split(':')
|
|
name_trg, pin_trg = name_trg.split(':')
|
|
ln = f'{name_src}.act("link", 0, 0, {name_src}, {name_trg}, [{pin_src}, {pin_trg}])'
|
|
|
|
elif '::>' in ln:
|
|
tickdata, cmd = ln[1:].split(' ',1)
|
|
|
|
if '-' in tickdata:
|
|
starttick, endtick = tickdata.split('-', 1)
|
|
else:
|
|
starttick = tickdata
|
|
endtick = starttick
|
|
name_src, name_trg = cmd.split('::>')
|
|
name_src, pin_src, rangepair_src = name_src.split(':')
|
|
pin_trg, rangepair_trg = name_trg.split(':')
|
|
from_src, from_trg = rangepair_src.split('/')
|
|
to_src, to_trg = rangepair_trg.split('/')
|
|
ln = f'{name_src}.act("rerange", sec({starttick}), sec({endtick}), {name_src}, {name_src}, [{pin_src}, {pin_trg}, {from_src}, {from_trg}, {to_src}, {to_trg}])'
|
|
|
|
elif ':>' in ln:
|
|
tickdata, cmd = ln[1:].split(' ',1)
|
|
|
|
if '-' in tickdata:
|
|
starttick, endtick = tickdata.split('-', 1)
|
|
else:
|
|
starttick = tickdata
|
|
endtick = starttick
|
|
name_src, pin_trg = cmd.split(':>')
|
|
name_src, pin_src = name_src.split(':')
|
|
ln = f'{name_src}.act("copy", sec({starttick}), sec({endtick}), {name_src}, None, [{pin_src}, {pin_trg}])'
|
|
|
|
else:
|
|
|
|
ln = ln[1:]
|
|
tickdata, cmd = ln.split(' ',1)
|
|
|
|
if '-' in tickdata:
|
|
starttick, endtick = tickdata.split('-', 1)
|
|
else:
|
|
starttick = tickdata
|
|
endtick = starttick
|
|
|
|
cmdcore, cmdargs = cmd.split('(', 1)
|
|
cmdargs = cmdargs[:-1]
|
|
|
|
cmdparts = cmdcore.split('.')
|
|
operand = cmdparts.pop(-1)
|
|
nodenames = '.'.join(cmdparts)
|
|
print(operand, nodenames)
|
|
if '>' in nodenames:
|
|
src_nodename, trg_nodename = nodenames.split('>')
|
|
else:
|
|
src_nodename = nodenames
|
|
trg_nodename = nodenames
|
|
|
|
if operand.startswith('@'):
|
|
operand = operand[1:]
|
|
ln = f'{src_nodename}.{operand}(sec({starttick}), sec({endtick}), [{cmdargs}])'
|
|
|
|
else:
|
|
ln = f'{src_nodename}.act("{operand}", sec({starttick}), sec({endtick}), {src_nodename}, {trg_nodename}, [{cmdargs}])'
|
|
|
|
ln = tablevel*'\t' + ln
|
|
py_src.append(ln)
|
|
|
|
else:
|
|
ln = tablevel*'\t' + ln
|
|
py_src.append(ln)
|
|
|
|
print('\n'.join(py_src))
|
|
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','pin'):
|
|
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') |