Exemplo n.º 1
0
        private static void StartNewSong(Song song, TimeSpan?startPosition)
        {
            lock (_volumeLock)
            {
                if (_volumeController != null)
                {
                    _volumeController.Dispose();
                    _volumeController = null;
                }
            }

            _currentSong = song;

            //We need to start playing from 0, then seek the stream when the topology is ready, otherwise the song doesn't play.
            if (startPosition.HasValue)
            {
                _desiredPosition = PositionVariantFor(startPosition.Value);
            }
            _session.SetTopology(SessionSetTopologyFlags.Immediate, song.Topology);

            StartSession(PositionBeginning);

            // The volume service won't be available until the session topology
            // is ready, so we now need to wait for the event indicating this
        }
        public void ReadWriteNullableVariantWithNull()
        {
            Variant?expected = null;
            var     json     = Serializer.SerializeObject(expected);
            var     result   = Serializer.DeserializeObject <Variant?>(json);

            Assert.Equal(expected, result);
        }
Exemplo n.º 3
0
        private static void OnTopologyReady()
        {
            IntPtr volumeObjectPtr;

            MediaFactory.GetService(_session, MediaServiceKeys.StreamVolume, AudioStreamVolumeGuid, out volumeObjectPtr);
            _volumeController = CppObject.FromPointer <AudioStreamVolume>(volumeObjectPtr);

            SetChannelVolumes();

            if (_desiredPosition.HasValue)
            {
                StartSession(_desiredPosition.Value);
                _desiredPosition = null;
            }
        }
 /// <inheritdoc/>
 public VariantValue Encode(Variant?value, out BuiltInType builtinType)
 {
     if (value == null || value == Variant.Null)
     {
         builtinType = BuiltInType.Null;
         return(VariantValue.Null);
     }
     using (var stream = new MemoryStream()) {
         using (var encoder = new JsonEncoderEx(stream, Context)
         {
             UseAdvancedEncoding = true
         }) {
             encoder.WriteVariant(nameof(value), value.Value);
         }
         var token = Serializer.Parse(stream.ToArray());
         Enum.TryParse((string)token.GetByPath("value.Type"),
                       true, out builtinType);
         return(token.GetByPath("value.Body"));
     }
 }
