Наследование: CiExpr, ICiStatement
Пример #1
0
 protected override void Write(CiMethodCall expr)
 {
     if (expr.Method == CiLibrary.MulDivMethod)
     {
         Write("(int) ((long) ");
         WriteMulDiv(2, expr);
     }
     else if (expr.Method == CiLibrary.CharAtMethod)
     {
         Write(expr.Obj);
         Write('[');
         Write(expr.Arguments[0]);
         Write(']');
     }
     else if (expr.Method == CiLibrary.SubstringMethod)
     {
         Write(expr.Obj);
         Write(".Substring(");
         Write(expr.Arguments[0]);
         Write(", ");
         Write(expr.Arguments[1]);
         Write(')');
     }
     else if (expr.Method == CiLibrary.ArrayCopyToMethod)
     {
         Write("System.Array.Copy(");
         Write(expr.Obj);
         Write(", ");
         Write(expr.Arguments[0]);
         Write(", ");
         Write(expr.Arguments[1]);
         Write(", ");
         Write(expr.Arguments[2]);
         Write(", ");
         Write(expr.Arguments[3]);
         Write(')');
     }
     else if (expr.Method == CiLibrary.ArrayToStringMethod)
     {
         Write("System.Text.Encoding.UTF8.GetString(");
         Write(expr.Obj);
         Write(", ");
         Write(expr.Arguments[0]);
         Write(", ");
         Write(expr.Arguments[1]);
         Write(')');
     }
     else if (expr.Method == CiLibrary.ArrayStorageClearMethod)
     {
         Write("System.Array.Clear(");
         Write(expr.Obj);
         Write(", 0, ");
         Write(((CiArrayStorageType)expr.Obj.Type).Length);
         Write(')');
     }
     else
     {
         base.Write(expr);
     }
 }
Пример #2
0
 protected void WriteMulDiv(int firstPriority, CiMethodCall expr)
 {
     WriteChild(firstPriority, expr.Obj);
     Write(" * ");
     WriteChild(3, expr.Arguments[0]);
     Write(" / ");
     WriteNonAssocChild(3, expr.Arguments[1]);
     Write(')');
 }
Пример #3
0
 protected override void Write(CiMethodCall expr)
 {
     if (expr.Method == CiLibrary.MulDivMethod)
     {
         Write("(int) ((double) ");
         WriteMulDiv(2, expr);
     }
     else
     {
         base.Write(expr);
     }
 }
Пример #4
0
        protected void WriteArguments(CiMethodCall expr)
        {
            Write('(');
            bool first = true;

            foreach (CiExpr arg in expr.Arguments)
            {
                if (first)
                {
                    first = false;
                }
                else
                {
                    Write(", ");
                }
                Write(arg);
            }
            Write(')');
        }
Пример #5
0
 protected virtual void Write(CiMethodCall expr)
 {
     if (expr.Method != null)
     {
         if (expr.Obj != null)
         {
             Write(expr.Obj);
         }
         else
         {
             Write(expr.Method.Class.Name);
         }
         Write('.');
         WriteName(expr.Method);
     }
     else
     {
         WriteDelegateCall(expr.Obj);
     }
     WriteArguments(expr);
 }
