From 60334da61c4ba13e2594f076953636635b5c3f61 Mon Sep 17 00:00:00 2001 From: aprilnightk Date: Thu, 11 Sep 2025 22:13:28 +0300 Subject: [PATCH] redone compiler --- pysonnum/activity.py | 12 +++++- pysonnum/compiler.py | 28 ++++--------- pysonnum/instruction.py | 77 ----------------------------------- pysonnum/sonnum.py | 90 ++++++++++++++++++++++++++++------------- pysonnum/soundnode.py | 28 +++++++++++++ 5 files changed, 107 insertions(+), 128 deletions(-) delete mode 100644 pysonnum/instruction.py create mode 100644 pysonnum/soundnode.py diff --git a/pysonnum/activity.py b/pysonnum/activity.py index 4fedebd..04f40fd 100644 --- a/pysonnum/activity.py +++ b/pysonnum/activity.py @@ -1,6 +1,16 @@ import struct -from .instruction import OPCODES +OPCODES = { + + 'create': 0, + 'wire': 1, + 'air': 2, + 'endtick': 3, + 'relay': 4, + 'setpos': 5, + 'sine': 6, + } + class Activity: def __repr__(self): diff --git a/pysonnum/compiler.py b/pysonnum/compiler.py index 804faa9..27f3d51 100644 --- a/pysonnum/compiler.py +++ b/pysonnum/compiler.py @@ -1,13 +1,12 @@ from .sonnum import Sonnum from .activity import Activity -from .instruction import * class SonnumCompiler: def __init__(self): - self.sonnum = Sonnum() # {order: name} + self.sonnum = Sonnum(self) # {order: name} self.activities = [] def list_activities(self): @@ -26,19 +25,9 @@ class SonnumCompiler: a = Activity(self.sonnum, name, tick_start, tick_end, src_node, trg_node, operands) self.activities.append(a) - - def sanitize_operand(self, operand): - - if operand.endswith('~sec'): - sec = operand[:-4] - return f'{sec}*44100' - - try: - return str(float(operand)) - except: - return str(operand) - + def transpile_snm_to_py(self, snm_src): + return snm_src py_src = [] @@ -55,7 +44,7 @@ class SonnumCompiler: if ln.endswith('*'): - name = ln[1:-1] + name = self.sanitize_operand(ln[1:-1]) ln = f"i_create_simple(self, self.sonnum, '{name}')" elif ln.endswith('!'): @@ -63,14 +52,9 @@ class SonnumCompiler: ticklen = self.sanitize_operand(ln[1:-1]) ln = f"i_end_tick(self, self.sonnum, {ticklen})" - elif ln.endswith('@@'): - - name = ln[1:-2] - ln = f"i_create_accumulate(self, self.sonnum, '{name}')" - elif ln.endswith('@'): - name = ln[1:-1] + name = self.sanitize_operand(ln[1:-1]) ln = f"i_create_relay(self, self.sonnum, '{name}')" elif '=>' in ln: @@ -115,6 +99,8 @@ class SonnumCompiler: def run_transpiled_code(self, py_src): + c = self + s = self.sonnum exec(py_src) def sort_activities(self): diff --git a/pysonnum/instruction.py b/pysonnum/instruction.py deleted file mode 100644 index 386e80f..0000000 --- a/pysonnum/instruction.py +++ /dev/null @@ -1,77 +0,0 @@ -# Here, s stands for the sonnum object, -# c stands for compiler object - -OPCODES = { - - 'create': 0, - 'wire': 1, - 'air': 2, - 'endtick': 3, - 'relay': 4, - 'setpos': 5, - 'sine': 6, - } - -def i_create_simple(c, s, name): - # ;name* - - node = s.add_node(name) - c.add_activity('create', 0, 0, node, None, []) - -def i_create_relay(c, s, name): - # ;name@ - - node = s.add_node(name) - c.add_activity('create', 0, 0, node, None, []) - c.add_activity('relay', 0, s.g('endtick'), node, None, []) - - -def i_end_tick(c, s, endtick): - # ;endtick! - c.add_activity('endtick', 0, endtick, None, None, []) - s.s('endtick', endtick) - -def i_wire(c, s, src_name, trg_name): - # ;name=>name - - src_node = s.node_by_name(src_name) - trg_node = s.node_by_name(trg_name) - - if src_node and trg_node: - c.add_activity('wire', 0, 0, src_node, trg_node, []) - -def i_air(c, s, src_name, trg_name): - # ;name->name - - src_node = s.node_by_name(src_name) - trg_node = s.node_by_name(trg_name) - - if src_node and trg_node: - c.add_activity('air', 0, 0, src_node, trg_node, []) - -def i_setpos(c, s, start_tick, end_tick, node_name, x, y, z): - - node = s.node_by_name(node_name) - c.add_activity('setpos', start_tick, end_tick, node, None, [x, y, z]) - -def i_sine(c, s, start_tick, end_tick, node_name, freq, r_amp): - - node = s.node_by_name(node_name) - c.add_activity('sine', start_tick, end_tick, node, None, [freq, r_amp]) - -def i_triangle(c, s, start_tick, end_tick, node_name, harmonics_q, freq, r_amp): - - node = s.node_by_name(node_name) - c.add_activity('reset', 0, 0, node, None, []) - - for i in range(0, int(harmonics_q)): - - har_freq = freq*(i*2 + 1) - - if i%2 == 0: - m = 1 - else: - m = -1 - - c.add_activity('setfreq', start_tick, end_tick, node, None, [har_freq, m * r_amp / float((i*2 + 1)**2)]) - \ No newline at end of file diff --git a/pysonnum/sonnum.py b/pysonnum/sonnum.py index 916464a..8742b5a 100644 --- a/pysonnum/sonnum.py +++ b/pysonnum/sonnum.py @@ -1,47 +1,79 @@ -class SoundNode: - - def __init__(self, order, name): - - self.order = order - self.name = name - self.properties = dict() # {k: v} - - def __repr__(self): - return f'{self.order}:{self.name}' - - def g(self, k): - return self.properties.get(k) - - def s(self, k, v): - self.properties[k] = v +from .soundnode import SoundNode class Sonnum: - def __init__(self): + def __init__(self, compiler): - self.nodes = dict() # {order: name} + self.c = compiler + self.nodes = [] # {order: name} self.properties = dict() # {k: v} def add_node(self, name): order = len(self.nodes) - self.nodes[name] = SoundNode(order, name) + node = SoundNode(self, order, name) + self.nodes.append(node) - return self.nodes[name] - - def node_by_name(self, name): - - for order, node in self.nodes.items(): - - if node.name == name: - return node + return node def node_by_order(self, order): - return self.nodes.get(order) + for node in self.nodes: + if node.order == order: + return node def g(self, k): return self.properties.get(k) def s(self, k, v): - self.properties[k] = v \ No newline at end of file + self.properties[k] = v + + def act(self, *args): + self.c.add_activity(*args) + + def node(self): + + node = self.add_node("") + self.act('create', 0, 0, node, None, []) + + return node + + def sec(self, seconds): + return seconds * 44100 + + def relay(self): + + node = self.add_node("") + self.act('create', 0, 0, node, None, []) + self.act('relay', 0, self.g('endtick'), node, None, []) + + return node + + def endtick(self, endtick): + + self.act('endtick', 0, endtick, None, None, []) + self.s('endtick', endtick) + + def wire(self, src_nodes, trg_nodes): + + if not isinstance(src_nodes, list): + src_nodes = [src_nodes] + + if not isinstance(trg_nodes, list): + trg_nodes = [trg_nodes] + + for src_node in src_nodes: + for trg_node in trg_nodes: + self.act('wire', 0, 0, src_node, trg_node, []) + + def air(self, src_nodes, trg_nodes): + + if not isinstance(src_nodes, list): + src_nodes = [src_nodes] + + if not isinstance(trg_nodes, list): + trg_nodes = [trg_nodes] + + for src_node in src_nodes: + for trg_node in trg_nodes: + self.act('air', 0, 0, src_node, trg_node, []) \ No newline at end of file diff --git a/pysonnum/soundnode.py b/pysonnum/soundnode.py new file mode 100644 index 0000000..46f7b0f --- /dev/null +++ b/pysonnum/soundnode.py @@ -0,0 +1,28 @@ +class SoundNode: + + def __init__(self, sonnum, order, name): + + self.order = order + self.s = sonnum + self.c = sonnum.c + self.name = name + self.properties = dict() # {k: v} + + def __repr__(self): + return f'{self.order}:{self.name}' + + def g(self, k): + return self.properties.get(k) + + def s(self, k, v): + self.properties[k] = v + + def act(self, *args): + self.c.add_activity(*args) + + def setpos(self, start_tick, x, y, z): + self.act('setpos', start_tick, start_tick, self, None, [x, y, z]) + + def sine(self, start_tick, end_tick, freq, r_amp): + self.act('sine', start_tick, end_tick, self, None, [freq, r_amp]) + \ No newline at end of file