Exemplo n.º 5
0
 /// <inheritdoc />
 public bool Equals(Variant?other)
 {
     return(ReferenceEquals(this, other));
 }
        /// <summary>
        /// Shows a value in control.
        /// </summary>
        private async Task ShowValue(int index, bool overwrite, object value)
        {
            if (value == null)
            {
                return;
            }

            // show monitored items.
            MonitoredItem monitoredItem = value as MonitoredItem;

            if (monitoredItem != null)
            {
                m_monitoredItem = monitoredItem;
                ShowValue(ref index, ref overwrite, monitoredItem.LastValue.ToString());
                return;
            }

            // show data changes
            MonitoredItemNotification datachange = value as MonitoredItemNotification;

            if (datachange != null)
            {
                ShowValue(ref index, ref overwrite, datachange.Value.ToString());
                return;
            }

            // show events
            EventFieldList eventFields = value as EventFieldList;

            if (eventFields != null)
            {
                for (int ii = 0; ii < eventFields.EventFields.Count; ii++)
                {
                    ShowValue(ref index, ref overwrite, eventFields, ii);
                }

                return;
            }

            // show extension bodies.
            ExtensionObject extension = value as ExtensionObject;

            if (extension != null)
            {
                ShowValue(ref index, ref overwrite, extension.Body.ToString());
                return;
            }

            // show encodeables.
            IEncodeable encodeable = value as IEncodeable;

            if (encodeable != null)
            {
                PropertyInfo[] properties = encodeable.GetType().GetProperties();

                foreach (PropertyInfo property in properties)
                {
                    ShowValue(ref index, ref overwrite, encodeable, property);
                }

                return;
            }

            // show bytes.
            byte[] bytes = value as byte[];

            if (bytes != null)
            {
                bool result = await PromptOnLongList(bytes.Length / 16);

                if (!result)
                {
                    return;
                }

                for (int ii = 0; ii < bytes.Length; ii += 16)
                {
                    ShowValue(ref index, ref overwrite, bytes, ii);
                }

                return;
            }

            // show arrays
            Array array = value as Array;

            if (array != null)
            {
                bool result = await PromptOnLongList(array.Length);

                if (!result)
                {
                    return;
                }

                for (int ii = 0; ii < array.Length; ii++)
                {
                    ShowValue(ref index, ref overwrite, array, ii);
                }

                return;
            }

            // show lists
            IList list = value as IList;

            if (list != null)
            {
                bool result = await PromptOnLongList(list.Count);

                if (!result)
                {
                    return;
                }

                for (int ii = 0; ii < list.Count; ii++)
                {
                    ShowValue(ref index, ref overwrite, list, ii);
                }

                return;
            }

            // show xml elements
            XmlElement xml = value as XmlElement;

            if (xml != null)
            {
                bool result = await PromptOnLongList(xml.ChildNodes.Count);

                if (!result)
                {
                    return;
                }

                for (int ii = 0; ii < xml.ChildNodes.Count; ii++)
                {
                    ShowValue(ref index, ref overwrite, xml, ii);
                }

                return;
            }

            // show data value.
            DataValue datavalue = value as DataValue;

            if (datavalue != null)
            {
                ShowValue(ref index, ref overwrite, datavalue, 0);
                ShowValue(ref index, ref overwrite, datavalue, 1);
                ShowValue(ref index, ref overwrite, datavalue, 2);
                ShowValue(ref index, ref overwrite, datavalue, 3);
                return;
            }

            // show node id value.
            NodeId nodeId = value as NodeId;

            if (nodeId != null)
            {
                ShowValue(ref index, ref overwrite, nodeId, 0);
                ShowValue(ref index, ref overwrite, nodeId, 1);
                ShowValue(ref index, ref overwrite, nodeId, 2);
                return;
            }

            // show expanded node id value.
            ExpandedNodeId expandedNodeId = value as ExpandedNodeId;

            if (expandedNodeId != null)
            {
                ShowValue(ref index, ref overwrite, expandedNodeId, 0);
                ShowValue(ref index, ref overwrite, expandedNodeId, 1);
                ShowValue(ref index, ref overwrite, expandedNodeId, 2);
                ShowValue(ref index, ref overwrite, expandedNodeId, 3);
                return;
            }

            // show qualified name value.
            QualifiedName qualifiedName = value as QualifiedName;

            if (qualifiedName != null)
            {
                ShowValue(ref index, ref overwrite, qualifiedName, 0);
                ShowValue(ref index, ref overwrite, qualifiedName, 1);
                return;
            }

            // show qualified name value.
            LocalizedText localizedText = value as LocalizedText;

            if (localizedText != null)
            {
                ShowValue(ref index, ref overwrite, localizedText, 0);
                ShowValue(ref index, ref overwrite, localizedText, 1);
                return;
            }

            // show variant.
            Variant?variant = value as Variant?;

            if (variant != null)
            {
                ShowValue(ref index, ref overwrite, variant.Value.Value.ToString());
                return;
            }

            // show unknown types as strings.
            ShowValue(ref index, ref overwrite, String.Format("{0}", value));
        }
Exemplo n.º 7
0
        private static void OnTopologyReady()
        {
            IntPtr volumeObjectPtr;
            MediaFactory.GetService(_session, MediaServiceKeys.StreamVolume, AudioStreamVolumeGuid, out volumeObjectPtr);
            _volumeController = CppObject.FromPointer<AudioStreamVolume>(volumeObjectPtr);

            SetChannelVolumes();

            if (_desiredPosition.HasValue)
            {
                StartSession(_desiredPosition.Value);
                _desiredPosition = null;
            }
        }