Пример #6
0
        CiType LookupType(string name)
        {
            CiSymbol symbol = this.Symbols.TryLookup(name);

            if (symbol is CiType)
            {
                return((CiType)symbol);
            }
            if (symbol is CiClass)
            {
                return new CiClassPtrType {
                           Name = name, Class = (CiClass)symbol
                }
            }
            ;
            if (symbol == null)
            {
                CiType unknown = new CiUnknownType();

                unknown.Name = name;
                return(unknown);
            }
            throw new ParseException("{0} is not a type", name);
        }

        CiType ParseArrayType(CiType baseType)
        {
            if (Eat(CiToken.LeftBracket))
            {
                if (Eat(CiToken.RightBracket))
                {
                    return new CiArrayPtrType {
                               ElementType = ParseArrayType(baseType)
                    }
                }
                ;
                CiExpr len = ParseExpr();
                Expect(CiToken.RightBracket);
                return(new CiArrayStorageType {
                    LengthExpr = len,
                    ElementType = ParseArrayType(baseType)
                });
            }
            return(baseType);
        }

        CiType ParseType()
        {
            string baseName = ParseId();
            CiType baseType;

            if (Eat(CiToken.LeftParenthesis))
            {
                if (baseName == "string")
                {
                    baseType = new CiStringStorageType {
                        LengthExpr = ParseExpr()
                    };

                    Expect(CiToken.RightParenthesis);
                }
                else
                {
                    Expect(CiToken.RightParenthesis);
                    baseType = new CiClassStorageType {
                        Name = baseName, Class = new CiUnknownClass {
                            Name = baseName
                        }
                    };
                }
            }
            else
            {
                baseType = LookupType(baseName);
            }
            return(ParseArrayType(baseType));
        }

        object ParseConstInitializer(CiType type)
        {
            if (type is CiArrayType)
            {
                Expect(CiToken.LeftBrace);
                CiType        elementType = ((CiArrayType)type).ElementType;
                List <object> list        = new List <object>();
                if (!See(CiToken.RightBrace))
                {
                    do
                    {
                        list.Add(ParseConstInitializer(elementType));
                    }while (Eat(CiToken.Comma));
                }
                Expect(CiToken.RightBrace);
                return(list.ToArray());
            }
            return(ParseExpr());
        }

        CiConst ParseConst()
        {
            Expect(CiToken.Const);
            CiConst konst = new CiConst();

            konst.Type = ParseType();
            konst.Name = ParseId();
            Expect(CiToken.Assign);
            konst.Value = ParseConstInitializer(konst.Type);
            Expect(CiToken.Semicolon);
            if (this.Symbols.Parent != null && konst.Type is CiArrayType)
            {
                this.ConstArrays.Add(konst);
                konst.GlobalName = "CiConstArray_" + this.ConstArrays.Count;
            }
            return(konst);
        }

        CiBinaryResourceExpr ParseBinaryResource()
        {
            Expect(CiToken.LeftParenthesis);
            CiExpr nameExpr = ParseExpr();

            Expect(CiToken.RightParenthesis);
            return(new CiBinaryResourceExpr {
                NameExpr = nameExpr
            });
        }

        CiExpr ParsePrimaryExpr()
        {
            if (See(CiToken.Increment) || See(CiToken.Decrement) || See(CiToken.Minus) || See(CiToken.Not))
            {
                CiToken op = this.CurrentToken;
                NextToken();
                CiExpr inner = ParsePrimaryExpr();
                return(new CiUnaryExpr {
                    Op = op, Inner = inner
                });
            }
            if (Eat(CiToken.CondNot))
            {
                CiExpr inner = ParsePrimaryExpr();
                return(new CiCondNotExpr {
                    Inner = inner
                });
            }
            CiExpr result;

            if (See(CiToken.IntConstant))
            {
                result = new CiConstExpr(this.CurrentInt);
                NextToken();
            }
            else if (See(CiToken.StringConstant))
            {
                result = new CiConstExpr(this.CurrentString);
                NextToken();
            }
            else if (Eat(CiToken.LeftParenthesis))
            {
                result = ParseExpr();
                Expect(CiToken.RightParenthesis);
            }
            else if (See(CiToken.Id))
            {
                string name = ParseId();
                if (name == "BinaryResource")
                {
                    result = ParseBinaryResource();
                }
                else
                {
                    CiSymbol symbol = this.Symbols.TryLookup(name);
                    if (symbol is CiMacro)
                    {
                        Expand((CiMacro)symbol);
                        Expect(CiToken.LeftParenthesis);
                        result = ParseExpr();
                        Expect(CiToken.RightParenthesis);
                    }
                    else
                    {
                        if (symbol == null)
                        {
                            symbol = new CiUnknownSymbol {
                                Name = name
                            }
                        }
                        ;
                        result = new CiSymbolAccess {
                            Symbol = symbol
                        };
                    }
                }
            }
            else if (Eat(CiToken.New))
            {
                CiType newType = ParseType();
                if (!(newType is CiClassStorageType || newType is CiArrayStorageType))
                {
                    throw new ParseException("'new' syntax error");
                }
                result = new CiNewExpr {
                    NewType = newType
                };
            }
            else
            {
                throw new ParseException("Invalid expression");
            }
            for (;;)
            {
                if (Eat(CiToken.Dot))
                {
                    result = new CiUnknownMemberAccess {
                        Parent = result, Name = ParseId()
                    }
                }
                ;
                else if (Eat(CiToken.LeftParenthesis))
                {
                    CiMethodCall call = new CiMethodCall();
                    call.Obj = result;
                    List <CiExpr> args = new List <CiExpr>();
                    if (!See(CiToken.RightParenthesis))
                    {
                        do
                        {
                            args.Add(ParseExpr());
                        }while (Eat(CiToken.Comma));
                    }
                    Expect(CiToken.RightParenthesis);
                    call.Arguments = args.ToArray();
                    result         = call;
                }
                else if (Eat(CiToken.LeftBracket))
                {
                    CiExpr index = ParseExpr();
                    Expect(CiToken.RightBracket);
                    result = new CiIndexAccess {
                        Parent = result, Index = index
                    };
                }
                else if (See(CiToken.Increment) || See(CiToken.Decrement))
                {
                    CiToken op = this.CurrentToken;
                    NextToken();
                    return(new CiPostfixExpr {
                        Inner = result, Op = op
                    });
                }
                else
                {
                    return(result);
                }
            }
        }

        CiExpr ParseMulExpr()
        {
            CiExpr left = ParsePrimaryExpr();

            while (See(CiToken.Asterisk) || See(CiToken.Slash) || See(CiToken.Mod))
            {
                CiToken op = this.CurrentToken;
                NextToken();
                left = new CiBinaryExpr {
                    Left = left, Op = op, Right = ParsePrimaryExpr()
                };
            }
            return(left);
        }

        CiExpr ParseAddExpr()
        {
            CiExpr left = ParseMulExpr();

            while (See(CiToken.Plus) || See(CiToken.Minus))
            {
                CiToken op = this.CurrentToken;
                NextToken();
                left = new CiBinaryExpr {
                    Left = left, Op = op, Right = ParseMulExpr()
                };
            }
            return(left);
        }

        CiExpr ParseShiftExpr()
        {
            CiExpr left = ParseAddExpr();

            while (See(CiToken.ShiftLeft) || See(CiToken.ShiftRight))
            {
                CiToken op = this.CurrentToken;
                NextToken();
                left = new CiBinaryExpr {
                    Left = left, Op = op, Right = ParseAddExpr()
                };
            }
            return(left);
        }

        CiExpr ParseRelExpr()
        {
            CiExpr left = ParseShiftExpr();

            while (See(CiToken.Less) || See(CiToken.LessOrEqual) || See(CiToken.Greater) || See(CiToken.GreaterOrEqual))
            {
                CiToken op = this.CurrentToken;
                NextToken();
                left = new CiBoolBinaryExpr {
                    Left = left, Op = op, Right = ParseShiftExpr()
                };
            }
            return(left);
        }

        CiExpr ParseEqualityExpr()
        {
            CiExpr left = ParseRelExpr();

            while (See(CiToken.Equal) || See(CiToken.NotEqual))
            {
                CiToken op = this.CurrentToken;
                NextToken();
                left = new CiBoolBinaryExpr {
                    Left = left, Op = op, Right = ParseRelExpr()
                };
            }
            return(left);
        }

        CiExpr ParseAndExpr()
        {
            CiExpr left = ParseEqualityExpr();

            while (Eat(CiToken.And))
            {
                left = new CiBinaryExpr {
                    Left = left, Op = CiToken.And, Right = ParseEqualityExpr()
                }
            }
            ;
            return(left);
        }

        CiExpr ParseXorExpr()
        {
            CiExpr left = ParseAndExpr();

            while (Eat(CiToken.Xor))
            {
                left = new CiBinaryExpr {
                    Left = left, Op = CiToken.Xor, Right = ParseAndExpr()
                }
            }
            ;
            return(left);
        }

        CiExpr ParseOrExpr()
        {
            CiExpr left = ParseXorExpr();

            while (Eat(CiToken.Or))
            {
                left = new CiBinaryExpr {
                    Left = left, Op = CiToken.Or, Right = ParseXorExpr()
                }
            }
            ;
            return(left);
        }

        CiExpr ParseCondAndExpr()
        {
            CiExpr left = ParseOrExpr();

            while (Eat(CiToken.CondAnd))
            {
                left = new CiBoolBinaryExpr {
                    Left = left, Op = CiToken.CondAnd, Right = ParseOrExpr()
                }
            }
            ;
            return(left);
        }

        CiExpr ParseCondOrExpr()
        {
            CiExpr left = ParseCondAndExpr();

            while (Eat(CiToken.CondOr))
            {
                left = new CiBoolBinaryExpr {
                    Left = left, Op = CiToken.CondOr, Right = ParseCondAndExpr()
                }
            }
            ;
            return(left);
        }

        CiExpr ParseExpr()
        {
            CiExpr left = ParseCondOrExpr();

            if (Eat(CiToken.QuestionMark))
            {
                CiCondExpr result = new CiCondExpr();
                result.Cond   = left;
                result.OnTrue = ParseExpr();
                Expect(CiToken.Colon);
                result.OnFalse = ParseExpr();
                return(result);
            }
            return(left);
        }

        CiMaybeAssign ParseMaybeAssign()
        {
            CiExpr  left = ParseExpr();
            CiToken op   = this.CurrentToken;

            if (op == CiToken.Assign || op == CiToken.AddAssign || op == CiToken.SubAssign || op == CiToken.MulAssign || op == CiToken.DivAssign || op == CiToken.ModAssign ||
                op == CiToken.AndAssign || op == CiToken.OrAssign || op == CiToken.XorAssign || op == CiToken.ShiftLeftAssign || op == CiToken.ShiftRightAssign)
            {
                NextToken();
                CiAssign result = new CiAssign();
                result.Target = left;
                result.Op     = op;
                result.Source = ParseMaybeAssign();
                return(result);
            }
            return(left);
        }

        ICiStatement ParseExprWithSideEffect()
        {
            ICiStatement result = ParseMaybeAssign() as ICiStatement;

            if (result == null)
            {
                throw new ParseException("Useless expression");
            }
            return(result);
        }

        CiExpr ParseCond()
        {
            Expect(CiToken.LeftParenthesis);
            CiExpr cond = ParseExpr();

            Expect(CiToken.RightParenthesis);
            return(cond);
        }

        void OpenScope()
        {
            this.Symbols = new SymbolTable {
                Parent = this.Symbols
            };
        }

        void CloseScope()
        {
            this.Symbols = this.Symbols.Parent;
        }

        CiVar ParseVar()
        {
            CiVar def = new CiVar();

            def.Type = ParseType();
            def.Name = ParseId();
            if (Eat(CiToken.Assign))
            {
                def.InitialValue = ParseExpr();
            }
            Expect(CiToken.Semicolon);
            this.Symbols.Add(def);
            return(def);
        }

        ICiStatement ParseVarOrExpr()
        {
            string   name   = this.CurrentString;
            CiSymbol symbol = this.Symbols.TryLookup(name);

            if (symbol is CiMacro)
            {
                NextToken();
                Expand((CiMacro)symbol);
                return(ParseStatement());
            }
            // try var
            StringBuilder sb = new StringBuilder();

            this.CopyTo = sb;
            try {
                return(ParseVar());
            }
            catch (ParseException) {
            }
            finally {
                this.CopyTo = null;
            }

            // try expr
            this.CurrentString = name;
            this.CurrentToken  = CiToken.Id;
            BeginExpand("ambigous code", sb.ToString(), null);
            SetReader(new StringReader(sb.ToString()));
            ICiStatement result = ParseExprWithSideEffect();

            Expect(CiToken.Semicolon);
            return(result);
        }

        CiNativeBlock ParseNativeBlock()
        {
            StringBuilder sb = new StringBuilder();

            this.CopyTo = sb;
            NextToken();
            bool oneLine = true;

            try {
                if (See(CiToken.LeftBrace))
                {
                    oneLine     = false;
                    sb          = new StringBuilder();
                    this.CopyTo = sb;
                    Expect(CiToken.LeftBrace);
                }
                int level = 1;
                for (;;)
                {
                    if (oneLine && See(CiToken.Semicolon) && level == 1)
                    {
                        break;
                    }
                    if (See(CiToken.EndOfFile))
                    {
                        throw new ParseException("Native block not terminated");
                    }
                    if (See(CiToken.LeftBrace))
                    {
                        level++;
                    }
                    else if (See(CiToken.RightBrace))
                    {
                        if (--level == 0)
                        {
                            break;
                        }
                    }
                    NextToken();
                }
            }
            finally {
                this.CopyTo = null;
            }
            NextToken();
            Trace.Assert(sb[sb.Length - 1] == '}');
            if (!oneLine)
            {
                sb.Length--;
            }
            else
            {
                sb.Append("\n\t");
            }

            return(new CiNativeBlock {
                Content = sb.ToString()
            });
        }

        CiSwitch ParseSwitch()
        {
            Expect(CiToken.LeftParenthesis);
            CiSwitch result = new CiSwitch();

            result.Value = ParseExpr();
            Expect(CiToken.RightParenthesis);
            Expect(CiToken.LeftBrace);

            List <CiCase> cases = new List <CiCase>();

            while (Eat(CiToken.Case))
            {
                List <object> values = new List <object>();
                do
                {
                    values.Add(ParseExpr());
                    Expect(CiToken.Colon);
                } while (Eat(CiToken.Case));
                if (See(CiToken.Default))
                {
                    throw new ParseException("Please remove case before default");
                }
                CiCase kase = new CiCase {
                    Values = values.ToArray()
                };

                List <ICiStatement> statements = new List <ICiStatement>();
                do
                {
                    statements.Add(ParseStatement());
                }while (!See(CiToken.Case) && !See(CiToken.Default) && !See(CiToken.Goto) && !See(CiToken.RightBrace));
                kase.Body = statements.ToArray();

                if (Eat(CiToken.Goto))
                {
                    if (Eat(CiToken.Case))
                    {
                        kase.FallthroughTo = ParseExpr();
                    }
                    else if (Eat(CiToken.Default))
                    {
                        kase.FallthroughTo = null;
                    }
                    else
                    {
                        throw new ParseException("Expected goto case or goto default");
                    }
                    Expect(CiToken.Semicolon);
                    kase.Fallthrough = true;
                }
                cases.Add(kase);
            }
            if (cases.Count == 0)
            {
                throw new ParseException("Switch with no cases");
            }
            result.Cases = cases.ToArray();

            if (Eat(CiToken.Default))
            {
                Expect(CiToken.Colon);
                List <ICiStatement> statements = new List <ICiStatement>();
                do
                {
                    statements.Add(ParseStatement());
                }while (!See(CiToken.RightBrace));
                result.DefaultBody = statements.ToArray();
            }

            Expect(CiToken.RightBrace);
            return(result);
        }

        ICiStatement ParseStatement()
        {
            while (Eat(CiToken.Macro))
            {
                this.Symbols.Add(ParseMacro());
            }
            if (See(CiToken.Id))
            {
                return(ParseVarOrExpr());
            }
            if (See(CiToken.LeftBrace))
            {
                OpenScope();
                CiBlock result = ParseBlock();
                CloseScope();
                return(result);
            }
            if (Eat(CiToken.Break))
            {
                Expect(CiToken.Semicolon);
                return(new CiBreak());
            }
            if (See(CiToken.Const))
            {
                CiConst konst = ParseConst();
                this.Symbols.Add(konst);
                return(konst);
            }
            if (Eat(CiToken.Continue))
            {
                Expect(CiToken.Semicolon);
                return(new CiContinue());
            }
            if (Eat(CiToken.Delete))
            {
                CiExpr expr = ParseExpr();
                Expect(CiToken.Semicolon);
                return(new CiDelete {
                    Expr = expr
                });
            }
            if (Eat(CiToken.Do))
            {
                CiDoWhile result = new CiDoWhile();
                result.Body = ParseStatement();
                Expect(CiToken.While);
                result.Cond = ParseCond();
                Expect(CiToken.Semicolon);
                return(result);
            }
            if (Eat(CiToken.For))
            {
                Expect(CiToken.LeftParenthesis);
                OpenScope();
                CiFor result = new CiFor();
                if (See(CiToken.Id))
                {
                    result.Init = ParseVarOrExpr();
                }
                else
                {
                    Expect(CiToken.Semicolon);
                }
                if (!See(CiToken.Semicolon))
                {
                    result.Cond = ParseExpr();
                }
                Expect(CiToken.Semicolon);
                if (!See(CiToken.RightParenthesis))
                {
                    result.Advance = ParseExprWithSideEffect();
                }
                Expect(CiToken.RightParenthesis);
                result.Body = ParseStatement();
                CloseScope();
                return(result);
            }
            if (Eat(CiToken.If))
            {
                CiIf result = new CiIf();
                result.Cond   = ParseCond();
                result.OnTrue = ParseStatement();
                if (Eat(CiToken.Else))
                {
                    result.OnFalse = ParseStatement();
                }
                return(result);
            }
            if (See(CiToken.Native))
            {
                return(ParseNativeBlock());
            }
            if (Eat(CiToken.Return))
            {
                CiReturn result = new CiReturn();
                if (this.CurrentMethod.Signature.ReturnType != CiType.Void)
                {
                    result.Value = ParseExpr();
                }
                Expect(CiToken.Semicolon);
                return(result);
            }
            if (Eat(CiToken.Switch))
            {
                return(ParseSwitch());
            }
            if (Eat(CiToken.Throw))
            {
                CiThrow result = new CiThrow();
                result.Message = ParseExpr();
                Expect(CiToken.Semicolon);
                return(result);
            }
            if (Eat(CiToken.While))
            {
                CiWhile result = new CiWhile();
                result.Cond = ParseCond();
                result.Body = ParseStatement();
                return(result);
            }
            throw new ParseException("Invalid statement");
        }

        CiBlock ParseBlock()
        {
            Expect(CiToken.LeftBrace);
            List <ICiStatement> statements = new List <ICiStatement>();

            while (!Eat(CiToken.RightBrace))
            {
                statements.Add(ParseStatement());
            }
            return(new CiBlock {
                Statements = statements.ToArray()
            });
        }

        CiParam CreateThis()
        {
            CiParam thiz = new CiParam();

            thiz.Type = new CiClassPtrType {
                Name = this.CurrentClass.Name, Class = this.CurrentClass
            };
            thiz.Name = "this";
            this.Symbols.Add(thiz);
            return(thiz);
        }

        CiType ParseReturnType()
        {
            if (Eat(CiToken.Void))
            {
                return(CiType.Void);
            }
            return(ParseType());
        }

        CiParam[] ParseParams()
        {
            Expect(CiToken.LeftParenthesis);
            List <CiParam> paramz = new List <CiParam>();

            if (!See(CiToken.RightParenthesis))
            {
                do
                {
                    CiParam param = new CiParam();
                    param.Documentation = ParseDoc();
                    param.Type          = ParseType();
                    param.Name          = ParseId();
                    this.Symbols.Add(param);
                    paramz.Add(param);
                } while (Eat(CiToken.Comma));
            }
            Expect(CiToken.RightParenthesis);
            return(paramz.ToArray());
        }

        void ParseMethod(CiMethod method)
        {
            this.CurrentMethod = method;
            OpenScope();
            if (method.CallType != CiCallType.Static)
            {
                method.This = CreateThis();
            }
            method.Signature.Params = ParseParams();
            if (method.CallType == CiCallType.Abstract)
            {
                Expect(CiToken.Semicolon);
            }
            else
            {
                method.Body = ParseBlock();
            }
            CloseScope();
            this.CurrentMethod = null;
        }

        CiMethod ParseConstructor()
        {
            NextToken();
            Expect(CiToken.LeftParenthesis);
            Expect(CiToken.RightParenthesis);
            OpenScope();
            CiMethod method = new CiMethod(
                CiType.Void, "<constructor>")
            {
                Class    = this.CurrentClass,
                CallType = CiCallType.Normal,
                This     = CreateThis()
            };

            this.CurrentMethod = method;
            method.Body        = ParseBlock();
            CloseScope();
            this.CurrentMethod = null;
            return(method);
        }

        CiClass ParseClass()
        {
            CiClass klass = new CiClass();

            klass.SourceFilename = this.Filename;
            if (Eat(CiToken.Abstract))
            {
                klass.IsAbstract = true;
            }
            Expect(CiToken.Class);
            klass.Name = ParseId();
            if (Eat(CiToken.Colon))
            {
                klass.BaseClass = new CiUnknownClass {
                    Name = ParseId()
                }
            }
            ;
            Expect(CiToken.LeftBrace);
            OpenScope();
            this.CurrentClass = klass;
            klass.Members     = this.Symbols;
            while (!Eat(CiToken.RightBrace))
            {
                CiCodeDoc    doc        = ParseDoc();
                CiVisibility visibility = CiVisibility.Private;
                if (Eat(CiToken.Public))
                {
                    visibility = CiVisibility.Public;
                }
                else if (Eat(CiToken.Internal))
                {
                    visibility = CiVisibility.Internal;
                }
                CiSymbol symbol;
                if (See(CiToken.Const))
                {
                    symbol = ParseConst();
                    ((CiConst)symbol).Class = klass;
                }
                else if (Eat(CiToken.Macro))
                {
                    if (visibility != CiVisibility.Private)
                    {
                        throw new ParseException("Macros must be private");
                    }
                    symbol = ParseMacro();
                }
                else
                {
                    if (See(CiToken.Id) && this.CurrentString == klass.Name)
                    {
                        if (klass.Constructor != null)
                        {
                            throw new ParseException("Duplicate constructor");
                        }
                        klass.Constructor = ParseConstructor();
                        continue;
                    }
                    CiCallType callType;
                    if (Eat(CiToken.Static))
                    {
                        callType = CiCallType.Static;
                    }
                    else if (Eat(CiToken.Abstract))
                    {
                        if (!klass.IsAbstract)
                        {
                            throw new ParseException("Abstract methods only allowed in abstract classes");
                        }
                        callType = CiCallType.Abstract;
                        if (visibility == CiVisibility.Private)
                        {
                            visibility = CiVisibility.Internal;
                        }
                    }
                    else if (Eat(CiToken.Virtual))
                    {
                        callType = CiCallType.Virtual;
                        if (visibility == CiVisibility.Private)
                        {
                            visibility = CiVisibility.Internal;
                        }
                    }
                    else if (Eat(CiToken.Override))
                    {
                        callType = CiCallType.Override;
                        if (visibility == CiVisibility.Private)
                        {
                            visibility = CiVisibility.Internal;
                        }
                    }
                    else
                    {
                        callType = CiCallType.Normal;
                    }
                    CiType type = ParseReturnType();
                    string name = ParseId();
                    if (See(CiToken.LeftParenthesis))
                    {
                        CiMethod method = new CiMethod(type, name)
                        {
                            Class    = klass,
                            CallType = callType
                        };
                        ParseMethod(method);
                        symbol = method;
                    }
                    else
                    {
                        if (visibility != CiVisibility.Private)
                        {
                            throw new ParseException("Fields must be private");
                        }
                        if (callType != CiCallType.Normal)
                        {
                            throw new ParseException("Fields cannot be static, abstract, virtual or override");
                        }
                        if (type == CiType.Void)
                        {
                            throw new ParseException("Field is void");
                        }
                        Expect(CiToken.Semicolon);
                        symbol = new CiField {
                            Class = klass, Type = type, Name = name
                        };
                    }
                }
                symbol.Documentation = doc;
                symbol.Visibility    = visibility;
                klass.Members.Add(symbol);
            }
            this.CurrentClass = null;
            CloseScope();
            klass.ConstArrays = this.ConstArrays.ToArray();
            this.ConstArrays.Clear();
            return(klass);
        }

        CiDelegate ParseDelegate()
        {
            CiDelegate del = new CiDelegate();

            Expect(CiToken.Delegate);
            del.ReturnType = ParseReturnType();
            del.Name       = ParseId();
            OpenScope();
            del.Params = ParseParams();
            CloseScope();
            Expect(CiToken.Semicolon);
            return(del);
        }

        public void Parse(string filename, TextReader reader)
        {
            Open(filename, reader);
            while (!See(CiToken.EndOfFile))
            {
                CiCodeDoc doc = ParseDoc();
                bool      pub = Eat(CiToken.Public);
                CiSymbol  symbol;
                if (See(CiToken.Enum))
                {
                    symbol = ParseEnum();
                }
                else if (See(CiToken.Class) || See(CiToken.Abstract))
                {
                    symbol = ParseClass();
                }
                else if (See(CiToken.Delegate))
                {
                    symbol = ParseDelegate();
                }
                else
                {
                    throw new ParseException("Expected class, enum or delegate");
                }
                symbol.Documentation = doc;
                symbol.Visibility    = pub ? CiVisibility.Public : CiVisibility.Internal;
                this.Symbols.Add(symbol);
            }
        }

        public CiProgram Program
        {
            get
            {
                return(new CiProgram {
                    Globals = this.Symbols
                });
            }
        }
    }
}
Пример #7
0
        protected override void Write(CiMethodCall expr)
        {
            if (expr.Method == CiLibrary.MulDivMethod)
            {
#if USE_INTEGER
                // FIXME: overflow on 32-bit perl
                Write("(");
#else
                Write("int(");
#endif
                WriteMulDiv(3, expr);
            }
            else if (expr.Method == CiLibrary.CharAtMethod)
            {
                Write("ord(substr(");
                Write(expr.Obj);
                Write(", ");
                Write(expr.Arguments[0]);
                Write(", 1))");
            }
            else if (expr.Method == CiLibrary.SubstringMethod)
            {
                Write("substr(");
                Write(expr.Obj);
                Write(", ");
                Write(expr.Arguments[0]);
                Write(", ");
                Write(expr.Arguments[1]);
                Write(')');
            }
            else if (expr.Method == CiLibrary.ArrayCopyToMethod)
            {
                CiExpr lenMinus1 = new CiBinaryExpr {
                    Left = expr.Arguments[3], Op = CiToken.Minus, Right = new CiConstExpr(1)
                };
                WriteSlice(expr.Arguments[1], expr.Arguments[2], lenMinus1);
                Write(" = ");
                WriteSlice(expr.Obj, expr.Arguments[0], lenMinus1);
            }
            else if (expr.Method == CiLibrary.ArrayToStringMethod)
            {
                CiExpr lenMinus1 = new CiBinaryExpr {
                    Left = expr.Arguments[1], Op = CiToken.Minus, Right = new CiConstExpr(1)
                };
                Write("pack('U*', ");
                WriteSlice(expr.Obj, expr.Arguments[0], lenMinus1);
                Write(')');
            }
            else if (expr.Method == CiLibrary.ArrayStorageClearMethod)
            {
                Write('@');
                if (expr.Obj is CiVarAccess)
                {
                    Write(((CiVarAccess)expr.Obj).Var.Name);
                }
                else
                {
                    Write('{');
                    Write(expr.Obj);
                    Write('}');
                }
                Write(" = (0) x ");
                Write(((CiArrayStorageType)expr.Obj.Type).Length);
            }
            else
            {
                if (expr.Method != null)
                {
                    if (expr.Obj != null)
                    {
                        Write(expr.Obj);
                        Write("->");
                    }
                    else
                    {
                        Write(this.Package);
                        Write(expr.Method.Class.Name);
                        Write("::");
                    }
                    WriteLowercaseWithUnderscores(expr.Method.Name);
                }
                else
                {
                    // delegate call
                    Write(expr.Obj);
                    Write("->");
                }
                WriteArguments(expr);
            }
        }
