示例#1
0
        public Expression CompileAddToCollection(string collecionName, AstExpression initializer)
        {
            AstArgument[] addArgs;

            if (initializer is AstArrayInitializer)
            {
                var ai = initializer as AstArrayInitializer;
                if (ai.Values.Count == 0)
                {
                    return(Error(initializer.Source, ErrorCode.E2079, "Element initializer cannot be empty"));
                }

                addArgs = new AstArgument[ai.Values.Count];

                for (int j = 0; j < addArgs.Length; j++)
                {
                    addArgs[j] = ai.Values[j];
                }
            }
            else
            {
                addArgs = new AstArgument[] { initializer }
            };

            return(CompileCall(
                       new AstCall(
                           AstCallType.Function,
                           new AstMember(
                               new AstIdentifier(initializer.Source, collecionName),
                               new AstIdentifier(initializer.Source, "Add")),
                           addArgs)));
        }
示例#2
0
 public override string VisitArgumentExpr(AstArgument expr, int data = 0)
 {
     if (expr.Name != null)
     {
         return($"{expr.Name.Accept(this)} = {expr.Expr.Accept(this)}");
     }
     return(expr.Expr.Accept(this));
 }
示例#3
0
文件: AstReader.cs 项目: mortend/uno
        public AstArgument[] ReadArguments()
        {
            var len = Read7BitEncodedInt() - 1;

            if (len == -1)
            {
                return(null);
            }

            var result = new AstArgument[len];

            for (int i = 0; i < len; i++)
            {
                result[i] = new AstArgument(
                    (AstIdentifier)ReadExpression(),
                    (ParameterModifier)ReadByte(),
                    ReadExpression());
            }
            return(result);
        }
        public void TestAstSwitch()
        {
            var argument = AstArgument.Create <int>(0, "Value");
            var ast      = Ast.Statements(
                Ast.Switch(
                    Ast.Argument(argument),
                    Ast.Default(Ast.Return("-")),
                    Ast.Case(1, Ast.Return("One")),
                    Ast.Case(3, Ast.Return("Three"))
                    ),
                Ast.Return("Invalid!")
                );
            var generatorIl = new GeneratorIl();
            var method      = generatorIl.GenerateDelegate <Func <int, string> >("TestSwitch", ast);

            Assert.Equal("-", method(0));
            Assert.Equal("One", method(1));
            Assert.Equal("-", method(2));
            Assert.Equal("Three", method(3));
            Assert.Equal("-", method(4));
        }
        public void TestAstSwitch()
        {
            var Argument = AstArgument.Create <int>(0, "Value");
            var Ast      = ast.Statements(
                ast.Switch(
                    ast.Argument(Argument),
                    ast.Default(ast.Return("-")),
                    ast.Case(1, ast.Return("One")),
                    ast.Case(3, ast.Return("Three"))
                    ),
                ast.Return("Invalid!")
                );
            var GeneratorIL = new GeneratorIL();
            var Method      = GeneratorIL.GenerateDelegate <Func <int, string> >("TestSwitch", Ast);

            Assert.AreEqual("-", Method(0));
            Assert.AreEqual("One", Method(1));
            Assert.AreEqual("-", Method(2));
            Assert.AreEqual("Three", Method(3));
            Assert.AreEqual("-", Method(4));
        }
        public Expression CompileCall(AstCall e)
        {
            // Builtin struct initialization
            if (e.Base is AstBuiltinType)
            {
                var dt = NameResolver.GetType(Namescope, e.Base);

                if (dt.IsStruct)
                {
                    // Default ctor
                    if (e.Arguments.Count == 0)
                    {
                        return(new Default(e.Source, dt));
                    }

                    dt.PopulateMembers();

                    Constructor  ctor;
                    Expression[] args;
                    return(TryResolveConstructorOverload(e.Source, dt.Constructors, e.Arguments, out ctor, out args)
                        ? new NewObject(e.Source, ctor, args)
                        : Error(e.Source, ErrorCode.E3125, dt.Quote() + " has no constructors matching the argument list " +
                                PrintableArgumentList(e.Arguments) +
                                NameResolver.SuggestCandidates(dt.Constructors)));
                }

                return(Error(e.Source, ErrorCode.E3126, dt.Quote() + " must be instantiated using 'new' because it is not a struct"));
            }

            var pe = ResolveExpression(e.Base, null);

            switch (pe.ExpressionType)
            {
            case PartialExpressionType.Block:
            case PartialExpressionType.Type:
            case PartialExpressionType.Namespace:
                if (e.Base is AstIdentifier)
                {
                    var p2 = NameResolver.TryResolveUsingType(Namescope, e.Base as AstIdentifier, null);
                    if (p2 != null)
                    {
                        pe = p2;
                    }
                }
                break;
            }

            var sym = CompilePartial(pe);

            if (sym.IsInvalid)
            {
                return(Expression.Invalid);
            }

            // Delegate call
            if (sym.ReturnType.IsDelegate)
            {
                var dt = (DelegateType)sym.ReturnType;
                dt.AssignBaseType();
                var args = TryApplyDefaultValuesOnArgumentList(sym.Source, dt.Parameters, CompileArgumentList(e.Arguments));
                return(TryApplyImplicitCastsOnArgumentList(dt.Parameters, args)
                    ? new CallDelegate(e.Source, sym, args)
                    : Error(e.Source, ErrorCode.E3127, "Call to delegate of type " + dt.Quote() + " has some invalid arguments " +
                            PrintableArgumentList(e.Arguments)));
            }

            // Using static fall back
            if (!(sym is MethodGroup) && e.Base is AstIdentifier)
            {
                var p2 = NameResolver.TryResolveUsingType(Namescope, e.Base as AstIdentifier, null);
                if (p2 != null)
                {
                    sym = CompilePartial(p2);
                    if (sym.IsInvalid)
                    {
                        return(Expression.Invalid);
                    }
                }
            }

            // Method call
            if (sym is MethodGroup)
            {
                var g = sym as MethodGroup;

                Method       method;
                Expression[] args;
                return(TryResolveMethodOverload(e.Source, g.Candidates, e.Arguments, out method, out args)
                    ? (g.IsQualified && g.Object != null && method.IsStatic
                            ? Error(sym.Source, ErrorCode.E3123, method.Quote() + " is static -- qualify with the type name") :
                       g.Object == null && !method.IsStatic
                            ? Error(sym.Source, ErrorCode.E3124, method.Quote() + " is non-static and cannot be accessed from a static context")
                            : new CallMethod(e.Source, method.IsStatic ? null : g.Object, method, args))
                    : g.Candidates.Count == 1
                        ? Error(e.Source, ErrorCode.E3128, "Call to " + g.Candidates[0].Quote() + " has some invalid arguments " +
                                PrintableArgumentList(e.Arguments))
                        : Error(e.Source, ErrorCode.E3129, "No overloads of " + g.CandidatesBaseName.Quote() + " matches the argument list " +
                                PrintableArgumentList(e.Arguments) +
                                NameResolver.SuggestCandidates(g.Candidates)));
            }

            // Extension method call
            if (sym is ExtensionGroup)
            {
                var g = sym as ExtensionGroup;

                Method       method;
                Expression[] args;
                var          astArgs = new AstArgument[e.Arguments.Count + 1];
                astArgs[0] = new AstIL(g.Object);
                for (int i = 0; i < e.Arguments.Count; i++)
                {
                    astArgs[i + 1] = e.Arguments[i];
                }

                return(TryResolveMethodOverload(e.Source, g.Candidates, astArgs, out method, out args)
                    ? new CallMethod(e.Source, null, method, args)
                    : g.Candidates.Count == 1
                        ? Error(e.Source, ErrorCode.E3128, "Call to " + g.Candidates[0].Quote() + " has some invalid arguments " +
                                PrintableArgumentList(astArgs))
                        : Error(e.Source, ErrorCode.E3129, "No overloads of " + g.CandidatesBaseName.Quote() + " matches the argument list " +
                                PrintableArgumentList(e.Arguments) +
                                NameResolver.SuggestCandidates(g.Candidates)));
            }

            return(Error(e.Source, ErrorCode.E3130, "Instances of type " + sym.ReturnType.Quote() + " cannot be called as a function"));
        }
