示例#1
0
        private AST CreateAssignmentTreeFromInitValue(string pVariableName, object pInitValue)
        {
            Token.TokenType tokenType;
            switch (ReturnValueConversions.SystemTypeToReturnValueType(pInitValue.GetType()))
            {
            case ReturnValueType.BOOL:
                tokenType = Token.TokenType.BOOLEAN_VALUE;
                break;

            case ReturnValueType.STRING:
                tokenType = Token.TokenType.QUOTED_STRING;
                break;

            case ReturnValueType.NUMBER:
                tokenType = Token.TokenType.NUMBER;
                break;

            case ReturnValueType.ARRAY:
                tokenType = Token.TokenType.ARRAY;
                break;

            case ReturnValueType.VOID:
                throw new Error("Can't assign void to variable");

            default:
                throw new Exception("Forgot to implement support for a type?");
            }
            Token initValueToken = new TokenWithValue(tokenType, pInitValue.ToString(), pInitValue);
            AST   assignmentTree = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), pVariableName);

            assignmentTree.addChild(initValueToken);
            return(assignmentTree);
        }
示例#2
0
        void AddLocalVariables(AST ast, VariableDefinition[] variableDefinitions)
        {
            AST nodeForDefiningGlobalVariables = ast.getChild(0).getChild(0);

            if (variableDefinitions == null)
            {
                return;
            }

            foreach (VariableDefinition vd in variableDefinitions)
            {
                Token token = new Token(Token.TokenType.VAR_DECLARATION, "<VAR_DECL>", ast.getToken().LineNr, ast.getToken().LinePosition);

                AST_VariableDeclaration declarationTree =
                    new AST_VariableDeclaration(token,
                                                ReturnValueConversions.SystemTypeToReturnValueType(vd.initValue.GetType()),
                                                vd.variableName);

                if (vd.initValue != null)
                {
                    AST assignmentTree = CreateAssignmentTreeFromInitValue(vd.variableName, vd.initValue);
                    AST declarationAndAssignmentTree = new AST(new Token(Token.TokenType.STATEMENT_LIST, "<DECLARATION_AND_ASSIGNMENT>", declarationTree.getToken().LineNr, declarationTree.getToken().LinePosition));
                    declarationAndAssignmentTree.addChild(declarationTree);
                    declarationAndAssignmentTree.addChild(assignmentTree);
                    nodeForDefiningGlobalVariables.addChild(declarationAndAssignmentTree);
                }
                else
                {
                    nodeForDefiningGlobalVariables.addChild(declarationTree);
                }
            }
        }
示例#3
0
        private void JumpToFunction()
        {
            AST_FunctionDefinitionNode functionDefinitionNode = (CurrentNode as AST_FunctionCall).FunctionDefinitionRef;
            string functionName = functionDefinitionNode.getChild(1).getTokenString();

                        #if BUILT_IN_PROFILING
            ProfileData data = null;
            if (m_profileData.TryGetValue(functionName, out data))
            {
                data.calls++;
            }
            else
            {
                m_profileData.Add(functionName, new ProfileData()
                {
                    calls     = 1,
                    totalTime = 0f,
                });
            }
                        #endif

            var parameterDefs = functionDefinitionNode.getChild(2).getChildren();

            //ASTPainter painter = new ASTPainter();

            int      nrOfParameters = parameterDefs.Count;
            object[] parameters     = new object[nrOfParameters];
            for (int i = nrOfParameters - 1; i >= 0; i--)
            {
                //painter.PaintAST(parameterDefs[i]);

                var paramDef    = parameterDefs[i];
                var declaration = paramDef.getChild(0) as AST_VariableDeclaration;

                parameters[i] = ReturnValueConversions.ChangeTypeBasedOnReturnValueType(PopValue(), declaration.Type);
            }

            //try {

            if (IsFunctionExternal(functionName))
            {
                CallExternalFunction(functionName, parameters);
            }
            else
            {
                PushNewScope(functionDefinitionNode.getScope(), functionName + "_memorySpace" + functionCounter++, functionDefinitionNode);

                for (int i = nrOfParameters - 1; i >= 0; i--)
                {
                    PushValue(parameters[i]);                             // reverse order
                }
            }

//			}
//			catch(Exception e) {
//				Console.WriteLine("Exception when calling " + functionName + ": " + e.StackTrace);
//				throw e;
//			}
        }
