def exec(self, symbols_scope: SymbolsScope, context: Context, *args, **kargs): forked = context.fork(symbols=symbols_scope.fork()) forked.symbols.assign('__callerctx__', context, local=True) for variable_name in self.using: forked.symbols.using(variable_name) for i in range(len(self.arguments)): (name, arg_mod, default_value) = self.arguments[i] argument_node, default_node = None, default_value if len(args) > i: argument_node = args[i] elif name in kargs: argument_node = kargs[name] elif default_value == None: raise Exception(f"Mandatory argument { name } was not given.") if arg_mod == 'expr': forked.symbols.assign(name, argument_node) elif (arg_mod == 'ref' or arg_mod == 'in') and argument_node is not None: is_variable = isinstance(argument_node, VariableExpressionNode) if arg_mod == 'ref' and not is_variable: raise BaseException( f"Only variable references can be passed to a function (function { self.name }, parameter { name })" ) # TODO: Should ref pointers be shallow? Since ref can mutate # the value, it could be sensible for them to be so if is_variable: pointer = context.symbols.pointer(argument_node.name) if pointer is None: context.symbols.assign(argument_node.name, None) else: forked.symbols.using(pointer, name) else: forked.symbols.assign( name, Value.assignment(argument_node.eval(context.fork()))) else: if argument_node is not None: value = Value.assignment(argument_node.eval( context.fork())) else: value = Value.assignment(default_node.eval(forked.fork())) value = forked.symbols.assign(name, value) return self.body.eval(forked)
def values(self, context): for i in Value.eval(context, self.it): forked = context.fork(symbols=context.symbols.fork(opaque=False)) if len(self.variables) == 1: forked.symbols.assign(self.variables[0], i, local=True) else: for k, name in enumerate(self.variables): forked.symbols.assign(name, i[k], local=True) yield Value.eval(forked, self.body) context.join(forked)
def __eval__ ( self, context : Context ): stack_frame : Optional[StackFrame] = context.symbols.lookup( 'stack_frame', container = 'stack' ) if stack_frame is None: raise Exception( "Cannot return here, no stack frame found." ) if self.expression is None: stack_frame.ret() else: val = Value.eval( context, self.expression ) stack_frame.ret( Value.assignment( val ) ) return val
def __eval__(self, context: Context): if self.child is not None: context.symbols.assign('stack_frame', StackFrame(), container='stack') return Value.eval(context, self.child)
def function_debug(context: Context, expr): value = expr.eval(context.fork()) if value is None: print(None) elif isinstance(value, Music): print('<Music> ' + ' '.join(str(event) for event in value.expand(context))) else: print("<%s>%s" % (Value.typeof(value), value))
def __eval__(self, context: Context): val = Value.assignment(self.right.eval(context.fork(cursor=0))) for i, op in enumerate(self.left): if self.operator is None or self.operator == "": op.assign(context, val[i], local=self.local) else: def _set(value): nonlocal val if self.operator == '*': value *= val[i] elif self.operator == '/': value /= val[i] elif self.operator == '+': value += val[i] elif self.operator == '-': value -= val[i] elif self.operator == '&': value &= val[i] elif self.operator == '|': value |= val[i] else: raise Exception("Invalid operator: " + self.operator) return value op.lookup_assign(context, _set, local=self.local) return None
def __eval__(self, context: Context): val = Value.assignment(self.right.eval(context.fork(cursor=0))) if self.operator is None or self.operator == "": self.left.assign(context, val, local=self.local) else: def _set(value): nonlocal val # value = context.symbols.lookup( self.name, recursive = not self.local ) if self.operator == '*': value *= val elif self.operator == '/': value /= val elif self.operator == '+': value += val elif self.operator == '-': value -= val elif self.operator == '&': value &= val elif self.operator == '|': value |= val else: raise Exception("Invalid operator: " + self.operator) return value self.left.lookup_assign(context, _set, local=self.local) return None
def function_eval(context: Context, code, rule: str = None) -> Any: if type(code) is str: code = function_parse(context, code, rule=rule) return Value.assignment(Value.eval(context, code))
def function_seek(context: Context, time: Node): context.cursor += Value.eval(context, time)
def function_withctx(_: Context, ctx: Context, expr: Node): return Value.eval(ctx, expr)
def function_setvar(var: Ref, value): var.set(Value.assignment(value))
def __eval__(self, context): return [ Value.assignment(Value.eval(context.fork(), node)) for node in self.values ]
def assertEval(self, source, value): ast = self.parser.parse(source) result = Value.eval(self.context, ast) self.assertEqual(result, value)
def __eval__(self, context): return Object([(key, Value.assignment(Value.eval(context.fork(), node))) for key, node in self.values])
def modify(self, context): voice: Voice = context.symbols.lookup(self.voice_name) Value.expect(voice, Voice, "Voice modifier " + self.voice_name) context.voice = voice