private static void WriteOperatorShortcut(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.VariableType type, G25.fgs fgs, FuncArgInfo[] FAI, G25.Operator op) { // C# does not allow return type of ++ or -- to be different from input type if (S.OutputCSharp() && (op.IsIncrement() || op.IsDecrement()) && (fgs.ReturnTypeName != type.GetName())) { return; } string operatorCall = getOperatorCall(S, fgs, FAI); SB.AppendLine(""); int nbTabs = 1; // output comment new Comment("operator for " + operatorCall).Write(SB, S, nbTabs); bool inline = false; bool staticFunc = true; string returnType = FT.GetMangledName(S, fgs.ReturnTypeName); FuncArgInfo returnArgument = null; SB.Append('\t', nbTabs); Functions.WriteDeclaration(SB, S, cgd, inline, staticFunc, returnType, "operator " + op.Symbol, returnArgument, FAI); SB.AppendLine(" {"); SB.Append('\t', nbTabs + 1); SB.Append("return "); SB.Append(operatorCall); SB.AppendLine(";"); SB.Append('\t', nbTabs); SB.AppendLine("}"); }
private static string GetComment(Specification S, bool declOnly, G25.fgs FGS, G25.Operator op, G25.FloatType FT, bool assign) { StringBuilder SB = new StringBuilder(); if ((S.OutputCpp()) && op.IsUnaryInPlace()) { if (op.IsPrefix) { SB.Append("returns (" + FGS.ArgumentVariableNames[0] + " = " + FGS.OutputName + "(" + FGS.ArgumentVariableNames[0] + "))"); } else { SB.Append("returns input value of " + FGS.ArgumentVariableNames[0] + ", but sets " + FGS.ArgumentVariableNames[0] + " to " + FGS.OutputName + "(" + FGS.ArgumentVariableNames[0] + ")"); } } else if (assign) { SB.Append("returns (" + FGS.ArgumentVariableNames[0] + " = " + FGS.OutputName + "(" + FGS.ArgumentVariableNames[0]); SB.Append(", " + FGS.ArgumentVariableNames[1]); SB.Append("))"); } else { SB.Append("returns " + FGS.OutputName + "(" + FGS.ArgumentVariableNames[0]); if (op.IsBinary()) { SB.Append(", " + FGS.ArgumentVariableNames[1]); } SB.Append(")"); } return(SB.ToString()); }
private static string GetFuncDecl(Specification S, bool declOnly, G25.fgs FGS, G25.Operator op, G25.FloatType FT, bool assign, bool constVal, bool returnByReference) { StringBuilder SB = new StringBuilder(); string inlineStr = G25.CG.Shared.Util.GetInlineString(S, (!declOnly) && S.m_inlineOperators, " "); string returnTypeName = (FGS.m_returnTypeName.Length > 0) ? FGS.m_returnTypeName : FT.type; if (!S.IsFloatType(returnTypeName)) { returnTypeName = FT.GetMangledName(S, returnTypeName); } string arg1typeName = FT.GetMangledName(S, FGS.ArgumentTypeNames[0]); string arg2typeName = (FGS.NbArguments > 1) ? FT.GetMangledName(S, FGS.ArgumentTypeNames[1]) : ""; SB.Append(inlineStr); SB.Append(returnTypeName); SB.Append(" "); if (returnByReference) { SB.Append("&"); } SB.Append("operator"); SB.Append(op.Symbol); if (assign) { SB.Append("="); } SB.Append("("); if (constVal) { SB.Append("const "); } SB.Append(arg1typeName); SB.Append(" &"); SB.Append(FGS.ArgumentVariableNames[0]); if (op.IsBinary()) { SB.Append(", const "); SB.Append(arg2typeName); SB.Append(" &"); SB.Append(FGS.ArgumentVariableNames[1]); } else if ((S.OutputCpp()) && op.IsPostfixUnary()) { // add a dummy int argument so C++ knows this is a unary postfix op SB.Append(", int"); } SB.Append(")"); return(SB.ToString()); }
private static void WriteOperator(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, bool declOnly, G25.fgs FGS, G25.Operator op) { bool comment = declOnly || S.m_inlineOperators; bool returnTypeEqualsFirstArgument = FGS.ReturnTypeName == FGS.ArgumentTypeNames[0]; foreach (string floatName in FGS.FloatNames) { G25.FloatType FT = S.GetFloatType(floatName); string funcName = FGS.OutputName; { // regular operator bool assign = false; bool returnByReference = returnTypeEqualsFirstArgument && op.IsPrefixUnary() && op.IsUnaryInPlace(); // for unary prefix ++ and --, needs to return by reference (&) bool constVal = !(op.IsUnaryInPlace() && returnTypeEqualsFirstArgument); string funcDecl = GetFuncDecl(S, declOnly, FGS, op, FT, assign, constVal, returnByReference); if (comment) // comment? { SB.AppendLine("/// " + GetComment(S, declOnly, FGS, op, FT, assign)); } SB.Append(funcDecl); if (declOnly) { SB.AppendLine(";"); } else { SB.AppendLine(" {"); WriteOperatorBody(SB, S, cgd, FGS, op, funcName); SB.AppendLine("}"); } } // add an extra operator with assignment (like +=) ? if (op.IsBinary() && returnTypeEqualsFirstArgument) { bool assign = true; bool constVal = false; bool returnByReference = true; // todo: for unary prefix ++ needs to return by reference (&) string funcDecl = GetFuncDecl(S, declOnly, FGS, op, FT, assign, constVal, returnByReference); if (comment) // comment? { SB.AppendLine("/// " + GetComment(S, declOnly, FGS, op, FT, assign)); } SB.Append(funcDecl); if (declOnly) { SB.AppendLine(";"); } else { SB.AppendLine(" {"); SB.Append("\treturn (" + FGS.ArgumentVariableNames[0] + " = " + funcName + "(" + FGS.ArgumentVariableNames[0]); SB.AppendLine(", " + FGS.ArgumentVariableNames[1] + "));"); SB.AppendLine("}"); } } } }
private static void WriteOperatorBody(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, G25.fgs FGS, G25.Operator op, string funcName) { bool returnTypeEqualsFirstArgument = FGS.ReturnTypeName == FGS.ArgumentTypeNames[0]; if ((S.OutputCpp()) && op.IsUnaryInPlace() && returnTypeEqualsFirstArgument) // special unary case for C++ { if (op.IsPrefix) { SB.AppendLine("\t" + FGS.ArgumentVariableNames[0] + " = " + funcName + "(" + FGS.ArgumentVariableNames[0] + ");"); SB.AppendLine("\treturn " + FGS.ArgumentVariableNames[0] + ";"); } else { SB.AppendLine("\t" + FGS.ReturnTypeName + " retVal(" + FGS.ArgumentVariableNames[0] + ");"); SB.AppendLine("\t" + FGS.ArgumentVariableNames[0] + " = " + funcName + "(" + FGS.ArgumentVariableNames[0] + ");"); SB.AppendLine("\treturn retVal;"); } } else // regular operator function { SB.Append("\treturn " + funcName + "(" + FGS.ArgumentVariableNames[0]); if (op.IsBinary()) { SB.Append(", " + FGS.ArgumentVariableNames[1]); } SB.AppendLine(");"); } }