Exemple #1
0
 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);
     }
 }
Exemple #2
0
 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);
     }
 }
Exemple #3
0
 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);
     }
 }
Exemple #4
0
 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);
 }
Exemple #5
0
 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));
 }
Exemple #6
0
 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);
 }
Exemple #7
0
 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);
 }
Exemple #8
0
 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);
 }
Exemple #9
0
 public override CiExpr Visit(CiInterpolatedString expr, CiPriority parent)
 {
     throw new NotImplementedException("Interpolated strings not supported in OpenCL C");
 }
Exemple #10
0
 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);
     }
 }
Exemple #11
0
Fichier : GenC.cs Projet : epi/cito
 void WriteChildWithSuggestedParentheses(CiBinaryExpr parent, CiExpr child, CiPriority suggestedParentPriority, bool assoc)
 {
     if (assoc && GetPriority(parent) == GetPriority(child))
     Write(child);
     else
     WriteChild(suggestedParentPriority, child);
 }
Exemple #12
0
 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(')');
         }
     }
Exemple #13
0
        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);
        }
Exemple #14
0
 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(')');
 }
Exemple #15
0
 protected override void WriteNew(CiClass klass, CiPriority parent)
 {
     WriteName(klass);
     Write("()");
 }
Exemple #16
0
 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(')');
         }
     }
Exemple #17
0
 protected abstract void WriteEqualString(CiExpr left, CiExpr right, CiPriority parent, bool not);
Exemple #18
0
 public override CiExpr Visit(CiLiteral expr, CiPriority parent)
 {
     WriteLiteral(expr.Value);
     return(expr);
 }
Exemple #19
0
 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(')');
         }
     }
Exemple #20
0
 protected void WriteNonAssocChild(CiPriority parentPriority, CiExpr child)
 {
     if (GetPriority(child) <= parentPriority) {
     Write('(');
     Write(child);
     Write(')');
     }
     else
     Write(child);
 }
Exemple #21
0
 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(')');
     }
Exemple #22
0
        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);
        }
Exemple #23
0
 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(')');
     }
Exemple #24
0
 protected virtual void WriteExpr(CiExpr expr, CiPriority parent)
 {
     expr.Accept(this, parent);
 }
Exemple #25
0
 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);
     }
 }
Exemple #26
0
 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);
         }
     }
Exemple #27
0
 protected virtual void WriteCoercedInternal(CiType type, CiExpr expr, CiPriority parent)
 {
     expr.Accept(this, parent);
 }
Exemple #28
0
 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(')');
     }
Exemple #29
0
 protected virtual void WriteNew(CiClass klass, CiPriority parent)
 {
     Write("new ");
     Write(klass.Name);
     Write("()");
 }
Exemple #30
0
        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);
        }
Exemple #31
0
 protected abstract void WriteNewArray(CiType elementType, CiExpr lengthExpr, CiPriority parent);
Exemple #32
0
 protected abstract void WriteArrayPtr(CiExpr expr, CiPriority parent);
Exemple #33
0
        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("))");
        }