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)
Beispiel #3
0
    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
Beispiel #4
0
    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)
Beispiel #5
0
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
Beispiel #7
0
    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
Beispiel #8
0
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))
Beispiel #9
0
def function_seek(context: Context, time: Node):
    context.cursor += Value.eval(context, time)
Beispiel #10
0
def function_withctx(_: Context, ctx: Context, expr: Node):
    return Value.eval(ctx, expr)
Beispiel #11
0
def function_setvar(var: Ref, value):
    var.set(Value.assignment(value))
Beispiel #12
0
 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)
Beispiel #14
0
 def __eval__(self, context):
     return Object([(key, Value.assignment(Value.eval(context.fork(),
                                                      node)))
                    for key, node in self.values])
Beispiel #15
0
    def modify(self, context):
        voice: Voice = context.symbols.lookup(self.voice_name)

        Value.expect(voice, Voice, "Voice modifier " + self.voice_name)

        context.voice = voice