xipd

programming language for audio processing that compiles to PureData
git clone https://git.ce9e.org/xipd.git

commit
bb9a3a1ca167752c8fc4ed606c940d4a9969e612
parent
607461035b879f00af39c58fedbad4af65dd60c2
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2022-08-26 18:57
resolve include relative to current file

Diffstat

M xipd/renderer.py 25 +++++++++++++++++--------

1 files changed, 17 insertions, 8 deletions


diff --git a/xipd/renderer.py b/xipd/renderer.py

@@ -1,6 +1,14 @@
   -1     1 import os
   -1     2 
    1     3 from .parser import Parser
    2     4 
    3     5 
   -1     6 def abspath(path, start):
   -1     7 	dir = os.path.dirname(start)
   -1     8 	joined = os.path.join(dir, path)
   -1     9 	return os.path.normpath(joined)
   -1    10 
   -1    11 
    4    12 class Scope:
    5    13 	def __init__(self, parent=None):
    6    14 		self.parent = parent
@@ -43,14 +51,14 @@ class Renderer:
   43    51 		self.output += f'#{s};\r\n'
   44    52 
   45    53 	def call(self, name, args, scope):
   46    -1 		params, body, lexical_scope = scope.get_func(name)
   -1    54 		params, body, path, lexical_scope = scope.get_func(name)
   47    55 		if len(args) != len(params):
   48    56 			raise SyntaxError(f'wrong number of argumtnes for function {name}')
   49    57 
   50    58 		subscope = Scope(lexical_scope)
   51    59 		for param, arg in zip(params, args):
   52    60 			subscope.add_ref(param, self.expr_to_ref(arg, scope))
   53    -1 		value = self.render_with_scope(body, subscope)
   -1    61 		value = self.render_with_scope(body, subscope, path)
   54    62 		if value is None:
   55    63 			raise SyntaxError(f'missing return in function {name}')
   56    64 		return value
@@ -86,12 +94,13 @@ class Renderer:
   86    94 		else:
   87    95 			raise SyntaxError('invalid expression', expr)
   88    96 
   89    -1 	def render_with_scope(self, ast, scope):
   -1    97 	def render_with_scope(self, ast, scope, path):
   90    98 		for stmt in ast:
   91    99 			if stmt[0] == 'include':
   92    -1 				with open(stmt[1]) as fh:
   -1   100 				_path = abspath(stmt[1], path)
   -1   101 				with open(_path) as fh:
   93   102 					ast = self.parser.parse_file(fh)
   94    -1 				self.render_with_scope(ast, scope)
   -1   103 				self.render_with_scope(ast, scope, _path)
   95   104 			elif stmt[0] == 'return':
   96   105 				_, expr = stmt
   97   106 				return self.expr_to_ref(expr, scope)
@@ -107,7 +116,7 @@ class Renderer:
  107   116 				scope.add_ref(name, ref)
  108   117 			elif stmt[0] == 'func':
  109   118 				_, name, params, body = stmt
  110    -1 				scope.add_func(name, (params, body))
   -1   119 				scope.add_func(name, (params, body, path))
  111   120 			else:
  112   121 				raise SyntaxError('invalid statement', stmt)
  113   122 
@@ -120,7 +129,7 @@ class Renderer:
  120   129 		self._print('N canvas')
  121   130 		self.render_with_scope([
  122   131 			('assign', '!loadbang', ('raw', 'loadbang'))
  123    -1 		], scope)
  124    -1 		self.render_with_scope(ast, scope)
   -1   132 		], scope, None)
   -1   133 		self.render_with_scope(ast, scope, fh.name)
  125   134 
  126   135 		return self.output