from .sonnum import Sonnum from .activity import Activity 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): 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','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')