Exemplo n.º 8
0
        private static void StartNewSong(Song song, TimeSpan? startPosition)
        {
            if (_volumeController != null)
            {
                _volumeController.Dispose();
                _volumeController = null;
            }

            _currentSong = song;

            //We need to start playing from 0, then seek the stream when the topology is ready, otherwise the song doesn't play.
            if (startPosition.HasValue)
                _desiredPosition = PositionVariantFor(startPosition.Value);
            _session.SetTopology(SessionSetTopologyFlags.Immediate, song.Topology);

            StartSession(PositionBeginning);

            // The volume service won't be available until the session topology
            // is ready, so we now need to wait for the event indicating this
        }
Exemplo n.º 9
0
 public void ParseFromVariant(string text, Variant?expected)
 {
     Assert.AreEqual(expected, text.TryParseFromVariant());
 }
Exemplo n.º 10
0
        /// <summary>
        /// Shows a value in control.
        /// </summary>
        private void ShowValue(ref int index, ref bool overwrite, object value)
        {
            if (value == null)
            {
                return;
            }

            // show monitored items.
            MonitoredItem monitoredItem = value as MonitoredItem;

            if (monitoredItem != null)
            {
                m_monitoredItem = monitoredItem;
                ShowValue(ref index, ref overwrite, monitoredItem.LastValue);
                return;
            }

            // show data changes
            MonitoredItemNotification datachange = value as MonitoredItemNotification;

            if (datachange != null)
            {
                ShowValue(ref index, ref overwrite, datachange.Value);
                return;
            }

            // show write value with IndexRange
            WriteValue writevalue = value as WriteValue;

            if (writevalue != null)
            {
                // check if the value is an array
                Array arrayvalue = writevalue.Value.Value as Array;

                if (arrayvalue != null)
                {
                    NumericRange  indexRange;
                    ServiceResult result = NumericRange.Validate(writevalue.IndexRange, out indexRange);

                    if (ServiceResult.IsGood(result) && indexRange != NumericRange.Empty)
                    {
                        for (int ii = 0; ii < arrayvalue.Length; ii++)
                        {
                            bool enabled = ((indexRange.Begin <= ii && indexRange.End >= ii) ||
                                            (indexRange.End < 0 && indexRange.Begin == ii));

                            ShowValue(ref index, ref overwrite, arrayvalue, ii, enabled);
                        }

                        return;
                    }
                }
            }

            // show events
            EventFieldList eventFields = value as EventFieldList;

            if (eventFields != null)
            {
                for (int ii = 0; ii < eventFields.EventFields.Count; ii++)
                {
                    ShowValue(ref index, ref overwrite, eventFields, ii);
                }

                return;
            }

            // show extension bodies.
            ExtensionObject extension = value as ExtensionObject;

            if (extension != null)
            {
                ShowValue(ref index, ref overwrite, extension.Body);
                return;
            }

            // show encodeables.
            IEncodeable encodeable = value as IEncodeable;

            if (encodeable != null)
            {
                PropertyInfo[] properties = encodeable.GetType().GetProperties();

                foreach (PropertyInfo property in properties)
                {
                    ShowValue(ref index, ref overwrite, encodeable, property);
                }

                return;
            }

            // show bytes.
            byte[] bytes = value as byte[];

            if (bytes != null)
            {
                if (!PromptOnLongList(bytes.Length / 16))
                {
                    return;
                }

                for (int ii = 0; ii < bytes.Length; ii += 16)
                {
                    ShowValue(ref index, ref overwrite, bytes, ii);
                }

                return;
            }

            // show arrays
            Array array = value as Array;

            if (array == null)
            {
                Matrix matrix = value as Matrix;

                if (matrix != null)
                {
                    array = matrix.ToArray();
                }
            }

            if (array != null)
            {
                if (!PromptOnLongList(array.GetLength(0)))
                {
                    return;
                }

                for (int ii = 0; ii < array.GetLength(0); ii++)
                {
                    ShowValue(ref index, ref overwrite, array, ii);
                }

                return;
            }

            // show lists
            IList list = value as IList;

            if (list != null)
            {
                if (!PromptOnLongList(list.Count))
                {
                    return;
                }

                for (int ii = 0; ii < list.Count; ii++)
                {
                    ShowValue(ref index, ref overwrite, list, ii);
                }

                return;
            }

            // show xml elements
            XmlElement xml = value as XmlElement;

            if (xml != null)
            {
                if (!PromptOnLongList(xml.ChildNodes.Count))
                {
                    return;
                }

                for (int ii = 0; ii < xml.ChildNodes.Count; ii++)
                {
                    ShowValue(ref index, ref overwrite, xml, ii);
                }

                return;
            }

            // show data value.
            DataValue datavalue = value as DataValue;

            if (datavalue != null)
            {
                ShowValue(ref index, ref overwrite, datavalue, 0);
                ShowValue(ref index, ref overwrite, datavalue, 1);
                ShowValue(ref index, ref overwrite, datavalue, 2);
                ShowValue(ref index, ref overwrite, datavalue, 3);
                return;
            }

            // show node id value.
            NodeId nodeId = value as NodeId;

            if (nodeId != null)
            {
                ShowValue(ref index, ref overwrite, nodeId, 0);
                ShowValue(ref index, ref overwrite, nodeId, 1);
                ShowValue(ref index, ref overwrite, nodeId, 2);
                return;
            }

            // show expanded node id value.
            ExpandedNodeId expandedNodeId = value as ExpandedNodeId;

            if (expandedNodeId != null)
            {
                ShowValue(ref index, ref overwrite, expandedNodeId, 0);
                ShowValue(ref index, ref overwrite, expandedNodeId, 1);
                ShowValue(ref index, ref overwrite, expandedNodeId, 2);
                ShowValue(ref index, ref overwrite, expandedNodeId, 3);
                return;
            }

            // show qualified name value.
            QualifiedName qualifiedName = value as QualifiedName;

            if (qualifiedName != null)
            {
                ShowValue(ref index, ref overwrite, qualifiedName, 0);
                ShowValue(ref index, ref overwrite, qualifiedName, 1);
                return;
            }

            // show qualified name value.
            LocalizedText localizedText = value as LocalizedText;

            if (localizedText != null)
            {
                ShowValue(ref index, ref overwrite, localizedText, 0);
                ShowValue(ref index, ref overwrite, localizedText, 1);
                return;
            }

            // show variant.
            Variant?variant = value as Variant?;

            if (variant != null)
            {
                ShowValue(ref index, ref overwrite, variant.Value.Value);
                return;
            }

            // show unknown types as strings.
            ShowValue(ref index, ref overwrite, String.Format("{0}", value));
        }
