Example #1
0
        private static void setVariableInScope(
            string variablename,
            EnumOverwriteExistingVariable overwriteExistingVariable,
            Datastructures.Variadic value,
            InterpretationState.ScopeLevel topScope
            )
        {
            int foundVariableIndex;
            int i;

            foundVariableIndex = -1;

            for( i = 0; i < topScope.variables.Count; i++ )
            {
                if( topScope.variables[i].name == variablename )
                {
                    foundVariableIndex = i;
                    break;
                }
            }

            if( foundVariableIndex != -1 )
            {
                if( overwriteExistingVariable == EnumOverwriteExistingVariable.NO )
                {
                    // variable allready existed, but can't be overwritten
                    throw new Exception("variable " + variablename + " exists in scope but can't be overwritten!");
                }

                topScope.variables[foundVariableIndex].value = value;
            }
            else
            {
                InterpretationState.ScopeLevel.Variable newVariable;

                newVariable = new InterpretationState.ScopeLevel.Variable();
                newVariable.name = variablename;
                newVariable.value = value;

                topScope.variables.Add(newVariable);
            }
        }
Example #2
0
 private static void returnResult(InterpretationState state, Datastructures.Variadic result)
 {
     System.Diagnostics.Debug.Assert(state.scopeLevels.Count >= 1);
     if (state.scopeLevels.Count == 1)
     {
         state.result = result;
     }
     else
     {
         state.scopeLevels[state.currentScopeLevel - 1].calleeResult = result;
     }
 }
Example #3
0
        /**
         *
         * returns the value of the dag element as the result
         *
         */
        private static void returnValue(ProgramRepresentation.DagElementData dagElementData, InterpretationState state)
        {
            Datastructures.Variadic resultValue;

            if( dagElementData.type == DagElementData.EnumType.CONSTINT )
            {
                resultValue = new Datastructures.Variadic(Datastructures.Variadic.EnumType.INT);
                resultValue.valueInt = dagElementData.valueInt;
            }
            else if( dagElementData.type == DagElementData.EnumType.CONSTFLOAT )
            {
                resultValue = new Datastructures.Variadic(Datastructures.Variadic.EnumType.FLOAT);
                resultValue.valueFloat = dagElementData.valueFloat;
            }
            else if( dagElementData.type == DagElementData.EnumType.CONSTBOOL )
            {
                resultValue = new Datastructures.Variadic(Datastructures.Variadic.EnumType.BOOL);
                resultValue.valueBool = dagElementData.valueBool;
            }
            else
            {
                // also TODO< handling for other types >
                throw new Exception("Internal Error");
            }

            returnResult(state, resultValue);
            removeTopScope(state);
        }
Example #4
0
        /**
         *
         * only resolves variables and gets the value of constants etc
         * doesn't execute any invokes/function calls
         *
         */
        private static Datastructures.Variadic resolveVariableAndConstant(Datastructures.Dag<ProgramRepresentation.DagElementData> dag, int dagIndexOfVariablesOrConstant, InterpretationState state)
        {
            Datastructures.Dag<ProgramRepresentation.DagElementData>.Element dagElement;

            dagElement = dag.elements[dagIndexOfVariablesOrConstant];

            if( dagElement.content.type == DagElementData.EnumType.IDENTIFIERNAME )
            {
                bool wasResolved;
                Datastructures.Variadic resultVariable;

                // it is a identifier (variable or a placeholder)
                // try to search it and return the value
                resultVariable = resolveVariable(dagElement.content.identifier, state, out wasResolved);
                if( !wasResolved )
                {
                    throw new Exception("variable " + dagElement.content.identifier + " could not be resolved!");
                }

                return resultVariable;
            }
            else if( dagElement.content.type == DagElementData.EnumType.CONSTSTRING )
            {
                // TODO
                System.Diagnostics.Debug.Assert(false, "TODO");

                return null;
            }
            else if( dagElement.content.type == DagElementData.EnumType.CONSTINT )
            {
                Datastructures.Variadic resultVariadic;

                resultVariadic = new Datastructures.Variadic(Datastructures.Variadic.EnumType.INT);
                resultVariadic.valueInt = dagElement.content.valueInt;

                return resultVariadic;
            }
            else if( dagElement.content.type == DagElementData.EnumType.FARRAY )
            {
                Datastructures.Variadic resultVariadic;

                resultVariadic = new Datastructures.Variadic(Datastructures.Variadic.EnumType.ARRAY);
                resultVariadic.valueArray = resolveVariablesAndConstants(dag, dagElement.childIndices, state);

                return resultVariadic;
            }
            // TODO< const float >
            else
            {
                System.Diagnostics.Debug.Assert(false, "TODO");
                throw new Exception("internal error");
            }
        }
Example #5
0
        private static List<Datastructures.Variadic> resolveVariablesAndConstants(Datastructures.Dag<ProgramRepresentation.DagElementData> dag, List<int> dagIndicesOfVariablesOrConstants, InterpretationState state)
        {
            List<Datastructures.Variadic> result;

            result = new List<Datastructures.Variadic>();

            foreach( int iterationDagIndexOfVariableOrConstant in dagIndicesOfVariablesOrConstants )
            {
                result.Add(resolveVariableAndConstant(dag, iterationDagIndexOfVariableOrConstant, state));
            }

            return result;
        }
