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))); }
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)); }
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")); }
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); }
// special public virtual ReturnType VisitArgumentExpr(AstArgument expr, DataType data = default) => default;
public void WriteArgument(AstArgument a) { Write(a.OptionalName); Write((byte)a.Modifier); Write(a.Value); }
public AstNodeExprArgument(AstArgument astArgument) { AstArgument = astArgument; }
public AstNodeExprArgument(AstArgument AstArgument) { this.AstArgument = AstArgument; }