示例#4
0
        private object ConvertToType(object valueToConvert, Type type)
        {
            var returnValueType = ReturnValueConversions.SystemTypeToReturnValueType(type);
//			Console.WriteLine("Assignment of " + ReturnValueConversions.PrettyStringRepresenation(valueToConvert) + " will convert it from " + valueToConvert.GetType() + " to " + type.ToString() + " (" + returnValueType + ")");
            object newObject = ReturnValueConversions.ChangeTypeBasedOnReturnValueType(valueToConvert, returnValueType);

            return(newObject);
        }
示例#5
0
        /// <summary>
        /// Sets the program to execute function.
        /// Returns true if the program had the function.
        /// </summary>
        public ProgramFunctionCallStatus SetProgramToExecuteFunction(string functionName, object[] args)
        {
            //Console.WriteLine ("Will execute '" + functionName + "' in global scope '" + m_globalScope + "'");

            FunctionSymbol functionSymbol = (FunctionSymbol)m_globalScope.resolve(functionName);

            //Console.WriteLine("Found function symbol: " + functionSymbol.ToString());

            if (functionSymbol == null)
            {
                return(ProgramFunctionCallStatus.NO_FUNCTION);
            }

            if (IsFunctionExternal(functionName))
            {
                CallExternalFunction(functionName, args);
                return(ProgramFunctionCallStatus.EXTERNAL_FUNCTION);
            }
            else
            {
                AST_FunctionDefinitionNode functionDefinitionNode = (AST_FunctionDefinitionNode)functionSymbol.getFunctionDefinitionNode();

                if (functionDefinitionNode != null)
                {
                    var parameters     = functionDefinitionNode.getChild(2).getChildren();
                    int nrOfParameters = parameters.Count;
                    if (nrOfParameters != args.Length)
                    {
                        throw new Error("The function " + functionName + " takes " + nrOfParameters + " arguments, not " + args.Length);
                    }

                    Reset();

                    m_topLevelDepth = 1;

                    m_currentScope = functionDefinitionNode.getScope();
                    m_currentScope.ClearMemorySpaces();

                    string nameOfNewMemorySpace = functionName + "_memorySpace" + functionCounter++;
                    PushNewScope(functionDefinitionNode.getScope(), nameOfNewMemorySpace, functionDefinitionNode);

                    for (int i = args.Length - 1; i >= 0; i--)
                    {
                        var    declaration    = parameters[i].getChild(0) as AST_VariableDeclaration;
                        object convertedValue = ReturnValueConversions.ChangeTypeBasedOnReturnValueType(args[i], declaration.Type);
                        PushValue(convertedValue);                         // reverse order
                    }

                    //Console.WriteLine ("Ready to start running function '" + functionName + "' with memory space '" + nameOfNewMemorySpace + "'");
                }
                else
                {
                    throw new Error(functionName + " has got no function definition node!");
                }
            }

            return(ProgramFunctionCallStatus.NORMAL_FUNCTION);            // all went well (starting the function)
        }
        private object print(object[] parameters)
        {
            object parameter0 = parameters[0];

            if (parameter0 == null)
            {
                throw new Exception("Parameter0 is null!");
            }
            m_output.Add(ReturnValueConversions.PrettyStringRepresenation(parameter0));
            return(VoidType.voidType);
        }
示例#7
0
 public static T SafeUnwrap <T>(object[] args, int index)
 {
     if (args[index].GetType() == typeof(T))
     {
         return((T)args[index]);
     }
     else
     {
         throw new Error("Arg " + index + " is of wrong type (" + ReturnValueConversions.PrettyObjectType(args[index].GetType()) +
                         "), should be " + ReturnValueConversions.PrettyObjectType(typeof(T)));
     }
 }
示例#8
0
        private object AddStuffTogetherHack()
        {
            object rhs = PopValue();
            object lhs = PopValue();

            var rightValueType = rhs.GetType();
            var leftValueType  = lhs.GetType();

            //Console.WriteLine("Adding " + lhs + " of type " + leftValueType + " together with " + rhs + " of type " + rightValueType);

            if (rightValueType == typeof(float) && leftValueType == typeof(float))
            {
                return((float)rhs + (float)lhs);
            }
            if (rightValueType == typeof(int) && leftValueType == typeof(int))
            {
                return((float)((int)rhs + (int)lhs));
            }
            else if (rightValueType == typeof(string) || leftValueType == typeof(string))
            {
                return(ReturnValueConversions.PrettyStringRepresenation(lhs) + ReturnValueConversions.PrettyStringRepresenation(rhs));
            }
            else if (rightValueType == typeof(object[]) && leftValueType == typeof(object[]))
            {
                throw new Error("Primitive array concatenation is temporarily disabled.");
            }
            else if (rightValueType == typeof(SortedDictionary <KeyWrapper, object>) && leftValueType == typeof(SortedDictionary <KeyWrapper, object>))
            {
                var lhsArray = lhs as SortedDictionary <KeyWrapper, object>;
                var rhsArray = rhs as SortedDictionary <KeyWrapper, object>;
                var newArray = new SortedDictionary <KeyWrapper, object>();
                for (int i = 0; i < lhsArray.Count; i++)
                {
                    newArray.Add(new KeyWrapper(i), lhsArray[new KeyWrapper(i)]);
                }
                for (int i = 0; i < rhsArray.Count; i++)
                {
                    newArray.Add(new KeyWrapper(i + lhsArray.Count), rhsArray[new KeyWrapper(i)]);
                }
                Console.WriteLine("Created new array by concatenation: " + ReturnValueConversions.PrettyStringRepresenation(newArray));
                return(newArray);
            }
            else
            {
                throw new Error("Can't add " + lhs + " to " + rhs);
            }
        }