Example #6
0
        private void executeForeach(Datastructures.Dag<ProgramRepresentation.DagElementData> dag, InterpretationState state)
        {
            int currentDagElementIndex;
            Datastructures.Dag<ProgramRepresentation.DagElementData>.Element currentDagElement;

            InterpretationState.ScopeLevel topScope;

            int dagIndexForIteratorScope;

            currentDagElementIndex = state.scopeLevels[state.scopeLevels.Count - 1].dagElementIndex;
            currentDagElement = dag.elements[currentDagElementIndex];

            topScope = state.scopeLevels[state.currentScopeLevel];

            if( topScope.foreachState == InterpretationState.ScopeLevel.EnumForeachState.INITIAL )
            {
                // dag index for the array to iterate over or for a variable which holds the array
                int dagIndexForArgument;

                // check if number of parameters is two
                if( currentDagElement.childIndices.Count != 2 )
                {
                    throw new Exception("foreach: must take two arguments!");
                }

                dagIndexForIteratorScope = currentDagElement.childIndices[0];
                dagIndexForArgument = currentDagElement.childIndices[1];

                // check if first parameter is a scope
                if( dag.elements[dagIndexForIteratorScope].content.type != DagElementData.EnumType.FSCOPE )
                {
                    throw new Exception("first parameter must be a scope!");
                }

                // setup
                topScope.foreachResultArray = new List<Datastructures.Variadic>();

                // check if second parameter is
                // * a array
                // * a scope
                // * a variable
                // TODO< if not, check if it is a scope, call the scope, check if it is a array >
                //     < if it is a variable, retrive the variable and check if it is an array, if not, throw something
                if( dag.elements[dagIndexForArgument].content.type == DagElementData.EnumType.FARRAY )
                {
                    List<int> dagIndicesOfContentOfArray;

                    // retrive and resolve array

                    dagIndicesOfContentOfArray = dag.elements[dagIndexForArgument].childIndices;
                    topScope.foreachArray = resolveVariablesAndConstants(dag, dagIndicesOfContentOfArray, state);

                    topScope.foreachState = InterpretationState.ScopeLevel.EnumForeachState.ITERATENEXT;

                    // no return
                }
                else if( dag.elements[dagIndexForArgument].content.type == DagElementData.EnumType.FSCOPE )
                {
                    InterpretationState.ScopeLevel createdScopeLevel;
                    int dagIndexOfCalled;

                    // it is a scope
                    topScope.foreachState = InterpretationState.ScopeLevel.EnumForeachState.SCOPEFORARRAYWASINVOKED;

                    // setup the scope
                    createdScopeLevel = new InterpretationState.ScopeLevel();
                    state.scopeLevels.Add(createdScopeLevel);

                    dagIndexOfCalled = dagIndexForArgument;
                    createdScopeLevel.dagElementIndex = dagIndexOfCalled;

                    // misc

                    // do this so the next step executes the scope
                    state.currentScopeLevel++;

                    return;
                }
                else if( dag.elements[dagIndexForArgument].content.type == DagElementData.EnumType.IDENTIFIERNAME )
                {
                    // it is a variable

                    System.Diagnostics.Debug.Assert(false, "TODO");
                }
                else
                {
                    throw new Exception("foreach: second parameter must be a array or a scope or a variable which holds an array!");
                }
            }
            else if( topScope.foreachState == InterpretationState.ScopeLevel.EnumForeachState.SCOPEFORARRAYWASINVOKED )
            {

                // scope for the array to iterate over was invoked

                // * check if result from scope is an array
                // * set array
                // * set state so it iterates over the array as usual

                if( topScope.calleeResult.type != Datastructures.Variadic.EnumType.ARRAY )
                {
                    throw new Exception("foreach  result from scope for variable must be an array");
                }

                topScope.foreachArray = topScope.calleeResult.valueArray;

                topScope.foreachState = InterpretationState.ScopeLevel.EnumForeachState.ITERATENEXT;

                // no return
            }

            // when w are here the state can either be
            // * ITERATENEXT
            //   we need to try to fetch the next item and feed it into the scope
            // * ITERATESTORE
            //   we need to retrive the result of the called scope and append it to the result array

            if( topScope.foreachState == InterpretationState.ScopeLevel.EnumForeachState.ITERATENEXT )
            {
                Datastructures.Variadic currentIterationValue;
                InterpretationState.ScopeLevel createdScopeLevel;
                int dagIndexOfCalled;

                dagIndexForIteratorScope = currentDagElement.childIndices[0];

                // * check if we are at the end of the array
                //   if so -> return result array
                // * fetch value
                // * build scope
                // * set variable "element"

                // check if we are the end
                System.Diagnostics.Debug.Assert(topScope.foreachIndexInArray <= topScope.foreachArray.Count);
                if (topScope.foreachIndexInArray == topScope.foreachArray.Count)
                {
                    Datastructures.Variadic resultValue;

                    resultValue = new Datastructures.Variadic(Datastructures.Variadic.EnumType.ARRAY);
                    resultValue.valueArray = topScope.foreachResultArray;

                    returnResult(state, resultValue);

                    // remove scope of call
                    removeTopScope(state);

                    return;
                }

                // fetch value
                currentIterationValue = topScope.foreachArray[topScope.foreachIndexInArray];

                // build scope

                createdScopeLevel = new InterpretationState.ScopeLevel();
                state.scopeLevels.Add(createdScopeLevel);

                dagIndexOfCalled = dagIndexForIteratorScope;
                createdScopeLevel.dagElementIndex = dagIndexOfCalled;

                // set variables
                createdScopeLevel.variables.Add(new InterpretationState.ScopeLevel.Variable());
                createdScopeLevel.variables.Add(new InterpretationState.ScopeLevel.Variable());
                createdScopeLevel.variables[0].name = "element";
                createdScopeLevel.variables[0].value = currentIterationValue;
                createdScopeLevel.variables[1].name = "index";
                createdScopeLevel.variables[1].value = new Datastructures.Variadic(Datastructures.Variadic.EnumType.INT);
                createdScopeLevel.variables[1].value.valueInt = topScope.foreachIndexInArray;

                // misc
                // do this so the next step executes the scope
                state.currentScopeLevel++;

                // misc
                topScope.foreachIndexInArray++;

                // state must be different
                topScope.foreachState = InterpretationState.ScopeLevel.EnumForeachState.ITERATESTORE;

                return;
            }
            else if( topScope.foreachState == InterpretationState.ScopeLevel.EnumForeachState.ITERATESTORE )
            {
                topScope.foreachResultArray.Add(topScope.calleeResult.deepCopy());

                topScope.foreachState = InterpretationState.ScopeLevel.EnumForeachState.ITERATENEXT;

                return;
            }
            else
            {
                throw new Exception("Internal Error!");
            }

            System.Diagnostics.Debug.Assert(false);
            throw new Exception("unreachable");
        }
Example #7
0
        private void executePass(Datastructures.Dag<ProgramRepresentation.DagElementData> dag, InterpretationState state)
        {
            int currentDagElementIndex;
            Datastructures.Dag<ProgramRepresentation.DagElementData>.Element currentDagElement;

            InterpretationState.ScopeLevel topScope;

            currentDagElementIndex = state.scopeLevels[state.scopeLevels.Count - 1].dagElementIndex;
            currentDagElement = dag.elements[currentDagElementIndex];

            topScope = state.scopeLevels[state.currentScopeLevel];

            if( currentDagElement.childIndices.Count != 1 )
            {
                throw new Exception("pass invalid number of arguments!");
            }

            if( topScope.passState == InterpretationState.ScopeLevel.EnumPassState.INITIAL )
            {
                InterpretationState.ScopeLevel createdScopeLevel;
                int dagIndexOfCalled;

                createdScopeLevel = new InterpretationState.ScopeLevel();
                state.scopeLevels.Add(createdScopeLevel);

                dagIndexOfCalled = currentDagElement.childIndices[0];
                createdScopeLevel.dagElementIndex = dagIndexOfCalled;

                // misc
                // do this so the next step executes the scope
                state.currentScopeLevel++;

                topScope.passState = InterpretationState.ScopeLevel.EnumPassState.RETURNRESULT;
            }
            else if( topScope.passState == InterpretationState.ScopeLevel.EnumPassState.RETURNRESULT )
            {
                returnResult(state, topScope.calleeResult);

                // remove scope of call
                removeTopScope(state);
            }
            else
            {
                throw new Exception("Internal Error");
            }
        }
Example #8
0
 private static bool isTopScopeATerminator(InterpretationState state)
 {
     System.Diagnostics.Debug.Assert(state.scopeLevels.Count >= 1);
     return state.scopeLevels[state.scopeLevels.Count - 1].isTerminator;
 }
Example #9
0
        private static void lookupInvokePath(InterpretationState state, List<string> pathOfInvokedProgram, out bool isInterpretableInvoke, out int dagIndexOfInvokedScope, List<string> variableNames)
        {
            isInterpretableInvoke = false;
            dagIndexOfInvokedScope = -1;

            foreach( InterpretationState.InvokableProgram iterationInvokableProgram in state.invokablePrograms )
            {
                bool pathIsTheSame;

                pathIsTheSame = isStringArrayTheSame(pathOfInvokedProgram, iterationInvokableProgram.path);
                if( !pathIsTheSame )
                {
                    continue;
                }

                dagIndexOfInvokedScope = iterationInvokableProgram.dagIndex;

                variableNames = iterationInvokableProgram.variableNames;

                isInterpretableInvoke = true;
                return;
            }
        }