Пример #8
0
Файл: GenAs.cs Проект: epi/cito
 protected override void Write(CiMethodCall expr)
 {
     if (expr.Method == CiLibrary.MulDivMethod) {
     Write("int(");
     WriteMulDiv(CiPriority.Multiplicative, expr);
     }
     else if (expr.Method == CiLibrary.CharAtMethod) {
     Write(expr.Obj);
     Write(".charCodeAt(");
     Write(expr.Arguments[0]);
     Write(')');
     }
     else if (expr.Method == CiLibrary.SubstringMethod) {
     if (expr.Arguments[0].HasSideEffect) {
         Write("substring(");
         Write(expr.Obj);
         Write(", ");
         Write(expr.Arguments[0]);
         Write(", ");
         Write(expr.Arguments[1]);
         Write(')');
         this.UsesSubstringMethod = true;
     }
     else {
         Write(expr.Obj);
         Write(".substring(");
         Write(expr.Arguments[0]);
         Write(", ");
         Write(new CiBinaryExpr { Left = expr.Arguments[0], Op = CiToken.Plus, Right = expr.Arguments[1] });
         Write(')');
     }
     }
     else if (expr.Method == CiLibrary.ArrayCopyToMethod) {
     Write("copyArray(");
     Write(expr.Obj);
     Write(", ");
     Write(expr.Arguments[0]);
     Write(", ");
     Write(expr.Arguments[1]);
     Write(", ");
     Write(expr.Arguments[2]);
     Write(", ");
     Write(expr.Arguments[3]);
     Write(')');
     this.UsesCopyArrayMethod = true;
     }
     else if (expr.Method == CiLibrary.ArrayToStringMethod) {
     Write("bytesToString(");
     Write(expr.Obj);
     Write(", ");
     Write(expr.Arguments[0]);
     Write(", ");
     Write(expr.Arguments[1]);
     Write(')');
     this.UsesBytesToStringMethod = true;
     }
     else if (expr.Method == CiLibrary.ArrayStorageClearMethod)
     WriteClearArray(expr.Obj);
     else
     base.Write(expr);
 }