示例#9
0
        private void EvaluateIf()
        {
            AST_IfNode ifnode = CurrentNode as AST_IfNode;

                        #if DEBUG
            Debug.Assert(ifnode != null);
                        #endif

            object r = PopValue();
                        #if DEBUG
            Debug.Assert(r != null);
                        #endif

            AST subNode = null;

            if (r.GetType() != typeof(bool) && r.GetType() != typeof(float))
            {
                var token = ifnode.getToken();
                throw new Error("Can't use value " + r + " of type " + ReturnValueConversions.PrettyObjectType(r.GetType()) + " in if-statement", Error.ErrorType.RUNTIME, token.LineNr, token.LinePosition);
            }

            if (ConvertToBool(r))
            {
                subNode = ifnode.getChild(1);
            }
            else
            {
                if (ifnode.getChildren().Count == 3)
                {
                    subNode = ifnode.getChild(2);
                }
                else
                {
                    //Console.WriteLine("There is no else-clause in statement");
                }
            }

            if (subNode != null)
            {
                //Console.WriteLine("entering node");
                PushNewScope(ifnode.getScope(), "IF_memorySpace" + ifCounter++, subNode);
            }
            else
            {
                //Console.WriteLine("can't enter node");
            }
        }
示例#10
0
 private bool ConvertToBool(object o)
 {
     //Console.WriteLine("Converting " + o + " of type " + o.GetType() + " to bool");
     if (o.GetType() == typeof(bool))
     {
         //Console.WriteLine(o + " is bool: " + (bool)o);
         return((bool)o);
     }
     else if (o.GetType() == typeof(float))
     {
         return((float)o == 0f ? false : true);
     }
     else if (o.GetType() == typeof(int))
     {
         return((int)o == 0 ? false : true);
     }
     throw new Error("Can't convert value " + o + " of type " + ReturnValueConversions.PrettyObjectType(o.GetType()) + " to bool");
 }
示例#11
0
        private float ConvertToNumber(object o)
        {
            if (o.GetType() == typeof(float))
            {
                return((float)o);
            }
            else if (o.GetType() == typeof(int))
            {
                return((float)(int)o);
            }
            else if (o.GetType() == typeof(string))
            {
                float f = 0f;
                if (float.TryParse((string)o, out f))
                {
                    return(f);
                }
            }

            throw new Error("Can't convert value " + o + " of type " + ReturnValueConversions.PrettyObjectType(o.GetType()) + " to number");
        }
示例#12
0
 private static object API_type(object[] args)
 {
     return(ReturnValueConversions.PrettyObjectType(args[0].GetType()));
 }
示例#13
0
        private void AssignmentToArrayElementSignal()
        {
            string variableName = (CurrentNode as AST_Assignment).VariableName;
            object valueToSet   = PopValue();
            object index        = PopValue();

            object rv = m_currentScope.getValue(variableName);

            if (rv.GetType() == typeof(SortedDictionary <KeyWrapper, object>))
            {
                SortedDictionary <KeyWrapper, object> array = rv as SortedDictionary <KeyWrapper, object>;

                //Console.WriteLine("Checking if index " + index + " of type " + index.GetType() + " is within range of array of length " + array.Count);

                if (array.ContainsKey(new KeyWrapper(index)))
                {
                    array[new KeyWrapper(index)] = valueToSet;
                }
                else
                {
                    array.Add(new KeyWrapper(index), valueToSet);
                }
            }
            else
            {
                var token = (CurrentNode as AST_Assignment).getToken();
                throw new Error("Can't assign to the variable '" + variableName + "' since it's of the type " + ReturnValueConversions.PrettyObjectType(rv.GetType()), Error.ErrorType.RUNTIME, token.LineNr, token.LinePosition);
            }
        }
