public static ExpressionNode Parse(ContextNode context, IAbstractSyntaxTree lexerNode, TypeReference expectedType = null) { Contract.Ensures(Contract.Result <ExpressionNode>() != null); ExpressionNode ret = null; switch (lexerNode.Type) { case Lexer.TokenType.FullSymbol: case Lexer.TokenType.Symbol: ret = DotOperatorNode.Parse(context, lexerNode); break; case Lexer.TokenType.LiteralNode: ret = LiteralNode.Parse(context, lexerNode); break; case Lexer.TokenType.Value: ret = ExpressionNode.Parse(context, lexerNode.Children[0], expectedType); break; case Lexer.TokenType.Function: ret = MethodNode.Parse(context, lexerNode); break; case Lexer.TokenType.InfixNode: ret = InfixParser.Parse(context, lexerNode); break; case Lexer.TokenType.PostfixNode: case Lexer.TokenType.PrefixNode: ret = UnaryOperators.Parse(context, lexerNode); break; case Lexer.TokenType.ParenthesesNode: ret = ExpressionNode.Parse(context, lexerNode.Children[1], expectedType); break; case Lexer.TokenType.ArrayLiteral: ret = ArrayCreationNode.Parse(context, lexerNode); break; case Lexer.TokenType.Null: ret = NullNode.Parse(context, lexerNode); break; default: ContractsHelper.AssumeUnreachable("Unknown expression type {0}", lexerNode.Type); break; } if (!(expectedType == null || expectedType.IsAuto())) { var ambiguous = ret as IAmbiguousNode; if (ambiguous != null) { ret = ambiguous.RemoveAmbiguity(context, expectedType); } } return(ret); }
private static ArrayCreationNode AsArrayCreation(ContextNode context, ExpressionNode array, IReadOnlyList <ExpressionNode> indices, SequencePoint point) { var type = array as TypeNode; if (type == null) { return(null); } return(ArrayCreationNode.Create(context, type.ParsedType, indices, null, point)); }
public static ArrayCreationNode Create(ContextNode context, TypeReference elementType, IReadOnlyList <ExpressionNode> dims, InitializerList initializer, SequencePoint point) { //rank 0 makes no sense Contract.Requires(dims == null || dims.Any()); Contract.Requires(elementType != null || initializer != null); //dims are declared inside the type, both must be null or not null Contract.Requires((dims == null) == (elementType == null)); //cant have [5,] or some shit Contract.Requires(dims == null || dims.All(d => d == null) || !dims.Any(d => d == null)); Contract.Ensures(Contract.Result <ArrayCreationNode>() != null); var instance = new ArrayCreationNode(point); if (elementType == null) { if (initializer == null) { ErrorCode.MissingArraySize.ReportAndThrow(point, "Cannot create array without size or an initializer"); } if (initializer.ElementType.IsTypeless()) { ErrorCode.InferrenceFromTypeless.ReportAndThrow(initializer.SequencePoint, "Cannot infer array type from typeless expressions"); } elementType = initializer.ElementType; instance.IsImplicit = true; dims = CreateArrayDims(context, point, initializer.Dimensions.ToArray()); } if (initializer != null && dims.Count() != initializer.Dimensions.Count()) { ErrorCode.ArrayDimMismatch.ReportAndThrow(point, "Cannot initialize array of {0} dimmensions with a matrix of {1} dimmensions", dims.Count(), initializer.Dimensions.Count()); } if (dims.Any(d => d == null)) { if (initializer == null) { ErrorCode.MissingArraySize.ReportAndThrow(point, "Cannot create array with implicit dimensions without initialization"); } dims = CreateArrayDims(context, point, initializer.Dimensions.ToArray()); } else { if (initializer != null && dims.Any(dim => !(dim is LiteralNode))) { ErrorCode.NotLiteralArrayDims.ReportAndThrow(point, "When initializing arrays, dimensions must be literal, or implicit"); } } foreach (var dim in dims) { if (!IsValidArrayDim(context.Parser, dim)) { ErrorCode.NotAnRValue.ReportAndThrow(dim.SequencePoint, "Array dimensions must be gettable integer expressions"); } } if (initializer != null && !initializer.Initializers.Any()) { initializer = null; } if (initializer != null) { if (!initializer.ElementType.IsAssignableTo(elementType)) { ErrorCode.TypeMismatch.ReportAndThrow(point, "Cannot initializer array of element type {0} when initializer element type is {1}", elementType.FullName, initializer.ElementType.FullName); } var numericDims = dims.Cast <LiteralNode>().Select(num => (int)num.Value).ToArray(); for (int i = 0; i < dims.Count; i++) { var value = numericDims[i]; if (value != initializer.Dimensions[i]) { ErrorCode.ArrayDimMismatch.ReportAndThrow(point, "Dimension mismatch, array dimensions are [{0}] initializer are [{1}]", String.Join(", ", numericDims), String.Join(", ", initializer.Dimensions)); } } } instance.type = AssemblyRegistry.GetArrayType(elementType, dims.Count); instance.dimensions = dims; instance.InitializerList = initializer; return(instance); }