Example #10
0
        private static void executeReturnVariable(Datastructures.Dag<ProgramRepresentation.DagElementData> dag, InterpretationState state)
        {
            int currentDagElementIndex;
            Datastructures.Dag<ProgramRepresentation.DagElementData>.Element currentDagElement;

            InterpretationState.ScopeLevel topScope;
            bool variableWasResolved;
            Datastructures.Variadic resolvedVariable;

            currentDagElementIndex = state.scopeLevels[state.scopeLevels.Count - 1].dagElementIndex;
            currentDagElement = dag.elements[currentDagElementIndex];

            topScope = state.scopeLevels[state.currentScopeLevel];

            if( currentDagElement.content.type != DagElementData.EnumType.IDENTIFIERNAME )
            {
                // type must be an identifier
                throw new Exception("Internal Error");
            }

            // look the identifier up
            resolvedVariable = resolveVariable(currentDagElement.content.identifier, state, out variableWasResolved);
            if( !variableWasResolved )
            {
                throw new Exception("Variable \"" + currentDagElement.content.identifier + "\" could not be resolved.");
            }

            // return variable
            returnResult(state, resolvedVariable);

            // remove scope of call
            removeTopScope(state);

            return;
        }
Example #11
0
        /**
         *
         * builds the path for a invoke scope command, executes eventually called functions etc
         *
         */
        private static List<string> getPathOfInvokeScopeInstruction(Datastructures.Dag<ProgramRepresentation.DagElementData> dag, List<int> dagIndicesOfPathElements, InterpretationState state)
        {
            List<string> result;

            result = new List<string>();

            foreach( int iterationDagIndex in dagIndicesOfPathElements )
            {
                Datastructures.Dag<ProgramRepresentation.DagElementData>.Element iterationDagElement;

                iterationDagElement = dag.elements[iterationDagIndex];

                if( iterationDagElement.content.type == DagElementData.EnumType.CONSTSTRING )
                {
                    result.Add(iterationDagElement.content.valueString);
                }
                else
                {
                    // TODO< only strings are until now implemented
                    //       later we need to support any operations >

                    throw new Exception("Internal Error");
                }
            }

            return result;
        }
Example #12
0
        private void executeSimpleMathOperation(Datastructures.Dag<ProgramRepresentation.DagElementData> dag, InterpretationState state, Parser.Functional.ScopeParseTreeElement.EnumType type)
        {
            int currentDagElementIndex;
            Datastructures.Dag<ProgramRepresentation.DagElementData>.Element currentDagElement;

            InterpretationState.ScopeLevel topScope;

            currentDagElementIndex = state.scopeLevels[state.scopeLevels.Count - 1].dagElementIndex;
            currentDagElement = dag.elements[currentDagElementIndex];

            topScope = state.scopeLevels[state.currentScopeLevel];

            if( currentDagElement.childIndices.Count == 0 )
            {
                throw new Exception("mathematical operation : It is invalid that it has no operands!");
            }

            if( topScope.simpleMathState == InterpretationState.ScopeLevel.EnumSimpleMathState.INITIAL )
            {
                InterpretationState.ScopeLevel createdScopeLevel;
                int dagIndexOfCalled;

                // invoke first value

                topScope.simpleMathState = InterpretationState.ScopeLevel.EnumSimpleMathState.STOREINITIAL;

                // build scope and setup

                createdScopeLevel = new InterpretationState.ScopeLevel();
                state.scopeLevels.Add(createdScopeLevel);

                dagIndexOfCalled = currentDagElement.childIndices[0];
                createdScopeLevel.dagElementIndex = dagIndexOfCalled;

                // misc
                // do this so the next step executes the scope
                state.currentScopeLevel++;

                return;
            }
            else if( topScope.simpleMathState == InterpretationState.ScopeLevel.EnumSimpleMathState.STOREINITIAL )
            {
                // we have to store the initial value (is in calleeResult)

                if( topScope.calleeResult.type == Datastructures.Variadic.EnumType.INT )
                {
                    topScope.simpleMathResult = (float)topScope.calleeResult.valueInt;
                    topScope.simpleMathType = InterpretationState.ScopeLevel.EnumSimpleMathType.INT;
                }
                else if( topScope.calleeResult.type == Datastructures.Variadic.EnumType.FLOAT )
                {
                    topScope.simpleMathResult = topScope.calleeResult.valueFloat;
                    topScope.simpleMathType = InterpretationState.ScopeLevel.EnumSimpleMathType.FLOAT;
                }
                else
                {
                    throw new Exception("arithmetic  value at [0] is not a number!");
                }

                topScope.simpleMathState = InterpretationState.ScopeLevel.EnumSimpleMathState.SUCCEEDINGTOCALL;
                topScope.simpleMathIndex = 1;
            }
            else if( topScope.simpleMathState == InterpretationState.ScopeLevel.EnumSimpleMathState.SUCCEEDINGTOCALL )
            {
                bool isAtEndOfChildrens;

                InterpretationState.ScopeLevel createdScopeLevel;
                int dagIndexOfCalled;

                System.Diagnostics.Debug.Assert(topScope.simpleMathIndex <= currentDagElement.childIndices.Count);
                isAtEndOfChildrens = topScope.simpleMathIndex == currentDagElement.childIndices.Count;

                if( isAtEndOfChildrens )
                {
                    Datastructures.Variadic resultVariadic;

                    if( topScope.simpleMathType == InterpretationState.ScopeLevel.EnumSimpleMathType.INT )
                    {
                        resultVariadic = new Datastructures.Variadic(Datastructures.Variadic.EnumType.INT);
                        resultVariadic.valueInt = (int)topScope.simpleMathResult;
                    }
                    else
                    {
                        resultVariadic = new Datastructures.Variadic(Datastructures.Variadic.EnumType.FLOAT);
                        resultVariadic.valueFloat = topScope.simpleMathResult;
                    }

                    returnResult(state, resultVariadic);

                    // remove scope of call
                    removeTopScope(state);

                    return;
                }
                // else we are here

                // invoke n'th value

                topScope.simpleMathState = InterpretationState.ScopeLevel.EnumSimpleMathState.SUCCEEDINGCALCULATE;

                // build scope and setup

                createdScopeLevel = new InterpretationState.ScopeLevel();
                state.scopeLevels.Add(createdScopeLevel);

                dagIndexOfCalled = currentDagElement.childIndices[topScope.simpleMathIndex];
                createdScopeLevel.dagElementIndex = dagIndexOfCalled;

                // misc
                // do this so the next step executes the scope
                state.currentScopeLevel++;

                topScope.simpleMathIndex++;

                return;
            }
            else if( topScope.simpleMathState == InterpretationState.ScopeLevel.EnumSimpleMathState.SUCCEEDINGCALCULATE )
            {
                float calleeResult;

                if( topScope.calleeResult.type == Datastructures.Variadic.EnumType.INT )
                {
                    calleeResult = (float)topScope.calleeResult.valueInt;
                }
                else if( topScope.calleeResult.type == Datastructures.Variadic.EnumType.FLOAT )
                {
                    calleeResult = topScope.calleeResult.valueFloat;
                    topScope.simpleMathType = InterpretationState.ScopeLevel.EnumSimpleMathType.FLOAT;
                }
                else
                {
                    throw new Exception("arithmetic  value at [" + (topScope.simpleMathIndex-1).ToString() + "] is not a number!");
                }

                // do real calculate
                if( currentDagElement.content.valueInt == (int)Parser.Functional.ScopeParseTreeElement.EnumType.ADD )
                {
                    topScope.simpleMathResult += calleeResult;
                }
                else if( currentDagElement.content.valueInt == (int)Parser.Functional.ScopeParseTreeElement.EnumType.SUB )
                {
                    topScope.simpleMathResult -= calleeResult;
                }
                else if( currentDagElement.content.valueInt == (int)Parser.Functional.ScopeParseTreeElement.EnumType.MUL )
                {
                    topScope.simpleMathResult *= calleeResult;
                }
                else if( currentDagElement.content.valueInt == (int)Parser.Functional.ScopeParseTreeElement.EnumType.DIV )
                {
                    topScope.simpleMathResult /= calleeResult;
                }
                else
                {
                    throw new Exception("Internal error!");
                }

                topScope.simpleMathState = InterpretationState.ScopeLevel.EnumSimpleMathState.SUCCEEDINGTOCALL;

                return;
            }
            else
            {
                throw new Exception("Internal Error!");
            }

            // unreachable
        }
