Beispiel #1
0
        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("");
            }
        }