Пример #9
0
Файл: GenC89.cs Проект: epi/cito
 protected override void Write(CiMethodCall expr)
 {
     if (expr.Method == CiLibrary.MulDivMethod) {
     Write("(int) ((double) ");
     WriteMulDiv(CiPriority.Prefix, expr);
     }
     else
     base.Write(expr);
 }
Пример #10
0
Файл: GenD.cs Проект: epi/cito
 protected override void Write(CiMethodCall expr)
 {
     if (expr.Method == CiLibrary.MulDivMethod) {
     Write("cast(int) (cast(long) ");
     WriteMulDiv(CiPriority.Prefix, expr);
     }
     else if (expr.Method == CiLibrary.CharAtMethod) {
     Write(expr.Obj);
     Write('[');
     Write(expr.Arguments[0]);
     Write(']');
     }
     else if (expr.Method == CiLibrary.SubstringMethod) {
     Write(expr.Obj);
     Write('[');
     Write(expr.Arguments[0]);
     Write(" .. (");
     Write(expr.Arguments[0]);
     Write(") + ");
     Write(expr.Arguments[1]);
     Write(']');
     }
     else if (expr.Method == CiLibrary.ArrayCopyToMethod) {
     Write(expr.Arguments[1]);
     Write('[');
     Write(expr.Arguments[2]);
     Write(" .. (");
     Write(expr.Arguments[2]);
     Write(") + ");
     Write(expr.Arguments[3]);
     Write("] = ");
     Write(expr.Obj);
     Write('[');
     Write(expr.Arguments[0]);
     Write(" .. (");
     Write(expr.Arguments[0]);
     Write(") + ");
     Write(expr.Arguments[3]);
     Write(']');
     }
     else if (expr.Method == CiLibrary.ArrayToStringMethod) {
     Write("toUTF8(cast(char[]) ");
     Write(expr.Obj);
     Write('[');
     Write(expr.Arguments[0]);
     Write(" .. (");
     Write(expr.Arguments[0]);
     Write(") + ");
     Write(expr.Arguments[1]);
     Write("])");
     }
     else if (expr.Method == CiLibrary.ArrayStorageClearMethod) {
     Write(expr.Obj);
     Write("[] = 0");
     }
     else
     base.Write(expr);
 }