Example #13
0
        private void executeSetVariables(Datastructures.Dag<ProgramRepresentation.DagElementData> dag, InterpretationState state)
        {
            int currentDagElementIndex;
            Datastructures.Dag<ProgramRepresentation.DagElementData>.Element currentDagElement;

            InterpretationState.ScopeLevel topScope;

            currentDagElementIndex = state.scopeLevels[state.scopeLevels.Count - 1].dagElementIndex;
            currentDagElement = dag.elements[currentDagElementIndex];

            topScope = state.scopeLevels[state.currentScopeLevel];

            if( topScope.setVariablesState == InterpretationState.ScopeLevel.EnumSetVariablesState.INITIAL )
            {
                int dagIndexOfVariablesArray;
                bool numberOfVariableArrayElementsValid;

                dagIndexOfVariablesArray = currentDagElement.childIndices[0];

                if( dag.elements[dagIndexOfVariablesArray].content.type != DagElementData.EnumType.FARRAY )
                {
                    throw new Exception("set  first argument must be a array!");
                }

                numberOfVariableArrayElementsValid = (dag.elements[dagIndexOfVariablesArray].childIndices.Count % 2) == 0;
                if( !numberOfVariableArrayElementsValid )
                {
                    throw new Exception("set  number of elements of the variable array is invalid!");
                }

                topScope.setVariablesState = InterpretationState.ScopeLevel.EnumSetVariablesState.RESOLVEVARIABLES;

                return;
            }
            else if( topScope.setVariablesState == InterpretationState.ScopeLevel.EnumSetVariablesState.RESOLVEVARIABLES )
            {
                int numberOfVariables;
                int dagIndexOfVariablesArray;
                List<int> variableArrayDagIndices;

                dagIndexOfVariablesArray = currentDagElement.childIndices[0];

                variableArrayDagIndices = dag.elements[dagIndexOfVariablesArray].childIndices;
                numberOfVariables = variableArrayDagIndices.Count / 2;

                for(;;)
                {
                    int indexInArrayOfVariableIdentifier;
                    int indexInArrayOfVariableValue;

                    int dagIndexOfVariableIndentifier;
                    int dagIndexOfVariableValue;

                    string identifierOfVariableToSet;

                    System.Diagnostics.Debug.Assert(topScope.setVariablesVariableIndex <= numberOfVariables);
                    if( topScope.setVariablesVariableIndex == numberOfVariables )
                    {
                        topScope.setVariablesState = InterpretationState.ScopeLevel.EnumSetVariablesState.INVOKEBODY;

                        return;
                    }

                    indexInArrayOfVariableIdentifier = topScope.setVariablesVariableIndex*2;
                    indexInArrayOfVariableValue = indexInArrayOfVariableIdentifier + 1;

                    dagIndexOfVariableIndentifier = variableArrayDagIndices[indexInArrayOfVariableIdentifier];
                    dagIndexOfVariableValue = variableArrayDagIndices[indexInArrayOfVariableValue];

                    if( dag.elements[dagIndexOfVariableIndentifier].content.type != DagElementData.EnumType.IDENTIFIERNAME )
                    {
                        throw new Exception("set  Array content at absolute index " + dagIndexOfVariableIndentifier.ToString() + " must be an identifier!");
                    }

                    identifierOfVariableToSet = dag.elements[dagIndexOfVariableIndentifier].content.identifier;

                    if( dag.elements[dagIndexOfVariableValue].content.type == DagElementData.EnumType.IDENTIFIERNAME )
                    {
                        bool variableWasResolved;
                        string sourceVariableName;
                        Datastructures.Variadic resolvedVariable;

                        // source is a variable

                        // * try to resolve the variable
                        // * set value of new variable (can also override an existing one in this scope)

                        sourceVariableName = dag.elements[dagIndexOfVariableValue].content.identifier;
                        resolvedVariable = resolveVariable(sourceVariableName, state, out variableWasResolved);
                        if( !variableWasResolved )
                        {
                            throw new Exception("set  variable " + sourceVariableName + " could not be resolved!");
                        }

                        // set value of new variable
                        setVariableInScope(identifierOfVariableToSet, EnumOverwriteExistingVariable.YES, resolvedVariable, topScope);

                        topScope.setVariablesVariableIndex++;

                        continue;
                    }
                    else
                    {
                        int dagIndexOfCalled;
                        InterpretationState.ScopeLevel createdScopeLevel;

                        // source is not a variable

                        // open new scope to calculate the value for the variable

                        topScope.setVariablesState = InterpretationState.ScopeLevel.EnumSetVariablesState.RESOLVEVARIABLESSCOPE;

                        // open scope ...
                        createdScopeLevel = new InterpretationState.ScopeLevel();
                        state.scopeLevels.Add(createdScopeLevel);

                        dagIndexOfCalled = dagIndexOfVariableValue;
                        createdScopeLevel.dagElementIndex = dagIndexOfCalled;

                        // do this so the next step executes the scope
                        state.currentScopeLevel++;

                        return;
                    }

                    // unreachable
                    throw new Exception("Unreachable!");
                }

                // unreachable
                throw new Exception("Unreachable!");
            }
            else if( topScope.setVariablesState == InterpretationState.ScopeLevel.EnumSetVariablesState.RESOLVEVARIABLESSCOPE )
            {
                Datastructures.Variadic variableValue;
                int indexInArrayOfVariableIdentifier;
                int dagIndexOfVariableIndentifier;
                string identifierOfVariableToSet;

                int dagIndexOfVariablesArray;
                List<int> variableArrayDagIndices;

                dagIndexOfVariablesArray = currentDagElement.childIndices[0];

                variableArrayDagIndices = dag.elements[dagIndexOfVariablesArray].childIndices;

                indexInArrayOfVariableIdentifier = topScope.setVariablesVariableIndex * 2;
                dagIndexOfVariableIndentifier = variableArrayDagIndices[indexInArrayOfVariableIdentifier];
                identifierOfVariableToSet = dag.elements[dagIndexOfVariableIndentifier].content.identifier;

                variableValue = topScope.calleeResult;

                setVariableInScope(identifierOfVariableToSet, EnumOverwriteExistingVariable.YES, variableValue, topScope);

                topScope.setVariablesVariableIndex++;

                topScope.setVariablesState = InterpretationState.ScopeLevel.EnumSetVariablesState.RESOLVEVARIABLES;

                return;
            }
            else if( topScope.setVariablesState == InterpretationState.ScopeLevel.EnumSetVariablesState.INVOKEBODY )
            {
                int dagIndexOfCalled;
                InterpretationState.ScopeLevel createdScopeLevel;

                int dagIndexOfScope;

                dagIndexOfScope = currentDagElement.childIndices[1];

                topScope.setVariablesState = InterpretationState.ScopeLevel.EnumSetVariablesState.RETURNVALUE;

                // open scope ...
                createdScopeLevel = new InterpretationState.ScopeLevel();
                state.scopeLevels.Add(createdScopeLevel);

                dagIndexOfCalled = dagIndexOfScope;
                createdScopeLevel.dagElementIndex = dagIndexOfCalled;

                // do this so the next step executes the scope
                state.currentScopeLevel++;

                return;
            }
            else if( topScope.setVariablesState == InterpretationState.ScopeLevel.EnumSetVariablesState.RETURNVALUE )
            {
                returnResult(state, topScope.calleeResult);

                // remove scope of call
                removeTopScope(state);

                return;
            }
            else
            {
                throw new Exception("Internal error");
            }
        }
