protected override void WriteCall(CiExpr obj, CiMethod method, CiExpr[] args, CiPriority parent) { if (obj == null) { WriteCCall(null, method, args); } else if (obj.IsReferenceTo(CiSystem.MathClass)) { WriteMathCall(method, args); } else if (method == CiSystem.ConsoleWrite) { WriteConsoleWrite(args, false); } else if (method == CiSystem.ConsoleWriteLine) { WriteConsoleWrite(args, true); } else { WriteCCall(obj, method, args); } }
protected override void WriteCall(CiExpr obj, CiMethod method, CiExpr[] args, CiPriority parent) { if (obj == null) { WriteName(method); WriteArgsInParentheses(method, args); } else if (obj.IsReferenceTo(CiSystem.MathClass)) { Include("cmath"); Write("std::"); WriteMathCall(method, args); } else if (method == CiSystem.StringContains) { if (parent > CiPriority.Equality) { Write('('); } WriteStringMethod(obj, "find", method, args); Write(" != std::string::npos"); if (parent > CiPriority.Equality) { Write(')'); } } else if (method == CiSystem.StringIndexOf) { Write("static_cast<int>("); WriteStringMethod(obj, "find", method, args); Write(')'); } else if (method == CiSystem.StringLastIndexOf) { Write("static_cast<int>("); WriteStringMethod(obj, "rfind", method, args); Write(')'); } else if (method == CiSystem.StringStartsWith) { WriteStringMethod(obj, "starts_with", method, args); } else if (method == CiSystem.StringEndsWith) { WriteStringMethod(obj, "ends_with", method, args); } else if (method == CiSystem.StringSubstring) { WriteStringMethod(obj, "substr", method, args); } else if (obj.Type is CiArrayType && method.Name == "CopyTo") { Include("algorithm"); Write("std::copy_n("); WriteArrayPtrAdd(obj, args[0]); Write(", "); args[3].Accept(this, CiPriority.Statement); Write(", "); WriteArrayPtrAdd(args[1], args[2]); Write(')'); } else if (obj.Type is CiListType list && method.Name == "Add") { if (method.Parameters.Count == 0) { string suffix = ".emplace_back()"; if (!this.AtLineStart) { if (list.ElementType is CiArrayStorageType) { suffix = ".emplace_back().data()"; } else { Write('&'); } } obj.Accept(this, CiPriority.Primary); Write(suffix); } else { obj.Accept(this, CiPriority.Primary); Write(".push_back"); WriteArgsInParentheses(method, args); } }
void WriteConsoleWrite(CiExpr obj, CiExpr[] args, bool newLine) { Include("iostream"); Write(obj.IsReferenceTo(CiSystem.ConsoleError) ? "std::cerr" : "std::cout"); if (args.Length == 1) { if (args[0] is CiInterpolatedString interpolated) { bool uppercase = false; bool hex = false; char flt = 'G'; foreach (CiInterpolatedPart part in interpolated.Parts) { switch (part.Format) { case 'E': case 'G': case 'X': if (!uppercase) { Write(" << std::uppercase"); uppercase = true; } break; case 'e': case 'g': case 'x': if (uppercase) { Write(" << std::nouppercase"); uppercase = false; } break; default: break; } switch (part.Format) { case 'E': case 'e': if (flt != 'E') { Write(" << std::scientific"); flt = 'E'; } break; case 'F': case 'f': if (flt != 'F') { Write(" << std::fixed"); flt = 'F'; } break; case 'X': case 'x': if (!hex) { Write(" << std::hex"); hex = true; } break; default: if (hex) { Write(" << std::dec"); hex = false; } if (flt != 'G') { Write(" << std::defaultfloat"); flt = 'G'; } break; } if (part.Prefix.Length > 0) { Write(" << "); WriteLiteral(part.Prefix); } Write(" << "); part.Argument.Accept(this, CiPriority.Mul); } if (uppercase) { Write(" << std::nouppercase"); } if (hex) { Write(" << std::dec"); } if (flt != 'G') { Write(" << std::defaultfloat"); } if (interpolated.Suffix.Length > 0) { Write(" << "); if (newLine) { WriteStringLiteralWithNewLine(interpolated.Suffix); return; } WriteLiteral(interpolated.Suffix); } } else { Write(" << "); if (newLine && args[0] is CiLiteral literal) { WriteStringLiteralWithNewLine((string)literal.Value); return; } args[0].Accept(this, CiPriority.Mul); } } if (newLine) { Write(" << '\\n'"); } }
protected override void WriteCall(CiExpr obj, CiMethod method, CiExpr[] args, CiPriority parent) { if (obj == null) { WriteName(method); WriteArgsInParentheses(method, args); } else if (obj.IsReferenceTo(CiSystem.MathClass)) { Include("cmath"); Write("std::"); WriteMathCall(method, args); } else if (method == CiSystem.StringContains) { if (parent > CiPriority.Equality) { Write('('); } WriteStringMethod(obj, "find", method, args); Write(" != std::string::npos"); if (parent > CiPriority.Equality) { Write(')'); } } else if (method == CiSystem.StringIndexOf) { Write("static_cast<int>("); WriteStringMethod(obj, "find", method, args); Write(')'); } else if (method == CiSystem.StringLastIndexOf) { Write("static_cast<int>("); WriteStringMethod(obj, "rfind", method, args); Write(')'); } else if (method == CiSystem.StringStartsWith) { WriteStringMethod(obj, "starts_with", method, args); } else if (method == CiSystem.StringEndsWith) { WriteStringMethod(obj, "ends_with", method, args); } else if (method == CiSystem.StringSubstring) { WriteStringMethod(obj, "substr", method, args); } else if (obj.Type is CiArrayType array && method.Name == "BinarySearch") { Include("algorithm"); if (parent > CiPriority.Add) { Write('('); } Write("std::lower_bound("); if (args.Length == 1) { obj.Accept(this, CiPriority.Primary); Write(".begin(), "); obj.Accept(this, CiPriority.Primary); // FIXME: side effect Write(".end()"); } else { WriteArrayPtrAdd(obj, args[1]); Write(", "); WriteArrayPtrAdd(obj, args[1]); // FIXME: side effect Write(" + "); args[2].Accept(this, CiPriority.Add); } Write(", "); args[0].Accept(this, CiPriority.Statement); Write(") - "); WriteArrayPtr(obj, CiPriority.Mul); if (parent > CiPriority.Add) { Write(')'); } }
protected override void WriteCall(CiExpr obj, CiMethod method, CiExpr[] args, CiPriority parent) { if (obj == null) { WriteCCall(null, method, args); } else if (method == CiSystem.StringStartsWith) { if (IsOneAsciiString(args[0], out char c)) { if (parent > CiPriority.Equality) { Write('('); } obj.Accept(this, CiPriority.Primary); Write("[0] == "); WriteCharLiteral(c); if (parent > CiPriority.Equality) { Write(')'); } } else { this.StringStartsWith = true; WriteCall("CiString_StartsWith", obj, args[0]); } } else if (obj.Type is CiArrayType && method.Name == "CopyTo") { Write("for (size_t _i = 0; _i < "); args[3].Accept(this, CiPriority.Rel); // FIXME: side effect in every iteration WriteLine("; _i++)"); Write('\t'); args[1].Accept(this, CiPriority.Primary); // FIXME: side effect in every iteration Write('['); if (!args[2].IsLiteralZero) { args[2].Accept(this, CiPriority.Add); // FIXME: side effect in every iteration Write(" + "); } Write("_i] = "); obj.Accept(this, CiPriority.Primary); // FIXME: side effect in every iteration Write('['); if (!args[0].IsLiteralZero) { args[0].Accept(this, CiPriority.Add); // FIXME: side effect in every iteration Write(" + "); } Write("_i]"); } else if (obj.Type is CiArrayType && method.Name == "Fill") { WriteArrayFill(obj, args); } else if (method == CiSystem.UTF8GetByteCount) { WriteStringLength(args[0]); } else if (method == CiSystem.UTF8GetBytes) { Write("for (size_t _i = 0; "); args[0].Accept(this, CiPriority.Primary); // FIXME: side effect in every iteration WriteLine("[_i] != '\\0'; _i++)"); Write('\t'); args[1].Accept(this, CiPriority.Primary); // FIXME: side effect in every iteration Write('['); if (!args[2].IsLiteralZero) { args[2].Accept(this, CiPriority.Add); // FIXME: side effect in every iteration Write(" + "); } Write("_i] = "); args[0].Accept(this, CiPriority.Primary); // FIXME: side effect in every iteration Write("[_i]"); } else if (obj.IsReferenceTo(CiSystem.MathClass)) { WriteMathCall(method, args); } else if (method == CiSystem.ConsoleWrite) { WriteConsoleWrite(args, false); } else if (method == CiSystem.ConsoleWriteLine) { WriteConsoleWrite(args, true); } else { WriteCCall(obj, method, args); } }