Пример #11
0
 void CoerceArguments(CiMethodCall expr)
 {
     expr.Signature.Accept(this);
     CiParam[] paramz = expr.Signature.Params;
     if (expr.Arguments.Length != paramz.Length)
     throw new ResolveException("Invalid number of arguments for {0}, expected {1}, got {2}", expr.Signature.Name, paramz.Length, expr.Arguments.Length);
     for (int i = 0; i < paramz.Length; i++) {
     CiExpr arg = Resolve(expr.Arguments[i]);
     CheckCopyPtr(paramz[i].Type, arg);
     expr.Arguments[i] = Coerce(arg, paramz[i].Type);
     }
 }
Пример #12
0
 CiExpr ICiExprVisitor.Visit(CiMethodCall expr)
 {
     ResolveObj(expr);
     CoerceArguments(expr);
     if (expr.Method != null && expr.Method != this.CurrentMethod) {
     if (expr.Method.IsMutator)
         MarkWritable(expr.Obj);
     expr.Method.CalledBy.Add(this.CurrentMethod);
     this.CurrentMethod.Calls.Add(expr.Method);
     }
     return expr;
 }
Пример #13
0
 void ResolveObj(CiMethodCall expr)
 {
     if (expr.Obj is CiSymbolAccess) {
     // Foo(...)
     CiMethod method = Lookup((CiSymbolAccess) expr.Obj) as CiMethod;
     if (method != null) {
         expr.Method = method;
         if (method.CallType == CiCallType.Static)
             expr.Obj = null;
         else {
             if (this.CurrentMethod.CallType == CiCallType.Static)
                 throw new ResolveException("Cannot call instance method from a static method");
             expr.Obj = Coerce(new CiVarAccess { Var = this.CurrentMethod.This }, new CiClassPtrType { Class = method.Class });
             CheckCopyPtr(method.This.Type, expr.Obj);
         }
         return;
     }
     }
     else if (expr.Obj is CiUnknownMemberAccess) {
     // ???.Foo(...)
     CiUnknownMemberAccess uma = (CiUnknownMemberAccess) expr.Obj;
     if (uma.Parent is CiSymbolAccess) {
         CiClass klass = Lookup((CiSymbolAccess) uma.Parent) as CiClass;
         if (klass != null) {
             // Class.Foo(...)
             CiMethod method = klass.Members.Lookup(uma.Name) as CiMethod;
             if (method != null) {
                 if (method.CallType != CiCallType.Static)
                     throw new ResolveException("{0} is a non-static method", method.Name);
                 expr.Method = method;
                 expr.Obj = null;
                 return;
             }
         }
     }
     CiExpr obj = Resolve(uma.Parent);
     {
         CiMethod method = obj.Type.LookupMember(uma.Name) as CiMethod;
         if (method != null) {
             // obj.Foo(...)
             if (method.CallType == CiCallType.Static)
                 throw new ResolveException("{0} is a static method", method.Name);
             if (method.This != null) {
                 // user-defined method
                 CheckCopyPtr(method.This.Type, obj);
                 obj = Coerce(obj, new CiClassPtrType { Class = method.Class });
             }
             expr.Method = method;
             expr.Obj = obj;
             return;
         }
     }
     }
     expr.Obj = Resolve(expr.Obj);
     if (!(expr.Obj.Type is CiDelegate))
     throw new ResolveException("Invalid call");
     if (expr.Obj.HasSideEffect)
     throw new ResolveException("Side effects not allowed in delegate call");
 }