Example #14
0
        private void executeReturnArray(Datastructures.Dag<ProgramRepresentation.DagElementData> dag, InterpretationState state)
        {
            int currentDagElementIndex;
            Datastructures.Dag<ProgramRepresentation.DagElementData>.Element currentDagElement;

            InterpretationState.ScopeLevel topScope;

            InterpretationState.ScopeLevel createdScopeLevel;
            int dagIndexOfCalled;

            currentDagElementIndex = state.scopeLevels[state.scopeLevels.Count - 1].dagElementIndex;
            currentDagElement = dag.elements[currentDagElementIndex];

            topScope = state.scopeLevels[state.currentScopeLevel];

            // if it is the first call -> create result array
            // else -> store result
            if (topScope.arrayIndex == 0)
            {
                topScope.arrayResultArray = new List<Datastructures.Variadic>();
            }
            else
            {
                topScope.arrayResultArray.Add(topScope.calleeResult);
            }

            System.Diagnostics.Debug.Assert(topScope.arrayIndex <= currentDagElement.childIndices.Count);
            if( topScope.arrayIndex == currentDagElement.childIndices.Count )
            {
                Datastructures.Variadic resultVariadic;

                resultVariadic = new Datastructures.Variadic(Datastructures.Variadic.EnumType.ARRAY);
                resultVariadic.valueArray = topScope.arrayResultArray;

                returnResult(state, resultVariadic);

                // remove scope of call
                removeTopScope(state);

                return;
            }
            // else we are here

            // build scope and setup

            createdScopeLevel = new InterpretationState.ScopeLevel();
            state.scopeLevels.Add(createdScopeLevel);

            dagIndexOfCalled = currentDagElement.childIndices[topScope.arrayIndex];
            createdScopeLevel.dagElementIndex = dagIndexOfCalled;

            // misc
            // do this so the next step executes the scope
            state.currentScopeLevel++;

            topScope.arrayIndex++;

            return;
        }
Example #15
0
        public void interpreteStep(Datastructures.Dag<ProgramRepresentation.DagElementData> dag, InterpretationState state, out bool terminatorReached)
        {
            int currentDagElementIndex;
            Datastructures.Dag<ProgramRepresentation.DagElementData>.Element currentDagElement;

            currentDagElementIndex = state.scopeLevels[state.scopeLevels.Count-1].dagElementIndex;
            currentDagElement = dag.elements[currentDagElementIndex];

            terminatorReached = isTopScopeATerminator(state);
            if( terminatorReached )
            {
                return;
            }

            if( currentDagElement.content.type == DagElementData.EnumType.FSCOPE )
            {
                if( currentDagElement.content.valueInt == (int)Parser.Functional.ScopeParseTreeElement.EnumType.INVOKE )
                {
                    executeInvoke(dag, state);
                }
                else if( currentDagElement.content.valueInt == (int)Parser.Functional.ScopeParseTreeElement.EnumType.FOLD )
                {
                    executeFold(dag, state);
                }
                else if( currentDagElement.content.valueInt == (int)Parser.Functional.ScopeParseTreeElement.EnumType.MATCH )
                {
                    executeMatch(dag, state);
                }
                else if( currentDagElement.content.valueInt == (int)Parser.Functional.ScopeParseTreeElement.EnumType.FOREACH )
                {
                    executeForeach(dag, state);
                }
                else if (currentDagElement.content.valueInt == (int)Parser.Functional.ScopeParseTreeElement.EnumType.PASS )
                {
                    executePass(dag, state);
                }
                else if( currentDagElement.content.valueInt == (int)Parser.Functional.ScopeParseTreeElement.EnumType.FSET )
                {
                    executeSetVariables(dag, state);
                }
                else if(
                    currentDagElement.content.valueInt == (int)Parser.Functional.ScopeParseTreeElement.EnumType.ADD ||
                    currentDagElement.content.valueInt == (int)Parser.Functional.ScopeParseTreeElement.EnumType.SUB ||
                    currentDagElement.content.valueInt == (int)Parser.Functional.ScopeParseTreeElement.EnumType.MUL ||
                    currentDagElement.content.valueInt == (int)Parser.Functional.ScopeParseTreeElement.EnumType.DIV
                )
                {
                    executeSimpleMathOperation(dag, state, (Parser.Functional.ScopeParseTreeElement.EnumType)currentDagElement.content.valueInt);
                }
                else
                {
                    throw new Exception("Internal Error!");
                }

                return;
            }
            else if(
                currentDagElement.content.type == DagElementData.EnumType.CONSTINT ||
                currentDagElement.content.type == DagElementData.EnumType.CONSTFLOAT ||
                currentDagElement.content.type == DagElementData.EnumType.CONSTBOOL
            )
            {
                returnValue(currentDagElement.content, state);

                return;
            }
            else if( currentDagElement.content.type == DagElementData.EnumType.FARRAY )
            {
                executeReturnArray(dag, state);
            }
            else if( currentDagElement.content.type == DagElementData.EnumType.IDENTIFIERNAME )
            {
                executeReturnVariable(dag, state);
            }
            else
            {
                throw new Exception("Tried to execute unexecutable instrution!");
            }
        }
Example #16
0
 /**
  *
  * removes the scope with all variables and so on on the top
  *
  */
 private static void removeTopScope(InterpretationState state)
 {
     state.scopeLevels.RemoveAt(state.scopeLevels.Count - 1);
     state.currentScopeLevel--;
 }