Exemplo n.º 11
0
        void recursiveInterpret(FunctionalInterpretationContext interpretationContext, ImmutableNodeReferer node)
        {
            if (!node.isBranch)
            {
                // it's it's own result

                node.interpretationResult = node;
                return;
            }

            // if we are here it must be an branch which must be executable


            // figure out if it is a native function call or a registered function call or a variable

            // if it is a string then this means that it indicates an variablename and not an call
            if (!node.children[0].isBranch && node.children[0].type == ValueNode.EnumType.STRING_DATATYPE && node.children[0].valueString == "string")
            {
                string variableName = getNativeString(node);

                Ensure.ensure(interpretationContext.existsVariableByName(variableName));
                node.interpretationResult = interpretationContext.getVariableByName(variableName);
                return;
            }

            // was the result of the node already set in the node
            // used if we return an nonatomic result
            bool interpretationResultOfNodeIsAlreadySet = false;

            string operationName = getNativeString(node.children[0]);
            bool   isSequence    = operationName == "seq";
            bool   isLet         = operationName == "let";
            bool   isCondition   = operationName == "if";
            bool   isSpecial     = isSequence || isLet || isCondition;
            string callName      = "";

            if (!isSpecial)
            {
                callName = operationName;

                if (
                    isNativeCallValid(callName) ||
                    interpretationContext.publicFnRegistryAndDispatcher.existsFunction(callName)
                    )
                {
                    // nothing by purpose
                }
                else
                {
                    throw new Exception("INTERPRETATIONEXCEPTION name \"" + operationName + "\"is not a native function call or a registered function call or a variable");
                }
            }

            int callId = -1, sequenceId = -1, conditionId = -1; // illegal

            if (isSequence)
            {
                sequenceId = tracer.sequenceEnter(node);
            }
            else if (isLet)
            {
                // nothing by purpose
            }
            else if (isCondition)
            {
                conditionId = tracer.conditionEnter(node);
            }
            else
            {
                Ensure.ensureHard(!isSpecial);
                callId = tracer.callEnter(callName, node);
            }

            // is null if the result initialization is dependent on the callName
            Variant?interpretationResult = null;
            bool    isFirstArgument = true;

            primitiveCalcResultForAdditionalArgumentType primitiveCalcResultForAdditionalArgument = delegate(Variant argument) {
                if (isFirstArgument)
                {
                    isFirstArgument      = false;
                    interpretationResult = argument;
                    return;
                }

                { // scope just for the null mess of interpretationResult
                    Variant interpretationResultTemp = interpretationResult.Value;
                    tryToWidenArithmeticType(ref interpretationResultTemp, argument.type);
                    interpretationResult = interpretationResultTemp;
                }
                Variant castedArgument = hardCastVariantTo(argument, interpretationResult.Value.type);

                if (callName == "+")
                {
                    if (castedArgument.type == Variant.EnumType.FLOAT)
                    {
                        interpretationResult = Variant.makeFloat(interpretationResult.Value.valueFloat + castedArgument.valueFloat);
                    }
                    else if (castedArgument.type == Variant.EnumType.INT)
                    {
                        interpretationResult = Variant.makeInt(interpretationResult.Value.valueInt + castedArgument.valueInt);
                    }
                }
                else if (callName == "-")
                {
                    if (castedArgument.type == Variant.EnumType.FLOAT)
                    {
                        interpretationResult = Variant.makeFloat(interpretationResult.Value.valueFloat - castedArgument.valueFloat);
                    }
                    else if (castedArgument.type == Variant.EnumType.INT)
                    {
                        interpretationResult = Variant.makeInt(interpretationResult.Value.valueInt - castedArgument.valueInt);
                    }
                }
                else if (callName == "*")
                {
                    if (castedArgument.type == Variant.EnumType.FLOAT)
                    {
                        interpretationResult = Variant.makeFloat(interpretationResult.Value.valueFloat * castedArgument.valueFloat);
                    }
                    else if (castedArgument.type == Variant.EnumType.INT)
                    {
                        interpretationResult = Variant.makeInt(interpretationResult.Value.valueInt * castedArgument.valueInt);
                    }
                }
                else if (callName == "/")
                {
                    if (castedArgument.type == Variant.EnumType.FLOAT)
                    {
                        Ensure.ensure(castedArgument.valueFloat != 0.0);
                        interpretationResult = Variant.makeFloat(interpretationResult.Value.valueFloat / castedArgument.valueFloat);
                    }
                    else if (castedArgument.type == Variant.EnumType.INT)
                    {
                        Ensure.ensure(castedArgument.valueInt != 0);
                        interpretationResult = Variant.makeInt(interpretationResult.Value.valueInt / castedArgument.valueInt);
                    }
                }
            };

            if (isLet)
            {
                Ensure.ensure(node.children.Length == 1 + 2); // let and variableAssignmentNode an executionNode
                ImmutableNodeReferer variableAssignmentArrayNode = node.children[1];
                ImmutableNodeReferer executionNode = node.children[2];

                Ensure.ensure(variableAssignmentArrayNode.isBranch);

                Ensure.ensure(variableAssignmentArrayNode.children.Length != 0);
                Ensure.ensure(getNativeString(variableAssignmentArrayNode.children[0]) == "array");

                Ensure.ensure((variableAssignmentArrayNode.children.Length - 1) % 2 == 0); // array minus the array prefix must have a length divisable by two
                int numberOfAssingments = (variableAssignmentArrayNode.children.Length - 1) / 2;
                for (int assigmentI = 0; assigmentI < numberOfAssingments; assigmentI++)
                {
                    string assignmentVariableName       = getNativeString(variableAssignmentArrayNode.children[(1 + assigmentI * 2)]);
                    ImmutableNodeReferer assignmentNode = variableAssignmentArrayNode.children[(1 + assigmentI * 2) + 1];

                    // for it to be calculated
                    recursiveInterpret(interpretationContext, assignmentNode);

                    // try to assign the variable
                    Ensure.ensure(!interpretationContext.existsVariableByName(assignmentVariableName));
                    interpretationContext.assignVariable(assignmentVariableName, assignmentNode.interpretationResult);
                }

                // execute the execution node
                recursiveInterpret(interpretationContext, executionNode);

                // transfer result
                node.interpretationResult = executionNode.interpretationResult;
            }
            else if (isCondition)
            {
                Ensure.ensure(node.children.Length == 1 + 3); // "if" and conditionNode and true tode and false node

                ImmutableNodeReferer conditionNode   = node.children[1];
                ImmutableNodeReferer trueBranchNode  = node.children[2];
                ImmutableNodeReferer falseBranchNode = node.children[3];

                // execute the condition node
                recursiveInterpret(interpretationContext, conditionNode);

                Ensure.ensure(conditionNode.interpretationResult != null);
                Ensure.ensure(!conditionNode.isBranch);
                Ensure.ensure(conditionNode.type == ValueNode.EnumType.VALUE);
                Ensure.ensure(conditionNode.value.type == Variant.EnumType.INT); // int which gets interpreted as bool

                long conditionInt = conditionNode.value.valueInt;
                Ensure.ensure(conditionInt == 0 || conditionInt == 1); // is it a valid boolean value
                bool conditionBool = conditionInt == 1;

                tracer.conditionCondition(conditionId, conditionNode, conditionNode.interpretationResult);
                tracer.conditionPathTaken(conditionId, conditionNode, conditionBool);

                if (conditionBool)
                {
                    recursiveInterpret(interpretationContext, trueBranchNode);
                    node.interpretationResult = trueBranchNode.interpretationResult;
                }
                else
                {
                    recursiveInterpret(interpretationContext, falseBranchNode);
                    node.interpretationResult = falseBranchNode.interpretationResult;
                }
            }
            else
            {
                // force all arguments to be calculated
                for (int argIdx = 0; argIdx < node.children.Length - 1; argIdx++)
                {
                    ImmutableNodeReferer argumentNode = node.children[argIdx + 1];
                    if (isSequence)
                    {
                        tracer.sequenceElement(sequenceId, argumentNode);
                    }
                    recursiveInterpret(interpretationContext, argumentNode);
                }
            }

            if (isSequence)
            {
                tracer.sequenceResult(sequenceId, node.children[node.children.Length - 1].interpretationResult);
                tracer.sequenceExit(sequenceId);
            }
            else if (isCondition)
            {
                tracer.conditionExit(conditionId);
            }
            else if (!isSpecial)
            {
                if (isArithmetic(callName))
                {
                    // process arguments
                    for (int argIdx = 0; argIdx < node.children.Length - 1; argIdx++)
                    {
                        ImmutableNodeReferer argumentValueNode = node.children[argIdx + 1].interpretationResult;

                        primitiveCalcResultForAdditionalArgument(argumentValueNode.value);

                        tracer.callArgument(callId, node.children[argIdx + 1], argumentValueNode, argIdx);
                    }
                }
                else if (isBasicMathFunctionWithOneParameter(callName))
                {
                    Ensure.ensure(node.children.Length == 1 + 1 /* one arguments*/);
                    ImmutableNodeReferer valueNode = node.children[1 + 0].interpretationResult;

                    Ensure.ensure(isCastableTo(valueNode.value, Variant.EnumType.FLOAT));
                    Variant castedValueVariant = hardCastVariantTo(valueNode.value, Variant.EnumType.FLOAT);

                    double resultValue = 0.0;
                    switch (callName)
                    {
                    case "exp":
                        resultValue = Math.Exp(castedValueVariant.valueFloat);
                        break;

                    case "sin":
                        resultValue = Math.Sin(castedValueVariant.valueFloat);
                        break;

                    case "asin":
                        resultValue = Math.Asin(castedValueVariant.valueFloat);
                        break;

                    case "cos":
                        resultValue = Math.Cos(castedValueVariant.valueFloat);
                        break;

                    case "acos":
                        resultValue = Math.Acos(castedValueVariant.valueFloat);
                        break;

                    case "tan":
                        resultValue = Math.Tan(castedValueVariant.valueFloat);
                        break;

                    case "atan":
                        resultValue = Math.Atan(castedValueVariant.valueFloat);
                        break;

                    default:
                        throw new Exception("INTERNALERROR interpreter internal error");
                    }

                    interpretationResult = Variant.makeFloat(resultValue);

                    tracer.callArgument(callId, node.children[1 + 0], valueNode, 0);
                }
                else if (callName == "shl" || callName == "shr" || callName == "bAnd" || callName == "bOr")    // shift
                {
                    Ensure.ensure(node.children.Length == 1 + 2 /* two arguments*/);
                    ImmutableNodeReferer leftNode  = node.children[1 + 0].interpretationResult;
                    ImmutableNodeReferer rightNode = node.children[1 + 1].interpretationResult;
                    long leftValue  = leftNode.value.valueInt;
                    long rightValue = rightNode.value.valueInt;

                    long result = 0;
                    if (callName == "shl")
                    {
                        result = leftValue << (int)rightValue;
                    }
                    else if (callName == "shr")
                    {
                        result = leftValue >> (int)rightValue;
                    }
                    else if (callName == "bAnd")
                    {
                        result = leftValue & rightValue;
                    }
                    else if (callName == "bOr")
                    {
                        result = leftValue | rightValue;
                    }
                    // else should never happen

                    interpretationResult = Variant.makeInt(result);

                    tracer.callArgument(callId, node.children[1 + 0], leftNode, 0);
                    tracer.callArgument(callId, node.children[1 + 1], rightNode, 1);
                }
                else if (interpretationContext.publicFnRegistryAndDispatcher.existsFunction(callName))
                {
                    // a function was invoked

                    IList <ImmutableNodeReferer> invokeParameters = new List <ImmutableNodeReferer>();
                    // collect invoke parameters
                    for (int i = 0; i < node.children.Length - 1; i++)
                    {
                        invokeParameters.Add(node.children[1 + 0].interpretationResult);
                    }

                    ImmutableNodeReferer calleeResult = interpretationContext.publicFnRegistryAndDispatcher.dispatchCall(callName, invokeParameters);

                    node.interpretationResult = calleeResult;
                    interpretationResultOfNodeIsAlreadySet = true;
                }
                else
                {
                    throw new Exception("INTERNALERRROR"); // hard internal error because the case should be handled, because we already made sure that the callName is valid
                }

                if (!interpretationResultOfNodeIsAlreadySet)
                {
                    node.interpretationResult = ImmutableNodeReferer.makeNonbranch(ValueNode.makeAtomic(interpretationResult.Value));
                }

                tracer.callResult(callId, node.interpretationResult);
                tracer.callExit(callId);
            }
        }