示例#14
0
        private void ArrayLookup()
        {
            object index = PopValue();
            object array = m_currentScope.getValue(CurrentNode.getTokenString());
            object val   = null;

            if (array is Range)
            {
                //Console.WriteLine ("LOOKING UP KEY " + index + " IN RANGE " + array.ToString ());

                if (index.GetType() == typeof(float))
                {
                    Range range      = (Range)array;
                    float i          = range.step * (int)(float)index;
                    float theNumber  = range.start + i;
                    float lowerBound = 0;
                    float upperBound = 0;
                    if (range.step > 0)
                    {
                        lowerBound = range.start;
                        upperBound = range.end;
                    }
                    else
                    {
                        lowerBound = range.end;
                        upperBound = range.start;
                    }
                    if (theNumber < lowerBound)
                    {
                        throw new Error("Index " + index.ToString() + " is outside the range " + array.ToString());
                    }
                    else if (theNumber > upperBound)
                    {
                        throw new Error("Index " + index.ToString() + " is outside the range " + array.ToString());
                    }
                    val = (float)theNumber;
                    //Console.WriteLine("The result was " + val);
                }
                else
                {
                    throw new Error("Can't look up " + index.ToString() + " in the range " + array.ToString());
                }
            }
            else if (array.GetType() == typeof(SortedDictionary <KeyWrapper, object>))
            {
                //Console.WriteLine ("LOOKING UP KEY " + index + " of type " + index.GetType() + " IN ARRAY " + ReturnValueConversions.PrettyStringRepresenation(array));

                var a = array as SortedDictionary <KeyWrapper, object>;

                if (a.TryGetValue(new KeyWrapper(index), out val))
                {
                    //Console.WriteLine("The result was " + val);
                }
                else
                {
                    throw new Error("Can't find the index '" + index + "' (" + ReturnValueConversions.PrettyObjectType(index.GetType()) + ") in the array '" + CurrentNode.getTokenString() + "'", Error.ErrorType.RUNTIME, CurrentNode.getToken().LineNr, CurrentNode.getToken().LinePosition);
                }
            }
            else if (array.GetType() == typeof(object[]))
            {
                throw new Error("Illegal object[] array: " + ReturnValueConversions.PrettyStringRepresenation(array));
//				var a = (object[])array;
//				if(index.GetType() != typeof(float)) {
//					throw new Exception("Index " + index + " is of wrong type: " + index.GetType());
//				}
//				int i = (int)(float)index;
//				val = a[i];
            }
            else if (array.GetType() == typeof(string))
            {
                int i = 0;
                if (index.GetType() == typeof(float))
                {
                    i = (int)(float)index;
                }
                else if (index.GetType() == typeof(int))
                {
                    i = (int)index;
                }
                else
                {
                    throw new Error("Must use nr when looking up index in string");
                }
                string s = (string)array;
                if (i >= 0 && i < s.Length)
                {
                    val = s[i].ToString();
                }
                else
                {
                    throw new Error("The index '" + i + "' (" + index.GetType() + ") is outside the bounds of the string '" + CurrentNode.getTokenString() + "'", Error.ErrorType.RUNTIME, CurrentNode.getToken().LineNr, CurrentNode.getToken().LinePosition);
                }
            }
            else
            {
                throw new Error("Can't convert " + array.ToString() + " to an array (for lookup)");
            }

            PushValue(val);
        }
        static List <FunctionDefinition> CreateFunctionDefinitions(object pProgramTarget, Dictionary <string, FunctionDocumentation> functionDocumentations, MethodInfo[] methodInfos)
        {
            List <FunctionDefinition> functionDefinitions = new List <FunctionDefinition>();

            foreach (MethodInfo methodInfo in methodInfos)
            {
                if (!methodInfo.Name.StartsWith("API_"))
                {
                    continue;
                }

                MethodInfo lambdaMethodInfo = methodInfo;                 // "hard copy" because of c# lambda rules

                string shortname = lambdaMethodInfo.Name.Substring(4);

                List <ReturnValueType> parameterTypes     = new List <ReturnValueType> ();
                List <string>          parameterNames     = new List <string> ();
                List <string>          parameterTypeNames = new List <string> ();

                foreach (ParameterInfo parameterInfo in lambdaMethodInfo.GetParameters())
                {
                    var t = ReturnValueConversions.SystemTypeToReturnValueType(parameterInfo.ParameterType);
                    //Console.WriteLine("Registering parameter '" + parameterInfo.Name + "' (" + parameterInfo.ParameterType + ") with ReturnValueType " + t + " for function " + shortname);
                    parameterNames.Add(parameterInfo.Name);
                    parameterTypes.Add(t);
                    parameterTypeNames.Add(t.ToString().ToLower());
                }

                ExternalFunctionCreator.OnFunctionCall function = (sprakArguments => {
                    ParameterInfo[] realParamInfo = lambdaMethodInfo.GetParameters();

                    if (sprakArguments.Count() != realParamInfo.Length)
                    {
                        throw new Error("Should call '" + shortname + "' with " + realParamInfo.Length + " argument" + (realParamInfo.Length == 1 ? "" : "s"));
                    }

                    int i = 0;
                    foreach (object sprakArg in sprakArguments)
                    {
                        //Console.WriteLine(string.Format("Parameter {0} in function {1} is of type {2}", i, shortname, realParamInfo[i].ParameterType));

                        var realParamType = realParamInfo [i].ParameterType;

                        if (sprakArg.GetType() == typeof(SortedDictionary <KeyWrapper, object>))
                        {
                            sprakArguments[i] = (sprakArg as SortedDictionary <KeyWrapper, object>).Values.ToArray();
                        }

                        if (sprakArg.GetType() == typeof(int))
                        {
                            // YES, this is kind of a HACK (allowing definitions with int arguments, making them work like the were floats. Remove later!
                            sprakArguments[i] = (float)sprakArg;
                            realParamType = typeof(int);
                        }

                        if (acceptableTypes.Contains(realParamType))
                        {
                            // OK
                        }
                        else
                        {
                            throw new Error("Can't deal with parameter " + i.ToString() + " of type " + realParamType + " in function " + shortname);
                        }

                        i++;
                    }

                    //Console.WriteLine("supplied parameter count" + parameters.Count + " neededParamter count " + lamdaMethodInfo.GetParameters().Length);

                    object result = null;

                    try {
                        /*
                         * Console.WriteLine("Will call " + shortname  + " with sprak arguments:");
                         * int j = 0;
                         * foreach(var a in sprakArguments) {
                         *      Console.WriteLine(" Argument " + (j++) + ": " + ReturnValueConversions.PrettyStringRepresenation(a) + " (" + a.GetType() + ")");
                         * }
                         */
                        result = lambdaMethodInfo.Invoke(pProgramTarget, sprakArguments.ToArray());
                    }
                    catch (System.Reflection.TargetInvocationException e) {
                        //Console.WriteLine("Got an exception when calling the lambda: " + e.ToString());
                        //Console.WriteLine("The base exception: " + e.GetBaseException().ToString());
                        throw e.GetBaseException();
                    }

                    // HACK
                    if (lambdaMethodInfo.ReturnType == typeof(int))
                    {
                        return((float)(int)result);
                    }

                    if (lambdaMethodInfo.ReturnType.IsSubclassOf(typeof(Array)))
                    {
                        var dictArray = new SortedDictionary <KeyWrapper, object>();
                        int j = 0;
                        foreach (var o in (Array)result)
                        {
                            //Console.WriteLine(" - " + o.ToString());
                            dictArray.Add(new KeyWrapper((float)j++), o);
                        }
                        //Console.WriteLine("Converted object[] to SortedDictionary when returning from " + shortname + ": " + ReturnValueConversions.PrettyStringRepresenation(dictArray));
                        return(dictArray);
                    }

                    if (!acceptableTypes.Contains(lambdaMethodInfo.ReturnType))
                    {
                        throw new Error("Function '" + shortname + "' can't return value of type " + lambdaMethodInfo.ReturnType.ToString());
                    }

                    if (lambdaMethodInfo.ReturnType == typeof(void))
                    {
                        //Console.WriteLine("Returning void from " + shortname);
                        return(VoidType.voidType);
                    }
                    else
                    {
                        //Console.WriteLine("Returning from " + shortname + ": " + ReturnValueConversions.PrettyStringRepresenation(result));
                        return(result);
                    }
                });

                ReturnValueType returnValueType = ReturnValueConversions.SystemTypeToReturnValueType(lambdaMethodInfo.ReturnType);

                FunctionDocumentation doc;

                if (functionDocumentations.ContainsKey(shortname))
                {
                    doc = functionDocumentations [shortname];
                }
                else
                {
                    doc = FunctionDocumentation.Default();
                }

                functionDefinitions.Add(new FunctionDefinition(
                                            returnValueType.ToString(),
                                            shortname,
                                            parameterTypeNames.ToArray(),
                                            parameterNames.ToArray(),
                                            function, // The lambda
                                            doc));
            }

            return(functionDefinitions);
        }