Example #17
0
        private void executeFold(Datastructures.Dag<ProgramRepresentation.DagElementData> dag, InterpretationState state)
        {
            int currentDagElementIndex;
            Datastructures.Dag<ProgramRepresentation.DagElementData>.Element currentDagElement;
            InterpretationState.ScopeLevel topScope;

            currentDagElementIndex = state.scopeLevels[state.scopeLevels.Count - 1].dagElementIndex;
            currentDagElement = dag.elements[currentDagElementIndex];

            topScope = state.scopeLevels[state.currentScopeLevel];

            if( topScope.foldState == InterpretationState.ScopeLevel.EnumFoldState.INITIAL )
            {
                int dagIndexOfArrayWithValuesOrScope;
                DagElementData.EnumType arrayWithValuesOrScopeType;

                dagIndexOfArrayWithValuesOrScope = currentDagElement.childIndices[1];
                arrayWithValuesOrScopeType = dag.elements[dagIndexOfArrayWithValuesOrScope].content.type;

                if (arrayWithValuesOrScopeType == DagElementData.EnumType.FARRAY)
                {
                    List<int> dagIndicesOfVariablesOrConstantsOfArray;

                    dagIndicesOfVariablesOrConstantsOfArray = dag.elements[dagIndexOfArrayWithValuesOrScope].childIndices;
                    topScope.foldInputArray = resolveVariablesAndConstants(dag, dagIndicesOfVariablesOrConstantsOfArray, state);

                    topScope.foldState = InterpretationState.ScopeLevel.EnumFoldState.SUCCEEDING;

                    // not return
                }
                else if( arrayWithValuesOrScopeType == DagElementData.EnumType.FSCOPE )
                {
                    int dagIndexOfCalled;
                    InterpretationState.ScopeLevel createdScopeLevel;

                    topScope.foldState = InterpretationState.ScopeLevel.EnumFoldState.SCOPEFORARRAYINVOKED;

                    // open scope ...
                    createdScopeLevel = new InterpretationState.ScopeLevel();
                    state.scopeLevels.Add(createdScopeLevel);

                    dagIndexOfCalled = dagIndexOfArrayWithValuesOrScope;
                    createdScopeLevel.dagElementIndex = dagIndexOfCalled;

                    // do this so the next step executes the scope
                    state.currentScopeLevel++;

                    return;
                }
                else
                {
                    throw new Exception("Internal Error : Invalid not handable parameter for fold");
                }
            }
            else if( topScope.foldState == InterpretationState.ScopeLevel.EnumFoldState.SCOPEFORARRAYINVOKED )
            {
                // check if result is an array
                if( topScope.calleeResult.type != Datastructures.Variadic.EnumType.ARRAY )
                {
                    throw new Exception("fold second parameter is not an array!");
                }

                // set array as working array
                topScope.foldInputArray = topScope.calleeResult.valueArray;

                topScope.foldState = InterpretationState.ScopeLevel.EnumFoldState.SUCCEEDING;

                // no return
            }

            System.Diagnostics.Debug.Assert(topScope.foldState == InterpretationState.ScopeLevel.EnumFoldState.SUCCEEDING);

            if (topScope.foldIterationIndex == -1)
            {
                // first iteration
                if (topScope.foldInputArray.Count == 0)
                {
                    // no value in array, return false

                    state.scopeLevels[state.currentScopeLevel - 1].calleeResult = new Datastructures.Variadic(Datastructures.Variadic.EnumType.BOOL);
                    state.scopeLevels[state.currentScopeLevel - 1].calleeResult.valueBool = false;

                    // remove scope of fold
                    state.scopeLevels.RemoveAt(state.scopeLevels.Count - 1);

                    return;
                }
                else if (topScope.foldInputArray.Count == 1)
                {
                    // one value in array, return it
                    Datastructures.Variadic result;

                    result = topScope.foldInputArray[0];
                    returnResult(state, result);

                    // remove scope of fold
                    //BUG? state.scopeLevels.RemoveAt(state.scopeLevels.Count - 1);
                    // TODO< investigate >
                    removeTopScope(state);

                    return;
                }
                else
                {
                    Datastructures.Variadic firstValue;
                    Datastructures.Variadic secondValue;
                    int dagIndexOfCalled;
                    InterpretationState.ScopeLevel createdScopeLevel;

                    // two or more values in the array

                    // * fetch values
                    // * check if called is a dag-scope
                    // * open scope and push the dag-scope for execution
                    // * set variables

                    // fetch values
                    firstValue = topScope.foldInputArray[0];
                    secondValue = topScope.foldInputArray[1];

                    // check
                    dagIndexOfCalled = currentDagElement.childIndices[0];
                    if (dag.elements[dagIndexOfCalled].content.type != DagElementData.EnumType.FSCOPE)
                    {
                        throw new Exception("fold: first parameter must be a scope!");
                    }

                    // open scope ...
                    createdScopeLevel = new InterpretationState.ScopeLevel();
                    state.scopeLevels.Add(createdScopeLevel);

                    createdScopeLevel.dagElementIndex = dagIndexOfCalled;

                    // (set variables)
                    createdScopeLevel.variables.Add(new InterpretationState.ScopeLevel.Variable());
                    createdScopeLevel.variables.Add(new InterpretationState.ScopeLevel.Variable());
                    createdScopeLevel.variables.Add(new InterpretationState.ScopeLevel.Variable());
                    createdScopeLevel.variables[0].name = "accu";
                    createdScopeLevel.variables[0].value = firstValue;
                    createdScopeLevel.variables[1].name = "other";
                    createdScopeLevel.variables[1].value = secondValue;
                    createdScopeLevel.variables[2].name = "index";
                    createdScopeLevel.variables[2].value = new Datastructures.Variadic(Datastructures.Variadic.EnumType.INT);
                    createdScopeLevel.variables[2].value.valueInt = 0;

                    topScope.foldIterationIndex = 1;

                    // do this so the next step executes the scope
                    state.currentScopeLevel++;

                    return;
                }
            }
            else
            {
                // following iterations

                // * check if array is walked
                //   if not ->
                //   * fetch value
                //   * evaluate value
                //   * open scope and push the dag-scope for execution
                //   * set variables
                //   if ->
                //   * return accumulated value

                int valueArrayListLength;
                Datastructures.Variadic evaluatedValue;
                InterpretationState.ScopeLevel createdScopeLevel;
                int dagIndexOfCalled;

                valueArrayListLength = topScope.foldInputArray.Count;

                dagIndexOfCalled = currentDagElement.childIndices[0];

                // check if array is walked
                System.Diagnostics.Debug.Assert(topScope.foldIterationIndex <= valueArrayListLength);
                if (topScope.foldIterationIndex == valueArrayListLength)
                {
                    // it is walked

                    // return the result
                    returnResult(state, topScope.calleeResult);

                    // remove scope of call
                    removeTopScope(state);

                    return;
                }
                // else we are here

                // fetch value
                // evaluate
                evaluatedValue = topScope.foldInputArray[topScope.foldIterationIndex];

                // open scope and push the dag-scope for execution
                createdScopeLevel = new InterpretationState.ScopeLevel();
                state.scopeLevels.Add(createdScopeLevel);

                createdScopeLevel.dagElementIndex = dagIndexOfCalled;

                // set variables
                createdScopeLevel.variables.Add(new InterpretationState.ScopeLevel.Variable());
                createdScopeLevel.variables.Add(new InterpretationState.ScopeLevel.Variable());
                createdScopeLevel.variables.Add(new InterpretationState.ScopeLevel.Variable());
                createdScopeLevel.variables[0].name = "accu";
                createdScopeLevel.variables[0].value = topScope.calleeResult;
                createdScopeLevel.variables[1].name = "other";
                createdScopeLevel.variables[1].value = evaluatedValue;
                createdScopeLevel.variables[2].name = "index";
                createdScopeLevel.variables[2].value = new Datastructures.Variadic(Datastructures.Variadic.EnumType.INT);
                createdScopeLevel.variables[2].value.valueInt = topScope.foldIterationIndex;

                // misc

                // increment the index for the next call
                topScope.foldIterationIndex++;

                // do this so the next step executes the scope
                state.currentScopeLevel++;

                return;
            }
        }
Example #18
0
        private static Datastructures.Variadic resolveVariable(string variableName, InterpretationState state, out bool wasResolved)
        {
            int scopeLevelIndex;

            wasResolved = false;

            for( scopeLevelIndex = state.scopeLevels.Count-1;; scopeLevelIndex-- )
            {
                InterpretationState.ScopeLevel currentScope;

                currentScope = state.scopeLevels[scopeLevelIndex];

                // search inside he variables for the variable
                foreach( InterpretationState.ScopeLevel.Variable iterationVariable in currentScope.variables )
                {
                    if( iterationVariable.name == variableName )
                    {
                        wasResolved = true;
                        return iterationVariable.value;
                    }
                }

                if( scopeLevelIndex == 0 )
                {
                    return null;
                }
            }
        }
