Ejemplo n.º 1
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!");
        }
Ejemplo n.º 2
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);
            }
        }