示例#7
0
        public IEntity GetEntity(Source src, string str, params Namescope[] scopes)
        {
            if (string.IsNullOrEmpty(str))
            {
                Log.Error(src, ErrorCode.E0000, "<null> could not be resolved");
                return(DataType.Invalid);
            }

            // Special case void because that is not a valid expression
            if (str == "void")
            {
                return(DataType.Void);
            }

            var log = new Log(TextWriter.Null);
            var e   = str[0] == '.' ? null : Parser.ParseExpression(log, src, str);

            if (log.HasErrors || e == null)
            {
                // Custom code to handle special cases not supported in the parser.
                // E.g.: foo(ref fixed float[8]), .ctor(), .cctor()

                string        basePart = null;
                AstArgument[] args     = null;

                str = str.Trim();

                if (str.EndsWith(')'))
                {
                    var parts = str.Split('(');

                    if (parts.Length == 2)
                    {
                        basePart = parts[0];
                        var argsPart = parts[1].Substring(0, parts[1].Length - 1);
                        if (argsPart.Length > 0)
                        {
                            var argParts = argsPart.Split(',');
                            args = new AstArgument[argParts.Length];

                            for (int i = 0; i < args.Length; i++)
                            {
                                var argPart = argParts[i].Trim();

                                if (argPart.StartsWith("ref fixed ", StringComparison.InvariantCulture) &&
                                    argPart.EndsWith(']'))
                                {
                                    argPart = argPart.Substring(10);

                                    var index    = argPart.LastIndexOf('[');
                                    var sizePart = argPart.Substring(index + 1, argPart.Length - index - 2);

                                    AstExpression size = null;
                                    if (sizePart.Length > 0)
                                    {
                                        size = Parser.ParseExpression(Log, src, sizePart);
                                    }

                                    var type = Parser.ParseType(Log, src, argPart.Substring(0, index));
                                    args[i] = new AstArgument(null, ParameterModifier.Ref, new AstFixedArray(src, type, size));
                                }
                                else if (argPart.StartsWith("ref ", StringComparison.InvariantCulture))
                                {
                                    args[i] = new AstArgument(null, ParameterModifier.Ref, Parser.ParseType(Log, src, argPart.Substring(4)));
                                }
                                else if (argPart.StartsWith("out ", StringComparison.InvariantCulture))
                                {
                                    args[i] = new AstArgument(null, ParameterModifier.Out, Parser.ParseType(Log, src, argPart.Substring(4)));
                                }
                                else
                                {
                                    args[i] = Parser.ParseType(Log, src, argPart);
                                }
                            }
                        }
                    }
                }

                if (basePart == null)
                {
                    basePart = str;
                }

                if (basePart == ".ctor" || basePart == ".cctor")
                {
                    e = new AstIdentifier(src, basePart);
                }
                else
                {
                    e = Parser.ParseExpression(Log, src, basePart);
                }

                if (args != null)
                {
                    e = new AstCall(AstCallType.Function, e, args);
                }
                else if (basePart != str)
                {
                    e = new AstCall(AstCallType.Function, e);
                }
            }

            var result = ResolveExpression(e, null, scopes ?? new Namescope[0]);

            if (result is Function && e.ExpressionType != AstExpressionType.Call)
            {
                Log.Error(src, ErrorCode.E3355, str.Quote() + " is a method and must include the parameter list");
                return(DataType.Invalid);
            }

            if (result is IEntity)
            {
                return(result as IEntity);
            }

            Log.Error(src, ErrorCode.E3356, str.Quote() + " could not be resolved");
            return(DataType.Invalid);
        }
示例#8
0
 // special
 public virtual ReturnType VisitArgumentExpr(AstArgument expr, DataType data       = default) => default;
示例#9
0
 public void WriteArgument(AstArgument a)
 {
     Write(a.OptionalName);
     Write((byte)a.Modifier);
     Write(a.Value);
 }
示例#10
0
 public AstNodeExprArgument(AstArgument astArgument)
 {
     AstArgument = astArgument;
 }
 public AstNodeExprArgument(AstArgument AstArgument)
 {
     this.AstArgument = AstArgument;
 }
示例#12
0
 public AstNodeExprArgument(AstArgument AstArgument)
 {
     this.AstArgument = AstArgument;
 }