Пример #14
0
Файл: GenC.cs Проект: epi/cito
 protected override void Write(CiMethodCall expr)
 {
     if (expr.Method == CiLibrary.MulDivMethod) {
     Write("(int) ((long long int) ");
     WriteMulDiv(CiPriority.Prefix, expr);
     }
     else if (expr.Method == CiLibrary.CharAtMethod) {
     Write(expr.Obj);
     Write('[');
     Write(expr.Arguments[0]);
     Write(']');
     }
     else if (expr.Method == CiLibrary.SubstringMethod) {
     // TODO
     throw new ArgumentException("Substring");
     }
     else if (expr.Method == CiLibrary.ArrayCopyToMethod) {
     Write("memcpy(");
     WriteSum(expr.Arguments[1], expr.Arguments[2]);
     Write(", ");
     WriteSum(expr.Obj, expr.Arguments[0]);
     Write(", ");
     Write(expr.Arguments[3]);
     Write(')');
     }
     else if (expr.Method == CiLibrary.ArrayToStringMethod) {
     // TODO
     throw new ArgumentException("Array.ToString");
     }
     else if (expr.Method == CiLibrary.ArrayStorageClearMethod) {
     WriteClearArray(expr.Obj);
     }
     else {
     bool first = true;
     if (expr.Method != null) {
         switch (expr.Method.CallType) {
         case CiCallType.Static:
             Write(expr.Method.Class.Name);
             Write('_');
             Write(expr.Method.Name);
             Write('(');
             break;
         case CiCallType.Normal:
             Write(expr.Method.Class.Name);
             Write('_');
             Write(expr.Method.Name);
             Write('(');
             Write(expr.Obj);
             first = false;
             break;
         case CiCallType.Abstract:
         case CiCallType.Virtual:
         case CiCallType.Override:
             CiClass objClass = ((CiClassType) expr.Obj.Type).Class;
             CiClass ptrClass = GetVtblPtrClass(expr.Method.Class);
             CiClass defClass;
             for (defClass = expr.Method.Class; !AddsVirtualMethod(defClass, expr.Method.Name); defClass = defClass.BaseClass)
                 ;
             if (defClass != ptrClass) {
                 Write("((const ");
                 Write(defClass.Name);
                 Write("Vtbl *) ");
             }
             StartFieldAccess(expr.Obj);
             for (CiClass baseClass = objClass; baseClass != ptrClass; baseClass = baseClass.BaseClass)
                 Write("base.");
             Write("vtbl");
             if (defClass != ptrClass)
                 Write(')');
             Write("->");
             WriteCamelCase(expr.Method.Name);
             Write('(');
             if (objClass == defClass)
                 Write(expr.Obj);
             else {
                 Write('&');
                 StartFieldAccess(expr.Obj);
                 Write("base");
                 for (CiClass baseClass = objClass.BaseClass; baseClass != defClass; baseClass = baseClass.BaseClass)
                     Write(".base");
             }
             first = false;
             break;
         }
     }
     else {
         // delegate
         Write(expr.Obj);
         Write(".func(");
         Write(expr.Obj);
         Write(".obj");
         first = false;
     }
     foreach (CiExpr arg in expr.Arguments)
     {
         if (first)
             first = false;
         else
             Write(", ");
         Write(arg);
     }
     Write(')');
     // if (expr.Method.Throws) Write(" /* throws */");
     }
 }
Пример #15
0
	protected override void Write(CiMethodCall expr)
	{
		if (expr.Method == CiLibrary.MulDivMethod) {
#if USE_INTEGER
			// FIXME: overflow on 32-bit perl
			Write("(");
#else
			Write("int(");
#endif
			WriteMulDiv(CiPriority.Multiplicative, expr);
		}
		else if (expr.Method == CiLibrary.CharAtMethod) {
			Write("ord(substr(");
			Write(expr.Obj);
			Write(", ");
			Write(expr.Arguments[0]);
			Write(", 1))");
		}
		else if (expr.Method == CiLibrary.SubstringMethod) {
			Write("substr(");
			Write(expr.Obj);
			Write(", ");
			Write(expr.Arguments[0]);
			Write(", ");
			Write(expr.Arguments[1]);
			Write(')');
		}
		else if (expr.Method == CiLibrary.ArrayCopyToMethod) {
			CiExpr lenMinus1 = new CiBinaryExpr { Left = expr.Arguments[3], Op = CiToken.Minus, Right = new CiConstExpr(1) };
			WriteSlice(expr.Arguments[1], expr.Arguments[2], lenMinus1);
			Write(" = ");
			WriteSlice(expr.Obj, expr.Arguments[0], lenMinus1);
		}
		else if (expr.Method == CiLibrary.ArrayToStringMethod) {
			CiExpr lenMinus1 = new CiBinaryExpr { Left = expr.Arguments[1], Op = CiToken.Minus, Right = new CiConstExpr(1) };
			Write("pack('U*', ");
			WriteSlice(expr.Obj, expr.Arguments[0], lenMinus1);
			Write(')');
		}
		else if (expr.Method == CiLibrary.ArrayStorageClearMethod) {
			Write('@');
			if (expr.Obj is CiVarAccess)
				Write(((CiVarAccess) expr.Obj).Var.Name);
			else {
				Write('{');
				Write(expr.Obj);
				Write('}');
			}
			Write(" = (0) x ");
			Write(((CiArrayStorageType) expr.Obj.Type).Length);
		}
		else {
			if (expr.Method != null) {
				if (expr.Obj != null) {
					Write(expr.Obj);
					Write("->");
				}
				else {
					Write(this.Package);
					Write(expr.Method.Class.Name);
					Write("::");
				}
				WriteLowercaseWithUnderscores(expr.Method.Name);
			}
			else {
				// delegate call
				Write(expr.Obj);
				Write("->");
			}
			WriteArguments(expr);
		}
	}
