protected override void WriteEqual(CiBinaryExpr expr, CiPriority parent, bool not) { if (NeedStringPtrData(expr.Left) && expr.Right.Type == CiSystem.NullType) { WriteCoerced(CiSystem.StringPtrType, expr.Left, CiPriority.Primary); Write(".data()"); Write(GetEqOp(not)); Write("nullptr"); } else if (expr.Left.Type == CiSystem.NullType && NeedStringPtrData(expr.Right)) { Write("nullptr"); Write(GetEqOp(not)); WriteCoerced(CiSystem.StringPtrType, expr.Right, CiPriority.Primary); Write(".data() "); } else { base.WriteEqual(expr, parent, not); } }
protected override void WriteEqual(CiBinaryExpr expr, CiPriority parent, bool not) { if ((expr.Left.Type is CiStringType && expr.Right.Type != CiSystem.NullType) || (expr.Right.Type is CiStringType && expr.Left.Type != CiSystem.NullType)) { this.StringEquals = true; if (not) { Write('!'); } Write("streq("); expr.Left.Accept(this, CiPriority.Statement); Write(", "); expr.Right.Accept(this, CiPriority.Statement); Write(')'); } else { base.WriteEqual(expr, parent, not); } }
protected override void WriteCoercedInternal(CiType type, CiExpr expr, CiPriority parent) { if (type is CiClass && expr is CiAggregateInitializer init) { Write("new "); Write(type.Name); string prefix = " { "; foreach (CiBinaryExpr field in init.Items) { Write(prefix); WriteName(((CiSymbolReference)field.Left).Symbol); Write(" = "); WriteCoerced(field.Left.Type, field.Right, CiPriority.Argument); prefix = ", "; } Write(" }"); } else { base.WriteCoercedInternal(type, expr, parent); } }
public override CiExpr Visit(CiInterpolatedString expr, CiPriority parent) { if (expr.Suffix.Length == 0 && expr.Parts.Length == 1 && expr.Parts[0].Prefix.Length == 0 && expr.Parts[0].WidthExpr == null && expr.Parts[0].Format == ' ') { CiExpr arg = expr.Parts[0].Argument; if (arg.Type == CiSystem.LongType) { Write("Long"); } else if (arg.Type == CiSystem.DoubleType || arg.Type == CiSystem.FloatIntType) { Write("Double"); } else if (arg.Type == CiSystem.FloatType) { Write("Float"); } else if (arg.Type is CiStringType) { arg.Accept(this, parent); return(expr); } else { Write("Integer"); } WriteCall(".toString", arg); } else { Write("String.format("); WritePrintf(expr, false); } return(expr); }
public override CiExpr Visit(CiAggregateInitializer expr, CiPriority parent) { if (((CiArrayStorageType)expr.Type).ElementType is CiNumericType number) { char c = GetArrayCode(number); if (c == 'B') { Write("bytes("); } else { Include("array"); Write("array.array(\""); Write(c); Write("\", "); } base.Visit(expr, parent); Write(')'); return(expr); } return(base.Visit(expr, parent)); }
protected bool WriteJavaMatchProperty(CiSymbolReference expr, CiPriority parent) { if (expr.Symbol == CiSystem.MatchStart) { expr.Left.Accept(this, CiPriority.Primary); Write(".start()"); return(true); } if (expr.Symbol == CiSystem.MatchEnd) { expr.Left.Accept(this, CiPriority.Primary); Write(".end()"); return(true); } if (expr.Symbol == CiSystem.MatchLength) { if (parent > CiPriority.Add) { Write('('); } expr.Left.Accept(this, CiPriority.Primary); Write(".end() - "); expr.Left.Accept(this, CiPriority.Primary); // FIXME: side effect Write(".start()"); if (parent > CiPriority.Add) { Write(')'); } return(true); } if (expr.Symbol == CiSystem.MatchValue) { expr.Left.Accept(this, CiPriority.Primary); Write(".group()"); return(true); } return(false); }
public override CiExpr Visit(CiInterpolatedString expr, CiPriority parent) { Write("$\""); foreach (CiInterpolatedPart part in expr.Parts) { foreach (char c in part.Prefix) { if (c == '{') { Write("{{"); } else { WriteEscapedChar(c); } } if (part.Argument != null) { Write('{'); part.Argument.Accept(this, CiPriority.Statement); if (part.WidthExpr != null) { Write(','); Write(part.Width); } if (part.Format != ' ') { Write(':'); Write(part.Format); } Write('}'); } } Write('"'); return(expr); }
public override CiExpr Visit(CiSymbolReference expr, CiPriority parent) { if (expr.Symbol == CiSystem.CollectionCount) { WriteStringLength(expr.Left); } else if (WriteJavaMatchProperty(expr, parent)) { return(expr); } else if (expr.Left != null && expr.Left.IsReferenceTo(CiSystem.MathClass)) { Include("math"); Write(expr.Symbol == CiSystem.MathNaN ? "math.nan" : expr.Symbol == CiSystem.MathNegativeInfinity ? "-math.inf" : expr.Symbol == CiSystem.MathPositiveInfinity ? "math.inf" : throw new NotImplementedException(expr.ToString())); } else { return(base.Visit(expr, parent)); } return(expr); }
public override CiExpr Visit(CiInterpolatedString expr, CiPriority parent) { throw new NotImplementedException("Interpolated strings not supported in OpenCL C"); }
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); } }
void WriteChildWithSuggestedParentheses(CiBinaryExpr parent, CiExpr child, CiPriority suggestedParentPriority, bool assoc) { if (assoc && GetPriority(parent) == GetPriority(child)) Write(child); else WriteChild(suggestedParentPriority, child); }
protected override void WriteCall(CiExpr obj, CiMethod method, CiExpr[] args, CiPriority parent) { if (obj == null) { WriteLocalName(method, CiPriority.Primary); WriteArgsInParentheses(method, args); } else if (method == CiSystem.StringSubstring) { obj.Accept(this, CiPriority.Primary); Write(".substring("); args[0].Accept(this, CiPriority.Statement); if (args.Length == 2) { Write(", "); WriteAdd(args[0], args[1]); // TODO: side effect } Write(')'); } else if (obj.Type is CiArrayType && method.Name == "CopyTo") { AddLibrary(GenJsMethod.CopyArray, "copyArray : function(sa, soffset, da, doffset, length)", "if (typeof(sa.subarray) == \"function\" && typeof(da.set) == \"function\")", "\tda.set(sa.subarray(soffset, soffset + length), doffset);", "else", "\tfor (let i = 0; i < length; i++)", "\t\tda[doffset + i] = sa[soffset + i];"); Write("Ci.copyArray("); obj.Accept(this, CiPriority.Statement); Write(", "); WriteArgs(method, args); Write(')'); } else if (method == CiSystem.CollectionClear) { if (obj.Type is CiDictionaryType) { Write("for (const key in "); obj.Accept(this, CiPriority.Statement); WriteLine(')'); Write("\tdelete "); obj.Accept(this, CiPriority.Primary); // FIXME: side effect Write("[key];"); } else { obj.Accept(this, CiPriority.Primary); Write(".length = 0"); } } else if (WriteListAddInsert(obj, method, args, "push", "splice", ", 0, ")) { // done } else if (method == CiSystem.ListRemoveAt) { obj.Accept(this, CiPriority.Primary); Write(".splice("); args[0].Accept(this, CiPriority.Statement); Write(", 1)"); } else if (method == CiSystem.ListRemoveRange) { obj.Accept(this, CiPriority.Primary); Write(".splice("); args[0].Accept(this, CiPriority.Statement); Write(", "); args[1].Accept(this, CiPriority.Statement); Write(')'); } else if (obj.Type is CiDictionaryType dict && method.Name == "Add") { if (parent > CiPriority.Assign) { Write('('); } obj.Accept(this, CiPriority.Primary); Write('['); args[0].Accept(this, CiPriority.Statement); Write("] = "); WriteNewStorage(dict.ValueType); if (parent > CiPriority.Assign) { Write(')'); } }
public override CiExpr Visit(CiInterpolatedString expr, CiPriority parent) { Write('`'); foreach (CiInterpolatedPart part in expr.Parts) { string s = part.Prefix; for (int i = 0; i < s.Length; i++) { char c = s[i]; if (c == '`' || (c == '$' && i + 1 < s.Length && s[i + 1] == '{')) { Write('\\'); } WriteEscapedChar(c); } if (part.Argument != null) { Write("${"); if (part.Width != 0 || part.Format != ' ') { part.Argument.Accept(this, CiPriority.Primary); if (part.Argument.Type is CiNumericType) { switch (part.Format) { case 'x': Write(".toString(16)"); break; case 'X': Write(".toString(16).toUpperCase()"); break; default: Write(".toString()"); break; } } if (part.Width > 0) { Write(".padStart("); Write(part.Width); Write(')'); } else if (part.Width < 0) { Write(".padEnd("); Write(-part.Width); Write(')'); } } else { part.Argument.Accept(this, CiPriority.Statement); } Write('}'); } } Write('`'); return(expr); }
protected void WriteMulDiv(CiPriority firstPriority, CiMethodCall expr) { WriteChild(firstPriority, expr.Obj); Write(" * "); WriteChild(CiPriority.Multiplicative, expr.Arguments[0]); Write(" / "); WriteNonAssocChild(CiPriority.Multiplicative, expr.Arguments[1]); Write(')'); }
protected override void WriteNew(CiClass klass, CiPriority parent) { WriteName(klass); Write("()"); }
protected override void WriteComparison(CiBinaryExpr expr, CiPriority parent, CiPriority child, string op) { if (expr.Left.IsIndexing && expr.Left is CiBinaryExpr indexing && indexing.Left.Type is CiStringType && expr.Right is CiLiteral literal && literal.Value is long c && IsAscii(c)) { if (parent > child) { Write('('); } expr.Left.Accept(this, child); Write(op); WriteCharLiteral((char)c); if (parent > child) { Write(')'); } }
protected abstract void WriteEqualString(CiExpr left, CiExpr right, CiPriority parent, bool not);
public override CiExpr Visit(CiLiteral expr, CiPriority parent) { WriteLiteral(expr.Value); return(expr); }
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 void WriteNonAssocChild(CiPriority parentPriority, CiExpr child) { if (GetPriority(child) <= parentPriority) { Write('('); Write(child); Write(')'); } else Write(child); }
protected override void WriteCall(CiExpr obj, CiMethod method, CiExpr[] args, CiPriority parent) { if (obj == null) { WriteName(method); WriteArgsInParentheses(method, args); } else if ((method == CiSystem.StringIndexOf || method == CiSystem.StringLastIndexOf) && IsOneAsciiString(args[0], out char c)) { obj.Accept(this, CiPriority.Primary); Write('.'); Write(method.Name); Write('('); WriteCharLiteral(c); Write(')'); } else if (method == CiSystem.UTF8GetString) { Include("System.Text"); Write("Encoding.UTF8.GetString"); WriteArgsInParentheses(method, args); } else if (method == CiSystem.RegexCompile) { Include("System.Text.RegularExpressions"); Write("new Regex"); WriteArgsInParentheses(method, args); } else if (method == CiSystem.MatchFindStr) { Include("System.Text.RegularExpressions"); Write('('); obj.Accept(this, CiPriority.Assign); Write(" = Regex.Match"); WriteArgsInParentheses(method, args); Write(").Success"); } else if (method == CiSystem.MatchFindRegex) { Include("System.Text.RegularExpressions"); Write('('); obj.Accept(this, CiPriority.Assign); Write(" = "); WriteCall(args[1], "Match", args[0]); Write(").Success"); } else if (method == CiSystem.MatchGetCapture) { obj.Accept(this, CiPriority.Primary); Write(".Groups["); args[0].Accept(this, CiPriority.Statement); Write("].Value"); } else if (obj.Type is CiArrayType array && method.Name == "BinarySearch") { Include("System"); Write("Array.BinarySearch("); obj.Accept(this, CiPriority.Statement); Write(", "); if (args.Length == 3) { args[1].Accept(this, CiPriority.Statement); Write(", "); args[2].Accept(this, CiPriority.Statement); Write(", "); } WriteNotPromoted(array.ElementType, args[0]); Write(')'); }
public override CiExpr Visit(CiInterpolatedString expr, CiPriority parent) { Write('`'); foreach (CiInterpolatedPart part in expr.Parts) { WriteInterpolatedLiteral(part.Prefix); Write("${"); if (part.Width != 0 || part.Format != ' ') { part.Argument.Accept(this, CiPriority.Primary); if (part.Argument.Type is CiNumericType) { switch (part.Format) { case 'E': Write(".toExponential("); if (part.Precision >= 0) { VisitLiteralLong(part.Precision); } Write(").toUpperCase()"); break; case 'e': Write(".toExponential("); if (part.Precision >= 0) { VisitLiteralLong(part.Precision); } Write(')'); break; case 'F': case 'f': Write(".toFixed("); if (part.Precision >= 0) { VisitLiteralLong(part.Precision); } Write(')'); break; case 'X': Write(".toString(16).toUpperCase()"); break; case 'x': Write(".toString(16)"); break; default: Write(".toString()"); break; } if (part.Precision >= 0 && "DdXx".IndexOf(part.Format) >= 0) { Write(".padStart("); VisitLiteralLong(part.Precision); Write(", \"0\")"); } } if (part.Width > 0) { Write(".padStart("); VisitLiteralLong(part.Width); Write(')'); } else if (part.Width < 0) { Write(".padEnd("); VisitLiteralLong(-part.Width); Write(')'); } } else { part.Argument.Accept(this, CiPriority.Argument); } Write('}'); } WriteInterpolatedLiteral(expr.Suffix); Write('`'); return(expr); }
protected override void WriteCall(CiExpr obj, CiMethod method, CiExpr[] args, CiPriority parent) { if (obj == null) { WriteLocalName(method, CiPriority.Primary); WriteArgsInParentheses(method, args); } else if (method == CiSystem.StringSubstring) { obj.Accept(this, CiPriority.Primary); Write(".substring("); args[0].Accept(this, CiPriority.Argument); if (args.Length == 2) { Write(", "); WriteAdd(args[0], args[1]); // TODO: side effect } Write(')'); } else if (obj.Type is CiArrayType && method.Name == "CopyTo") { AddLibrary(GenJsMethod.CopyArray, "copyArray : function(sa, soffset, da, doffset, length)", "if (typeof(sa.subarray) == \"function\" && typeof(da.set) == \"function\")", "\tda.set(sa.subarray(soffset, soffset + length), doffset);", "else", "\tfor (let i = 0; i < length; i++)", "\t\tda[doffset + i] = sa[soffset + i];"); Write("Ci.copyArray("); obj.Accept(this, CiPriority.Argument); Write(", "); WriteArgs(method, args); Write(')'); } else if (obj.Type is CiArrayType array && method.Name == "Fill") { obj.Accept(this, CiPriority.Primary); Write(".fill("); args[0].Accept(this, CiPriority.Argument); if (args.Length == 3) { Write(", "); WriteStartEnd(args[1], args[2]); } Write(')'); }
protected virtual void WriteExpr(CiExpr expr, CiPriority parent) { expr.Accept(this, parent); }
protected override void WriteCall(CiExpr obj, CiMethod method, CiExpr[] args, CiPriority parent) { if (obj.Type is CiArrayType && !(obj.Type is CiListType) && method.Name == "CopyTo") { Write("System.Array.Copy("); obj.Accept(this, CiPriority.Statement); Write(", "); WriteArgs(method, args); Write(')'); } else if (obj.Type is CiArrayStorageType && method.Name == "Fill") { if (!(args[0] is CiLiteral literal) || !literal.IsDefaultValue) { throw new NotImplementedException("Only null, zero and false supported"); } Write("System.Array.Clear("); obj.Accept(this, CiPriority.Statement); Write(", 0, "); Write(((CiArrayStorageType)obj.Type).Length); Write(')'); } else if (method == CiSystem.ArraySort) { if (obj.Type is CiArrayStorageType) { Write("System.Array.Sort("); obj.Accept(this, CiPriority.Statement); Write(')'); } else { obj.Accept(this, CiPriority.Primary); Write(".Sort()"); } } else if ((method == CiSystem.StringIndexOf || method == CiSystem.StringLastIndexOf) && IsOneAsciiString(args[0], out char c)) { obj.Accept(this, CiPriority.Primary); Write('.'); Write(method.Name); Write('('); WriteCharLiteral(c); Write(')'); } else if (method == CiSystem.UTF8GetString) { Write("System.Text.Encoding.UTF8.GetString"); WriteArgsInParentheses(method, args); } else { if (method == CiSystem.ConsoleWrite || method == CiSystem.ConsoleWriteLine || IsMathReference(obj)) { Write("System."); } obj.Accept(this, CiPriority.Primary); Write('.'); Write(method.Name); WriteArgsInParentheses(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); } }
protected virtual void WriteCoercedInternal(CiType type, CiExpr expr, CiPriority parent) { expr.Accept(this, parent); }
protected override void WriteCall(CiExpr obj, CiMethod method, CiExpr[] args, CiPriority parent) { if (obj == null) { WriteName(method); WriteArgsInParentheses(method, args); } else if ((method == CiSystem.StringIndexOf || method == CiSystem.StringLastIndexOf) && IsOneAsciiString(args[0], out char c)) { obj.Accept(this, CiPriority.Primary); Write('.'); Write(method.Name); Write('('); WriteCharLiteral(c); Write(')'); } else if (method == CiSystem.UTF8GetString) { Include("System.Text"); Write("Encoding.UTF8.GetString"); WriteArgsInParentheses(method, args); } else if (method == CiSystem.RegexCompile) { Include("System.Text.RegularExpressions"); Write("new Regex"); WriteArgsInParentheses(method, args); } else if (method == CiSystem.MatchFindStr) { Include("System.Text.RegularExpressions"); Write('('); obj.Accept(this, CiPriority.Assign); Write(" = Regex.Match"); WriteArgsInParentheses(method, args); Write(").Success"); } else if (method == CiSystem.MatchFindRegex) { Include("System.Text.RegularExpressions"); Write('('); obj.Accept(this, CiPriority.Assign); Write(" = "); args[1].Accept(this, CiPriority.Primary); Write(".Match("); args[0].Accept(this, CiPriority.Statement); Write(")).Success"); } else if (method == CiSystem.MatchGetCapture) { obj.Accept(this, CiPriority.Primary); Write(".Groups["); args[0].Accept(this, CiPriority.Statement); Write("].Value"); } else if (obj.Type is CiArrayType && !(obj.Type is CiListType) && method.Name == "CopyTo") { Include("System"); Write("Array.Copy("); obj.Accept(this, CiPriority.Statement); Write(", "); WriteArgs(method, args); Write(')'); } else if (obj.Type is CiArrayStorageType && method.Name == "Fill") { if (!(args[0] is CiLiteral literal) || !literal.IsDefaultValue) { throw new NotImplementedException("Only null, zero and false supported"); } Include("System"); Write("Array.Clear("); obj.Accept(this, CiPriority.Statement); Write(", 0, "); Write(((CiArrayStorageType)obj.Type).Length); Write(')'); } else if (WriteListAddInsert(obj, method, args, "Add", "Insert", ", ")) { // done } else if (obj.Type is CiDictionaryType dict && method.Name == "Add") { obj.Accept(this, CiPriority.Primary); Write(".Add("); args[0].Accept(this, CiPriority.Statement); Write(", "); WriteNewStorage(dict.ValueType); Write(')'); }
protected virtual void WriteNew(CiClass klass, CiPriority parent) { Write("new "); Write(klass.Name); Write("()"); }
public override CiExpr Visit(CiSymbolReference expr, CiPriority parent) { if (expr.Symbol == CiSystem.CollectionCount) { switch (expr.Left.Type) { case CiListType _: case CiStackType _: expr.Left.Accept(this, CiPriority.Primary); Write(".length"); break; case CiHashSetType _: expr.Left.Accept(this, CiPriority.Primary); Write(".size"); break; case CiDictionaryType _: WriteCall("Object.keys", expr.Left); Write(".length"); break; default: throw new NotImplementedException(expr.Left.Type.ToString()); } } else if (expr.Symbol == CiSystem.MatchStart) { expr.Left.Accept(this, CiPriority.Primary); Write(".index"); } else if (expr.Symbol == CiSystem.MatchEnd) { if (parent > CiPriority.Add) { Write('('); } expr.Left.Accept(this, CiPriority.Primary); Write(".index + "); expr.Left.Accept(this, CiPriority.Primary); // FIXME: side effect Write("[0].length"); if (parent > CiPriority.Add) { Write(')'); } } else if (expr.Symbol == CiSystem.MatchLength) { expr.Left.Accept(this, CiPriority.Primary); Write("[0].length"); } else if (expr.Symbol == CiSystem.MatchValue) { expr.Left.Accept(this, CiPriority.Primary); Write("[0]"); } else if (expr.Left != null && expr.Left.IsReferenceTo(CiSystem.MathClass)) { Write(expr.Symbol == CiSystem.MathNaN ? "NaN" : expr.Symbol == CiSystem.MathNegativeInfinity ? "-Infinity" : expr.Symbol == CiSystem.MathPositiveInfinity ? "Infinity" : throw new NotImplementedException(expr.ToString())); } else { return(base.Visit(expr, parent)); } return(expr); }
protected abstract void WriteNewArray(CiType elementType, CiExpr lengthExpr, CiPriority parent);
protected abstract void WriteArrayPtr(CiExpr expr, CiPriority parent);
protected override void WriteNewArray(CiType elementType, CiExpr lengthExpr, CiPriority parent) { if (!(elementType is CiNumericType)) { Write("new Array("); lengthExpr.Accept(this, CiPriority.Statement); Write(')'); return; } string name; int shift; if (elementType == CiSystem.IntType) { name = "Int32"; shift = 2; } else if (elementType == CiSystem.DoubleType) { name = "Float64"; shift = 3; } else if (elementType == CiSystem.FloatType) { name = "Float32"; shift = 2; } else if (elementType == CiSystem.LongType) { // TODO: UInt32 if possible? name = "Float64"; // no 64-bit integers in JavaScript shift = 3; } else { CiRangeType range = (CiRangeType)elementType; if (range.Min < 0) { if (range.Min < short.MinValue || range.Max > short.MaxValue) { name = "Int32"; shift = 2; } else if (range.Min < sbyte.MinValue || range.Max > sbyte.MaxValue) { name = "Int16"; shift = 1; } else { name = "Int8"; shift = 0; } } else if (range.Max > ushort.MaxValue) { name = "Int32"; shift = 2; } else if (range.Max > byte.MaxValue) { name = "Uint16"; shift = 1; } else { name = "Uint8"; shift = 0; } } Write("new "); Write(name); Write("Array(new ArrayBuffer("); if (shift == 0) { lengthExpr.Accept(this, CiPriority.Statement); } else if (lengthExpr is CiLiteral literalLength) { Write(((long)literalLength.Value) << shift); } else { lengthExpr.Accept(this, CiPriority.Shift); Write(" << "); Write(shift); } Write("))"); }