public void BuildReturnParameters(RuleInvocation invocation, SequenceVariable[] ReturnVars, out String returnParameterDeclarations, out String returnArguments, out String returnAssignments, out String returnParameterDeclarationsAllCall, out String intermediateReturnAssignmentsAllCall, out String returnAssignmentsAllCall) { // can't use the normal xgrs variables for return value receiving as the type of an out-parameter must be invariant // this is bullshit, as it is perfectly safe to assign a subtype to a variable of a supertype // so we create temporary variables of exact type, which are used to receive the return values, // and finally we assign these temporary variables to the real xgrs variables StringBuilder sbReturnParameterDeclarations = new StringBuilder(); StringBuilder sbReturnArguments = new StringBuilder(); StringBuilder sbReturnAssignments = new StringBuilder(); StringBuilder sbReturnParameterDeclarationsAllCall = new StringBuilder(); StringBuilder sbIntermediateReturnAssignmentsAllCall = new StringBuilder(); StringBuilder sbReturnAssignmentsAllCall = new StringBuilder(); for (int i = 0; i < actionsTypeInformation.rulesToOutputTypes[invocation.PackagePrefixedName].Count; ++i) { String varName; if (ReturnVars.Length != 0) { varName = GetUniqueId() + ReturnVars[i].PureName; } else { varName = GetUniqueId(); } String typeName = actionsTypeInformation.rulesToOutputTypes[invocation.PackagePrefixedName][i]; String tmpvarName = "tmpvar_" + varName; sbReturnParameterDeclarations.Append(TypesHelper.XgrsTypeToCSharpType(typeName, model)); sbReturnParameterDeclarations.Append(" "); sbReturnParameterDeclarations.Append(tmpvarName); sbReturnParameterDeclarations.Append("; "); String returnListValueVarType = typeName; String tmpvarListName = "tmpvarlist_" + varName; if (ReturnVars.Length != 0 && ReturnVars[i].Type != "" && ReturnVars[i].Type.StartsWith("array<")) { returnListValueVarType = TypesHelper.ExtractSrc(ReturnVars[i].Type); } if (ReturnVars.Length != 0) { sbReturnParameterDeclarationsAllCall.Append("List<"); sbReturnParameterDeclarationsAllCall.Append(TypesHelper.XgrsTypeToCSharpType(returnListValueVarType, model)); sbReturnParameterDeclarationsAllCall.Append("> "); sbReturnParameterDeclarationsAllCall.Append(tmpvarListName); sbReturnParameterDeclarationsAllCall.Append(" = new List<"); sbReturnParameterDeclarationsAllCall.Append(TypesHelper.XgrsTypeToCSharpType(returnListValueVarType, model)); sbReturnParameterDeclarationsAllCall.Append(">(); "); } sbReturnArguments.Append(", out "); sbReturnArguments.Append(tmpvarName); if (ReturnVars.Length != 0) { sbReturnAssignments.Append(SetVar(ReturnVars[i], tmpvarName)); sbIntermediateReturnAssignmentsAllCall.Append(tmpvarListName); sbIntermediateReturnAssignmentsAllCall.Append(".Add(("); sbIntermediateReturnAssignmentsAllCall.Append(TypesHelper.XgrsTypeToCSharpType(returnListValueVarType, model)); sbIntermediateReturnAssignmentsAllCall.Append(")"); sbIntermediateReturnAssignmentsAllCall.Append(tmpvarName); sbIntermediateReturnAssignmentsAllCall.Append("); "); sbReturnAssignmentsAllCall.Append(SetVar(ReturnVars[i], tmpvarListName)); } } returnParameterDeclarations = sbReturnParameterDeclarations.ToString(); returnArguments = sbReturnArguments.ToString(); returnAssignments = sbReturnAssignments.ToString(); returnParameterDeclarationsAllCall = sbReturnParameterDeclarationsAllCall.ToString(); intermediateReturnAssignmentsAllCall = sbIntermediateReturnAssignmentsAllCall.ToString(); returnAssignmentsAllCall = sbReturnAssignmentsAllCall.ToString(); }
// implicit casts supported by GrGen: // enum -> (integer) number // integer number -> larger integer number (note that there are no operators working on byte and short) // floating point number -> larger floating point number // integer number -> floating point number // everything -> string (for convenient emitting) // explicit casts supported by GrGen: // integer number -> smaller integer number // floating point number -> smaller floating point number // floating point number -> integer number // everything -> object /// <summary> /// Returns the types to which the operands must be casted to, /// for the types of the left and right operands and the operator given. /// Used for type checking and casting at compile time. /// Returns "" if the type can only be determined at runtime. /// Returns "-" in case of a type error. /// </summary> public static string Balance(SequenceExpressionType op, string left, string right, IGraphModel model) { string result; switch (op) { case SequenceExpressionType.Equal: case SequenceExpressionType.NotEqual: result = BalanceArithmetic(left, right, model); if (result == "") { return(""); } if (result == "-") { result = BalanceString(left, right, model); if (result == "") { return(""); } if (result == "-") { result = BalanceGraphElement(left, right, model); if (result == "") { return(""); } if (result == "-") { result = BalanceExternalType(left, right, model); if (result == "") { return(""); } if (result == "-") { if (left == right) { return(left); } else { return("-"); } } } } } return(result); case SequenceExpressionType.Lower: case SequenceExpressionType.LowerEqual: case SequenceExpressionType.Greater: case SequenceExpressionType.GreaterEqual: result = BalanceArithmetic(left, right, model); if (result == "-") { if (left == right && (left.StartsWith("set<") || left.StartsWith("map<") || left.StartsWith("array<") || left.StartsWith("deque<"))) { return(left); } result = BalanceExternalType(left, right, model); return(result); } return(result); case SequenceExpressionType.StructuralEqual: return("graph"); case SequenceExpressionType.Plus: result = BalanceArithmetic(left, right, model); if (result == "") { return(""); } if (result == "-") { result = BalanceString(left, right, model); if (result == "") { return(""); } if (result == "-") { if (left == right && (left.StartsWith("array<") || left.StartsWith("deque<"))) { return(left); } else { return("-"); } } } return(result); case SequenceExpressionType.Minus: case SequenceExpressionType.Mul: case SequenceExpressionType.Div: case SequenceExpressionType.Mod: result = BalanceArithmetic(left, right, model); return(result); case SequenceExpressionType.Except: if (left == "" || right == "") { return(""); } if (left == right && left.StartsWith("set<")) { return(left); } if (left == right && left.StartsWith("map<")) { return(left); } if (left.StartsWith("map<") && right.StartsWith("set<") && TypesHelper.ExtractSrc(left) == TypesHelper.ExtractSrc(right)) { return(left); } return("-"); case SequenceExpressionType.StrictAnd: case SequenceExpressionType.StrictOr: if (left == "" || right == "") { return(""); } if (left == right && left == "boolean") { return(left); } if (left == right && left.StartsWith("set<")) { return(left); } if (left == right && left.StartsWith("map<")) { return(left); } return("-"); default: return(""); } }