Example #19
0
        private void executeInvoke(Datastructures.Dag<ProgramRepresentation.DagElementData> dag, InterpretationState state)
        {
            Datastructures.Variadic invokeResult;
            EnumInvokeDispatcherCallResult callResult;

            int currentDagElementIndex;
            Datastructures.Dag<ProgramRepresentation.DagElementData>.Element currentDagElement;
            InterpretationState.ScopeLevel topScope;

            currentDagElementIndex = state.scopeLevels[state.scopeLevels.Count-1].dagElementIndex;
            currentDagElement = dag.elements[currentDagElementIndex];

            topScope = state.scopeLevels[state.currentScopeLevel];

            if( topScope.invokeState == InterpretationState.ScopeLevel.EnumInvokeState.INITIAL )
            {
                topScope.invokeState = InterpretationState.ScopeLevel.EnumInvokeState.RESOLVEPARAMETERS;
                topScope.invokeResolvedParameters = new List<Datastructures.Variadic>();

                return;
            }
            else if( topScope.invokeState == InterpretationState.ScopeLevel.EnumInvokeState.RESOLVEPARAMETERS )
            {
                int dagIndexOfArrayWithParameters;
                List<int> dagIndicesOfArrayContentForParameters;

                // retrieve and try to resolve remaining parameters

                dagIndexOfArrayWithParameters = currentDagElement.childIndices[1];
                dagIndicesOfArrayContentForParameters = dag.elements[dagIndexOfArrayWithParameters].childIndices;

                for(;;)
                {
                    int dagIndexOfParameter;

                    // check if we are done with the resolving
                    System.Diagnostics.Debug.Assert(topScope.invokeResolveParametersIndex <= dagIndicesOfArrayContentForParameters.Count);
                    if( topScope.invokeResolveParametersIndex == dagIndicesOfArrayContentForParameters.Count )
                    {
                        topScope.invokeState = InterpretationState.ScopeLevel.EnumInvokeState.INVOKE;

                        return;
                    }

                    // check if the current parameter is a scope
                    // if it is the case, we open the scope and transfer control
                    // if its not the case we can try to resolve the parameter as usual and continue
                    dagIndexOfParameter = dagIndicesOfArrayContentForParameters[topScope.invokeResolveParametersIndex];

                    if( dag.elements[dagIndexOfParameter].content.type == DagElementData.EnumType.FSCOPE )
                    {
                        InterpretationState.ScopeLevel createdScopeLevel;

                        topScope.invokeResolveParametersIndex++;
                        topScope.invokeState = InterpretationState.ScopeLevel.EnumInvokeState.SCOPEFORPARAMETERWASINVOKED;

                        // build new scope
                        createdScopeLevel = new InterpretationState.ScopeLevel();
                        state.scopeLevels.Add(createdScopeLevel);

                        createdScopeLevel.dagElementIndex = dagIndexOfParameter;

                        // do this so the next step executes the scope
                        state.currentScopeLevel++;

                        return;
                    }
                    else
                    {
                        Datastructures.Variadic currentResolvedParameter;

                        currentResolvedParameter = resolveVariableAndConstant(dag, dagIndexOfParameter, state);
                        topScope.invokeResolvedParameters.Add(currentResolvedParameter);
                        topScope.invokeResolveParametersIndex++;
                    }
                }

            }
            else if( topScope.invokeState == InterpretationState.ScopeLevel.EnumInvokeState.SCOPEFORPARAMETERWASINVOKED )
            {
                Datastructures.Variadic parameterFromScope;

                // the scope for an parameter was invoked and the result is on the stack

                // * get the result from the stack
                // * add it to the parameters
                // * go back in the state

                // NOTE< we just move the reference >
                parameterFromScope = topScope.calleeResult;
                topScope.invokeResolvedParameters.Add(parameterFromScope);

                topScope.invokeState = InterpretationState.ScopeLevel.EnumInvokeState.RESOLVEPARAMETERS;

                return;
            }
            else if( topScope.invokeState == InterpretationState.ScopeLevel.EnumInvokeState.INVOKE )
            {
                int dagIndexOfArrayWithPath;
                List<int> dagIndicesOfArrayContentForPath;
                List<string> pathOfInvokedProgram;

                bool isInterpretableInvoke;
                int dagIndexOfInvokedScope;
                List<string> invokeVariableNames;

                // build the path of the invoked program
                dagIndexOfArrayWithPath = currentDagElement.childIndices[0];

                if (dag.elements[dagIndexOfArrayWithPath].content.type != DagElementData.EnumType.FARRAY)
                {
                    throw new Exception("Invoke parameter [0] was not an Array as expected!");
                }

                // grab the indices of the array
                dagIndicesOfArrayContentForPath = dag.elements[dagIndexOfArrayWithPath].childIndices;
                // and put them into the function which executes building stuff for the path for the invoke
                pathOfInvokedProgram = getPathOfInvokeScopeInstruction(dag, dagIndicesOfArrayContentForPath, state);

                // try to lookup the path inside the list with all interpretable programs (which can be invoked)
                invokeVariableNames = new List<string>();
                lookupInvokePath(state, pathOfInvokedProgram, out isInterpretableInvoke, out dagIndexOfInvokedScope, invokeVariableNames);

                if (isInterpretableInvoke)
                {
                    InterpretationState.ScopeLevel createdScopeLevel;
                    int variableI;

                    // set state
                    topScope.invokeState = InterpretationState.ScopeLevel.EnumInvokeState.PROGRAMINVOKED;

                    // check if number of parameter is correct
                    if (topScope.invokeResolvedParameters.Count != invokeVariableNames.Count)
                    {
                        throw new Exception("invoke parameter count is invalid!");
                    }

                    // build new scope
                    createdScopeLevel = new InterpretationState.ScopeLevel();
                    state.scopeLevels.Add(createdScopeLevel);

                    createdScopeLevel.dagElementIndex = dagIndexOfInvokedScope;

                    // set variables
                    for (variableI = 0; variableI < invokeVariableNames.Count; variableI++)
                    {
                        InterpretationState.ScopeLevel.Variable createdVariable;

                        createdVariable = new InterpretationState.ScopeLevel.Variable();
                        createdVariable.name = invokeVariableNames[variableI];
                        createdVariable.value = topScope.invokeResolvedParameters[variableI];

                        createdScopeLevel.variables.Add(createdVariable);
                    }

                    // do this so the next step executes the scope
                    state.currentScopeLevel++;

                    return;
                }
                else
                {
                    // dispatch invoke
                    invokeDispatcher.dispatchInvokeStart(pathOfInvokedProgram, topScope.invokeResolvedParameters, state.scopeLevels, out invokeResult, out callResult);

                    // TODO< maybe logic for searching of callee >
                    System.Diagnostics.Debug.Assert(state.currentScopeLevel > 0);

                    // if we are done
                    // return result to caller (in state stack)
                    // if the call failed we return false
                    if (callResult == EnumInvokeDispatcherCallResult.DONE)
                    {
                        state.scopeLevels[state.currentScopeLevel - 1].calleeResult = invokeResult;

                        // remove scope of call
                        state.scopeLevels.RemoveAt(state.scopeLevels.Count - 1);
                        state.currentScopeLevel--;

                        return;
                    }
                    else if (callResult == EnumInvokeDispatcherCallResult.PATHINVALID)
                    {
                        state.scopeLevels[state.currentScopeLevel - 1].calleeResult = new Datastructures.Variadic(Datastructures.Variadic.EnumType.BOOL);
                        state.scopeLevels[state.currentScopeLevel - 1].calleeResult.valueBool = false;

                        // remove scope of call
                        state.scopeLevels.RemoveAt(state.scopeLevels.Count - 1);
                        state.currentScopeLevel--;

                        return;
                    }
                    else if (callResult == EnumInvokeDispatcherCallResult.SUCCEEDINGINTERNAL)
                    {
                        System.Diagnostics.Debug.Assert(false, "SUCCEEDINGINTERNAL not supported!");
                        throw new Exception("Internal Error!");
                    }

                    return;
                }
            }
            else if( topScope.invokeState == InterpretationState.ScopeLevel.EnumInvokeState.PROGRAMINVOKED )
            {
                // TODO< maybe logic for searching of callee >
                System.Diagnostics.Debug.Assert(state.currentScopeLevel > 0);

                state.scopeLevels[state.currentScopeLevel - 1].calleeResult = state.scopeLevels[state.currentScopeLevel].calleeResult;

                // remove scope of call
                state.scopeLevels.RemoveAt(state.scopeLevels.Count - 1);
                state.currentScopeLevel--;

                return;
            }
            else
            {
                throw new Exception("Internal Error!");
            }

            throw new Exception("unreachable!");
        }