Пример #16
0
 protected virtual void Write(CiMethodCall expr)
 {
     if (expr.Method != null) {
     if (expr.Obj != null)
         Write(expr.Obj);
     else
         Write(expr.Method.Class.Name);
     Write('.');
     WriteName(expr.Method);
     }
     else
     WriteDelegateCall(expr.Obj);
     WriteArguments(expr);
 }
Пример #17
0
 CiExpr ParsePrimaryExpr()
 {
     if (See(CiToken.Increment) || See(CiToken.Decrement) || See(CiToken.Minus) || See(CiToken.Not)) {
     CiToken op = this.CurrentToken;
     NextToken();
     CiExpr inner = ParsePrimaryExpr();
     return new CiUnaryExpr { Op = op, Inner = inner };
     }
     if (Eat(CiToken.CondNot)) {
     CiExpr inner = ParsePrimaryExpr();
     return new CiCondNotExpr { Inner = inner };
     }
     CiExpr result;
     if (See(CiToken.IntConstant)) {
     result = new CiConstExpr(this.CurrentInt);
     NextToken();
     }
     else if (See(CiToken.StringConstant)) {
     result = new CiConstExpr(this.CurrentString);
     NextToken();
     }
     else if (Eat(CiToken.LeftParenthesis)) {
     result = ParseExpr();
     Expect(CiToken.RightParenthesis);
     }
     else if (See(CiToken.Id)) {
     string name = ParseId();
     if (name == "BinaryResource")
         result = ParseBinaryResource();
     else {
         CiSymbol symbol = this.Symbols.TryLookup(name);
         if (symbol is CiMacro) {
             Expand((CiMacro) symbol);
             Expect(CiToken.LeftParenthesis);
             result = ParseExpr();
             Expect(CiToken.RightParenthesis);
         }
         else {
             if (symbol == null)
                 symbol = new CiUnknownSymbol { Name = name };
             result = new CiSymbolAccess { Symbol = symbol };
         }
     }
     }
     else if (Eat(CiToken.New)) {
     CiType newType = ParseType();
     if (!(newType is CiClassStorageType || newType is CiArrayStorageType))
         throw new ParseException("'new' syntax error");
     result = new CiNewExpr { NewType = newType };
     }
     else
     throw new ParseException("Invalid expression");
     for (;;) {
     if (Eat(CiToken.Dot))
         result = new CiUnknownMemberAccess { Parent = result, Name = ParseId() };
     else if (Eat(CiToken.LeftParenthesis)) {
         CiMethodCall call = new CiMethodCall();
         call.Obj = result;
         List<CiExpr> args = new List<CiExpr>();
         if (!See(CiToken.RightParenthesis)) {
             do
                 args.Add(ParseExpr());
             while (Eat(CiToken.Comma));
         }
         Expect(CiToken.RightParenthesis);
         call.Arguments = args.ToArray();
         result = call;
     }
     else if (Eat(CiToken.LeftBracket)) {
         CiExpr index = ParseExpr();
         Expect(CiToken.RightBracket);
         result = new CiIndexAccess { Parent = result, Index = index };
     }
     else if (See(CiToken.Increment) || See(CiToken.Decrement)) {
         CiToken op = this.CurrentToken;
         NextToken();
         return new CiPostfixExpr { Inner = result, Op = op };
     }
     else
         return result;
     }
 }
Пример #18
0
 protected void WriteArguments(CiMethodCall expr)
 {
     Write('(');
     bool first = true;
     foreach (CiExpr arg in expr.Arguments)
     {
     if (first)
         first = false;
     else
         Write(", ");
     Write(arg);
     }
     Write(')');
 }
Пример #19
0
Файл: GenCs.cs Проект: epi/cito
 protected override void Write(CiMethodCall expr)
 {
     if (expr.Method == CiLibrary.MulDivMethod) {
     Write("(int) ((long) ");
     WriteMulDiv(CiPriority.Prefix, expr);
     }
     else if (expr.Method == CiLibrary.CharAtMethod) {
     Write(expr.Obj);
     Write('[');
     Write(expr.Arguments[0]);
     Write(']');
     }
     else if (expr.Method == CiLibrary.SubstringMethod) {
     Write(expr.Obj);
     Write(".Substring(");
     Write(expr.Arguments[0]);
     Write(", ");
     Write(expr.Arguments[1]);
     Write(')');
     }
     else if (expr.Method == CiLibrary.ArrayCopyToMethod) {
     Write("System.Array.Copy(");
     Write(expr.Obj);
     Write(", ");
     Write(expr.Arguments[0]);
     Write(", ");
     Write(expr.Arguments[1]);
     Write(", ");
     Write(expr.Arguments[2]);
     Write(", ");
     Write(expr.Arguments[3]);
     Write(')');
     }
     else if (expr.Method == CiLibrary.ArrayToStringMethod) {
     Write("System.Text.Encoding.UTF8.GetString(");
     Write(expr.Obj);
     Write(", ");
     Write(expr.Arguments[0]);
     Write(", ");
     Write(expr.Arguments[1]);
     Write(')');
     }
     else if (expr.Method == CiLibrary.ArrayStorageClearMethod) {
     Write("System.Array.Clear(");
     Write(expr.Obj);
     Write(", 0, ");
     Write(((CiArrayStorageType) expr.Obj.Type).Length);
     Write(')');
     }
     else
     base.Write(expr);
 }
Пример #20
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(')');
 }
