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); }
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); } } }
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; // } }
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); }
/// <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); }
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))); } }
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); } }
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"); } }
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"); }
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"); }
private static object API_type(object[] args) { return(ReturnValueConversions.PrettyObjectType(args[0].GetType())); }
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); } }
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); }