Example #20
0
        private void executeMatch(Datastructures.Dag<ProgramRepresentation.DagElementData> dag, InterpretationState state)
        {
            int currentDagElementIndex;
            Datastructures.Dag<ProgramRepresentation.DagElementData>.Element currentDagElement;

            InterpretationState.ScopeLevel topScope;

            currentDagElementIndex = state.scopeLevels[state.scopeLevels.Count - 1].dagElementIndex;
            currentDagElement = dag.elements[currentDagElementIndex];

            topScope = state.scopeLevels[state.currentScopeLevel];

            if( topScope.matchState == InterpretationState.ScopeLevel.EnumMatchState.ENTRY )
            {
                int dagIndexOfValueOrScope;
                bool valueIsPresentAsConstantOrVariable;
                Datastructures.Variadic valueToCompare;

                // check number of childrens, must be odd
                if( (currentDagElement.childIndices.Count % 2) != 1 )
                {
                    throw new Exception("match was executed with even number of parameters!");
                }

                dagIndexOfValueOrScope = currentDagElement.childIndices[0];

                valueIsPresentAsConstantOrVariable = isConstantOrVariable(dag, dagIndexOfValueOrScope);
                if( valueIsPresentAsConstantOrVariable )
                {
                    valueToCompare = resolveVariableAndConstant(dag, dagIndexOfValueOrScope, state);

                    // set value to compare of "match"
                    topScope.matchValue = valueToCompare;

                    topScope.matchState = InterpretationState.ScopeLevel.EnumMatchState.COMPARE;

                    return;
                }
                else
                {
                    InterpretationState.ScopeLevel createdScopeLevel;

                    // * setup current scope to "catch" return value
                    // * open scope and push the dag-scope for execution

                    // TODO< setup current scope to "catch" return value >

                    // open scope and push the dag-scope for execution

                    createdScopeLevel = new InterpretationState.ScopeLevel();
                    state.scopeLevels.Add(createdScopeLevel);

                    createdScopeLevel.dagElementIndex = dagIndexOfValueOrScope;

                    // misc

                    // do this so the next step executes the scope
                    state.currentScopeLevel++;

                    topScope.matchState = InterpretationState.ScopeLevel.EnumMatchState.SCOPEFORVALUEWASINVOKED;

                    return;
                }
            }
            else if( topScope.matchState == InterpretationState.ScopeLevel.EnumMatchState.RETURNRESULT )
            {
                // TODO< propagate result value >

                returnResult(state, topScope.calleeResult);

                // remove scope of call
                removeTopScope(state);

                return;
            }
            else if (topScope.matchState == InterpretationState.ScopeLevel.EnumMatchState.SCOPEFORVALUEWASINVOKED)
            {
                // the scope for the calculation of the comparison value was executed
                // now we need to store the value and compare

                topScope.matchValue = topScope.calleeResult;

                topScope.matchState = InterpretationState.ScopeLevel.EnumMatchState.COMPARE;

                // no return
            }
            else if( topScope.matchState == InterpretationState.ScopeLevel.EnumMatchState.COMPARE )
            {
                // fall through
            }
            else
            {
                System.Diagnostics.Debug.Assert(false);
                throw new Exception("Internal Error!");
            }

            // if we are here we can either compare or open a scope to calculate the result of the "match"
            if( topScope.matchState == InterpretationState.ScopeLevel.EnumMatchState.COMPARE )
            {
                int dagIndexOfComparePattern;
                int numberOfMatchArguments;
                int numberOfMatches;

                // check for end and return false if it reached the end without finding a match

                numberOfMatchArguments = currentDagElement.childIndices.Count;
                numberOfMatches = (numberOfMatchArguments-1)/2;
                System.Diagnostics.Debug.Assert(topScope.matchIndexInCompare <= numberOfMatches);
                if( topScope.matchIndexInCompare == numberOfMatches )
                {
                    Datastructures.Variadic resultValue;
                    // end reached without a match
                    // return false

                    resultValue = new Datastructures.Variadic(Datastructures.Variadic.EnumType.BOOL);
                    resultValue.valueBool = false;
                    returnResult(state, resultValue);

                    // remove scope of call
                    removeTopScope(state);

                    return;
                }

                // we are here if there are enougth elements

                dagIndexOfComparePattern = currentDagElement.childIndices[1 + topScope.matchIndexInCompare * 2]; // can be unsafe

                if(
                    dag.elements[dagIndexOfComparePattern].content.type == DagElementData.EnumType.CONSTINT ||
                    dag.elements[dagIndexOfComparePattern].content.type == DagElementData.EnumType.CONSTBOOL
                )
                {
                    bool isConvertableTo;
                    Datastructures.Variadic convertedPattern;
                    bool doesMatch;

                    // try to convert

                    isConvertableTo = isDagElementTypeTheSameOrConvertableToType(dag.elements[dagIndexOfComparePattern], topScope.matchValue.type);
                    if( !isConvertableTo )
                    {
                        throw new Exception("match: Type of compared value is not convertable or equal to pattern type!");
                    }

                    convertedPattern = convertTo(dag.elements[dagIndexOfComparePattern], topScope.matchValue.type);

                    // match
                    doesMatch = doesVariableMatchPattern(topScope.matchValue, convertedPattern);

                    if( doesMatch )
                    {
                        InterpretationState.ScopeLevel createdScopeLevel;
                        int dagIndexOfExecutedBranch;

                        // set value so next call terminates and returns the result
                        topScope.matchState = InterpretationState.ScopeLevel.EnumMatchState.RETURNRESULT;

                        // execution of scope if it does match on the next step

                        createdScopeLevel = new InterpretationState.ScopeLevel();
                        state.scopeLevels.Add(createdScopeLevel);

                        dagIndexOfExecutedBranch = currentDagElement.childIndices[1 + topScope.matchIndexInCompare * 2 + 1]; // can be unsafe
                        createdScopeLevel.dagElementIndex = dagIndexOfExecutedBranch;

                        // misc

                        // do this so the next step executes the scope
                        state.currentScopeLevel++;

                        return;
                    }
                    else
                    {
                        // continue in the next step with the next pattern

                        topScope.matchIndexInCompare++;

                        return;
                    }
                }
                else
                {
                    // also TODO

                    System.Diagnostics.Debug.Assert(false);
                    throw new Exception("Internal Error!");
                }
            }
            else
            {
                // also TODO

                System.Diagnostics.Debug.Assert(false);
                throw new Exception("Internal Error!");
            }
        }