Пример #21
0
 protected override void Write(CiMethodCall expr)
 {
     if (expr.Method == CiLibrary.MulDivMethod)
     {
         Write("int(");
         WriteMulDiv(3, expr);
     }
     else if (expr.Method == CiLibrary.CharAtMethod)
     {
         Write(expr.Obj);
         Write(".charCodeAt(");
         Write(expr.Arguments[0]);
         Write(')');
     }
     else if (expr.Method == CiLibrary.SubstringMethod)
     {
         if (expr.Arguments[0].HasSideEffect)
         {
             Write("substring(");
             Write(expr.Obj);
             Write(", ");
             Write(expr.Arguments[0]);
             Write(", ");
             Write(expr.Arguments[1]);
             Write(')');
             this.UsesSubstringMethod = true;
         }
         else
         {
             Write(expr.Obj);
             Write(".substring(");
             Write(expr.Arguments[0]);
             Write(", ");
             Write(new CiBinaryExpr {
                 Left = expr.Arguments[0], Op = CiToken.Plus, Right = expr.Arguments[1]
             });
             Write(')');
         }
     }
     else if (expr.Method == CiLibrary.ArrayCopyToMethod)
     {
         Write("copyArray(");
         Write(expr.Obj);
         Write(", ");
         Write(expr.Arguments[0]);
         Write(", ");
         Write(expr.Arguments[1]);
         Write(", ");
         Write(expr.Arguments[2]);
         Write(", ");
         Write(expr.Arguments[3]);
         Write(')');
         this.UsesCopyArrayMethod = true;
     }
     else if (expr.Method == CiLibrary.ArrayToStringMethod)
     {
         Write("bytesToString(");
         Write(expr.Obj);
         Write(", ");
         Write(expr.Arguments[0]);
         Write(", ");
         Write(expr.Arguments[1]);
         Write(')');
         this.UsesBytesToStringMethod = true;
     }
     else if (expr.Method == CiLibrary.ArrayStorageClearMethod)
     {
         WriteClearArray(expr.Obj);
     }
     else
     {
         base.Write(expr);
     }
 }
Пример #22
0
 protected override void Write(CiMethodCall expr)
 {
     if (expr.Method == CiLibrary.MulDivMethod)
     {
         Write("(int) ((long) ");
         WriteMulDiv(2, expr);
     }
     else if (expr.Method == CiLibrary.CharAtMethod)
     {
         Write(expr.Obj);
         Write(".charAt(");
         Write(expr.Arguments[0]);
         Write(')');
     }
     else if (expr.Method == CiLibrary.SubstringMethod)
     {
         if (expr.Arguments[0].HasSideEffect)
         {
             Write("substring(");
             Write(expr.Obj);
             Write(", ");
             Write(expr.Arguments[0]);
             Write(", ");
             Write(expr.Arguments[1]);
             Write(')');
             this.UsesSubstringMethod = true;
         }
         else
         {
             Write(expr.Obj);
             Write(".substring(");
             Write(expr.Arguments[0]);
             Write(", ");
             WriteSum(expr.Arguments[0], expr.Arguments[1]);
             Write(')');
         }
     }
     else if (expr.Method == CiLibrary.ArrayCopyToMethod)
     {
         Write("System.arraycopy(");
         Write(expr.Obj);
         Write(", ");
         Write(expr.Arguments[0]);
         Write(", ");
         Write(expr.Arguments[1]);
         Write(", ");
         Write(expr.Arguments[2]);
         Write(", ");
         Write(expr.Arguments[3]);
         Write(')');
     }
     else if (expr.Method == CiLibrary.ArrayToStringMethod)
     {
         Write("new String(");
         Write(expr.Obj);
         Write(", ");
         Write(expr.Arguments[0]);
         Write(", ");
         Write(expr.Arguments[1]);
         Write(')');
     }
     else if (expr.Method == CiLibrary.ArrayStorageClearMethod)
     {
         Write("clear(");
         Write(expr.Obj);
         Write(')');
         CiType type = ((CiArrayStorageType)expr.Obj.Type).ElementType;
         if (type == CiByteType.Value)
         {
             this.UsesClearBytesMethod = true;
         }
         else if (type == CiIntType.Value)
         {
             this.UsesClearIntsMethod = true;
         }
         else
         {
             throw new ArgumentException(type.Name);
         }
     }
     else
     {
         base.Write(expr);
     }
 }
Пример #23
0
 protected override void Write(CiMethodCall expr)
 {
     if (expr.Method == CiLibrary.MulDivMethod) {
     Write("(int) ((long) ");
     WriteMulDiv(CiPriority.Prefix, expr);
     }
     else if (expr.Method == CiLibrary.CharAtMethod) {
     Write(expr.Obj);
     Write(".charAt(");
     Write(expr.Arguments[0]);
     Write(')');
     }
     else if (expr.Method == CiLibrary.SubstringMethod) {
     if (expr.Arguments[0].HasSideEffect) {
         Write("substring(");
         Write(expr.Obj);
         Write(", ");
         Write(expr.Arguments[0]);
         Write(", ");
         Write(expr.Arguments[1]);
         Write(')');
         this.UsesSubstringMethod = true;
     }
     else {
         Write(expr.Obj);
         Write(".substring(");
         Write(expr.Arguments[0]);
         Write(", ");
         WriteSum(expr.Arguments[0], expr.Arguments[1]);
         Write(')');
     }
     }
     else if (expr.Method == CiLibrary.ArrayCopyToMethod) {
     Write("System.arraycopy(");
     Write(expr.Obj);
     Write(", ");
     Write(expr.Arguments[0]);
     Write(", ");
     Write(expr.Arguments[1]);
     Write(", ");
     Write(expr.Arguments[2]);
     Write(", ");
     Write(expr.Arguments[3]);
     Write(')');
     }
     else if (expr.Method == CiLibrary.ArrayToStringMethod) {
     Write("new String(");
     Write(expr.Obj);
     Write(", ");
     Write(expr.Arguments[0]);
     Write(", ");
     Write(expr.Arguments[1]);
     Write(')');
     }
     else if (expr.Method == CiLibrary.ArrayStorageClearMethod) {
     Write("clear(");
     Write(expr.Obj);
     Write(')');
     CiType type = ((CiArrayStorageType) expr.Obj.Type).ElementType;
     if (type == CiByteType.Value)
         this.UsesClearBytesMethod = true;
     else if (type == CiIntType.Value)
         this.UsesClearIntsMethod = true;
     else
         throw new ArgumentException(type.Name);
     }
     else
     base.Write(expr);
 }
Пример #24
0
 protected override void Write(CiMethodCall expr)
 {
     if (expr.Method == CiLibrary.MulDivMethod)
     {
         Write("cast(int) (cast(long) ");
         WriteMulDiv(2, expr);
     }
     else if (expr.Method == CiLibrary.CharAtMethod)
     {
         Write(expr.Obj);
         Write('[');
         Write(expr.Arguments[0]);
         Write(']');
     }
     else if (expr.Method == CiLibrary.SubstringMethod)
     {
         Write(expr.Obj);
         Write('[');
         Write(expr.Arguments[0]);
         Write(" .. (");
         Write(expr.Arguments[0]);
         Write(") + ");
         Write(expr.Arguments[1]);
         Write(']');
     }
     else if (expr.Method == CiLibrary.ArrayCopyToMethod)
     {
         Write(expr.Arguments[1]);
         Write('[');
         Write(expr.Arguments[2]);
         Write(" .. (");
         Write(expr.Arguments[2]);
         Write(") + ");
         Write(expr.Arguments[3]);
         Write("] = ");
         Write(expr.Obj);
         Write('[');
         Write(expr.Arguments[0]);
         Write(" .. (");
         Write(expr.Arguments[0]);
         Write(") + ");
         Write(expr.Arguments[3]);
         Write(']');
     }
     else if (expr.Method == CiLibrary.ArrayToStringMethod)
     {
         Write("toUTF8(cast(char[]) ");
         Write(expr.Obj);
         Write('[');
         Write(expr.Arguments[0]);
         Write(" .. (");
         Write(expr.Arguments[0]);
         Write(") + ");
         Write(expr.Arguments[1]);
         Write("])");
     }
     else if (expr.Method == CiLibrary.ArrayStorageClearMethod)
     {
         Write(expr.Obj);
         Write("[] = 0");
     }
     else
     {
         base.Write(expr);
     }
 }