public static ArrayCreationNode Parse(ContextNode context, IAbstractSyntaxTree lexerNode) { Contract.Requires(lexerNode.Type == Lexer.TokenType.ArrayLiteral); Contract.Ensures(Contract.Result <ArrayCreationNode>() != null); var point = context.Parser.GetSequencePoint(lexerNode); if (lexerNode.Children.Count == 1) { var initializer = InitializerList.Parse(context, lexerNode.Children[0]); return(Create(context, initializer, point)); } else { var builder = new TypeNode.TypeBuilder(context); var lexerType = lexerNode.Children[0]; for (int i = 0; i < lexerType.Children.Count - 1; i++) { builder.Append(lexerType.Children[i]); } //.Last() returns parameter list var last = lexerType.Children.Last().Children[0]; var elementType = builder.Type; IReadOnlyList <ExpressionNode> dims; if (ArrayAccessNode.IsEmptyIndexer(last)) { dims = Enumerable.Repeat((ExpressionNode)null, ArrayAccessNode.CountEmptyIndexerDims(last)).ToArray(); } else { dims = ArrayAccessNode.ParseIndex(context, last); } var initializer = InitializerList.Parse(context, lexerNode.Children[1]); return(Create(context, elementType, dims, initializer, point)); } }
private static InitializerList CreateEmpty(ContextNode context, SequencePoint point) { var instace = new InitializerList(point); instace.Dimensions = new int[] { 0 }; instace.Initializers = Enumerable.Empty <ExpressionNode>(); instace.ElementType = context.Parser.Object; return(instace); }
public static InitializerList Create(ContextNode context, IEnumerable <InitializerList> subLists, SequencePoint point) { //cant create a matrix if the list is {} Contract.Ensures(subLists.Any()); var first = subLists.First(); if (!subLists.Skip(1).All(l => l.Dimensions.SequenceEqual(first.Dimensions))) { ErrorCode.MisshapedMatrix.ReportAndThrow(point, "Invalid intializer list structure, all sublists must have same dimmensions"); } var instance = new InitializerList(point); instance.Initializers = Utils.Utils.ConcatAll(subLists.Select(s => s.Initializers)); instance.ElementType = TypeUtils.GetCommonBaseClass(context.Assembly, subLists.Select(s => s.ElementType)); instance.Dimensions = subLists.Count().Enumerate().Concat(first.Dimensions).ToArray(); return(instance); }
public override string ToString(int indent) { StringBuilder builder = new StringBuilder(); builder.Indent(indent).AppendLine("ArrayCreation:"); builder.Indent(indent + 1).AppendFormat("ElementType: {0}", type.ElementType).AppendLine(); builder.Indent(indent + 1).AppendFormat("Rank: {0}", type.Rank).AppendLine(); builder.Indent(indent + 1).AppendLine("Dimensions:"); foreach (var dim in dimensions) { builder.AppendLine(dim.ToString(indent + 2)); } if (InitializerList != null) { builder.Indent(indent + 1).AppendLine("Initializer:"); builder.AppendLine(InitializerList.ToString(indent + 2)); } return(builder.ToString()); }
public static InitializerList Parse(ContextNode context, IAbstractSyntaxTree lexerNode) { Contract.Requires(lexerNode.Type == Lexer.TokenType.InitializerList); Contract.Ensures(Contract.Result <InitializerList>() != null); var point = context.Parser.GetSequencePoint(lexerNode); var instance = new InitializerList(point); var members = new List <ExpressionNode>(); foreach (var node in lexerNode.Children) { switch (node.Type) { case Lexer.TokenType.LeftCurlyBrace: case Lexer.TokenType.RightCurlyBrace: case Lexer.TokenType.Comma: break; case Lexer.TokenType.Value: members.Add(ExpressionNode.Parse(context, node)); break; } } var arrays = members.Select(m => m as ArrayCreationNode); //implicit = initializer list if (arrays.Any(a => a != null && a.IsImplicit)) { if (arrays.Any(a => a == null || !a.IsImplicit)) { ErrorCode.MisshapedMatrix.ReportAndThrow(point, "An initializer list can only contain another initializer list if all members are lists of the same dimmensions and types"); } var lists = arrays.Select(a => a.InitializerList); return(Create(context, lists, point)); } return(Create(context, members, point)); }
public static InitializerList Create(ContextNode context, IEnumerable <ExpressionNode> expressions, SequencePoint point) { Contract.Ensures(Contract.Result <InitializerList>() != null); if (!expressions.Any()) { return(CreateEmpty(context, point)); } foreach (var exp in expressions) { if (!exp.IsGettable) { ErrorCode.NotAnRValue.ReportAndThrow(exp.SequencePoint, "Initializer list items must be gettable"); } } var instance = new InitializerList(point); instance.ElementType = TypeUtils.GetCommonBaseClass(context.Assembly, expressions.Select(e => e.ExpressionReturnType)); instance.Dimensions = new int[] { expressions.Count() }; instance.Initializers = expressions; return(instance); }
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); }
public static ArrayCreationNode Create(ContextNode context, InitializerList initializer, SequencePoint point) { return(Create(context, null, null, initializer, point)); }