private static string constructarray2str(ConstructArray ca) { return ("anew " + ca.ElementType.FullName + "[" + exprlist2str(ca.Operands) + "]" + ((ca.Initializers == null) ? "" : ("{" + exprlist2str(ca.Initializers)) + "}")); }
public void ConstructArrayTest() { // Arrange var data = MakeArray(); var op = new ConstructArray { Elements = new Enumerate() }; // Act var result = op.RunAsSequence(data); // Assert result.Count().Should().Be(1); result.First().DeepEqual(data).Should().BeTrue(); }
public void LetAndGetVariableSequenceTest() { // Arrange var data = "[1,2,3]".AsJson(); var op = new ConstructArray { Elements = new Let { Value = new Enumerate(), Matcher = new ValueMatcher("var"), Body = new GetVariable { Name = "var" } } }; // Act var result = op.RunAsScalar(data); // Assert result.DeepEqual(data).Should().BeTrue(); }
public static Block createElementInitializerInternal(TYPE type, Expression indexer, int level, List <Expression> nonConstantDimensions, bool skipFirstLevel, SourceContext sourceContext) { // Generates internal part of array initializer: // either object constructor or, again, array initializer. // Check if the type is ARRAY. if (!(type is ARRAY_TYPE) && !(type is OBJECT_TYPE)) { return(null); } if (type is ARRAY_TYPE) { EXPRESSION_LIST declaredDimensions = ((ARRAY_TYPE)type).dimensions; int Rank = declaredDimensions.Length; List <Expression> dimensions = new List <Expression>(); // Check if all dimensions are constants or there is an expression available. for (int i = 0, n = Rank; i < n; i++) { if (declaredDimensions[i] == null || declaredDimensions[i].calculate() == null) { if (nonConstantDimensions == null) { return(null); } if (nonConstantDimensions.Count > 0) { dimensions.Add(nonConstantDimensions[0]); nonConstantDimensions.RemoveAt(0); } else { ERROR.MissingParameters(Rank, type.sourceContext); return(null); } } else { long d = (long)declaredDimensions[i].calculate(); Literal dim = new Literal((int)d, SystemTypes.Int32); dimensions.Add(dim); } } Block block = new Block(new StatementList()); // Generate array initializer: // x = new object[n]; if (skipFirstLevel && level == 0) { goto Bypass; } AssignmentStatement array_initializer = new AssignmentStatement(); array_initializer.NodeType = NodeType.AssignmentStatement; array_initializer.Operator = NodeType.Nop; // this means "normal" assignment, but not += etc. // Generate 'new object[n]' ConstructArray array_construct = new ConstructArray(); Node elem_type = ((ARRAY_TYPE)type).base_type.convert(); if (elem_type is ArrayTypeExpression) { ArrayTypeExpression arr_type = (elem_type.Clone()) as ArrayTypeExpression; // for ( int i=0, n=arr_type.Rank; i<n; i++ ) // arr_type.Sizes[i] = -1; elem_type = arr_type; } array_construct.ElementType = (TypeNode)elem_type; array_construct.Rank = Rank; array_construct.SourceContext = sourceContext; array_construct.Type = (TypeNode)type.convert(); array_construct.Operands = new ExpressionList(); for (int i = 0; i < Rank; i++) { array_construct.Operands.Add(dimensions[i]); } array_initializer.Source = array_construct; array_initializer.Target = indexer; array_initializer.SourceContext = sourceContext; block.Statements.Add(array_initializer); Bypass: // Generate x[i0,i1,...] for passing to the recursive call. Indexer new_indexer = new Indexer(); new_indexer.Object = indexer; new_indexer.Type = type.convert() as TypeNode; new_indexer.ElementType = ((ARRAY_TYPE)type).base_type.convert() as TypeNode; new_indexer.Operands = new ExpressionList(); for (int i = 0; i < Rank; i++) { Identifier index = Identifier.For("_i" + (level + i).ToString()); new_indexer.Operands.Add(index); } // Generate the last part (see comment, part 4, below). Block elem_initializers = createElementInitializerInternal(((ARRAY_TYPE)type).base_type, new_indexer, level + Rank, nonConstantDimensions, true, sourceContext); if (elem_initializers == null) { return(block); } // We do not need loops to initialize elements... // Return just array initializer. // Otherwise go generate initializers. // Generate // 1) int i0, i1, ...; // 2) for (int i1=0; i1<n; i1++) // for (int i2=0; i2<m; i2++) // ... // // Generate recursively: // 3) Initializers for array elements: x[i1,i2,...] = new object[n]; // 4) Initializers for every element (the similar loop(s)). // Generate int i0, i1, ...; for (int i = 0; i < Rank; i++) { VariableDeclaration locali = new VariableDeclaration(Identifier.For("_i" + (level + i).ToString()), SystemTypes.Int32, null); block.Statements.Add(locali); } // Generate loop headers: // for (int i1=0; i1<n; i1++) // for (int i2=0; i2<m; i2++) // ... Block owner = block; // where to put generated for-node for (int i = 0; i < Rank; i++) { For forStatement = new For(); // forStatement.NodeType; forStatement.SourceContext = sourceContext; // Making for-statement's body forStatement.Body = new Block(); forStatement.Body.Checked = true; forStatement.Body.HasLocals = false; // forStatement.Body.NodeType; // forStatement.Body.Scope; forStatement.Body.SourceContext = sourceContext; forStatement.Body.SuppressCheck = false; forStatement.Body.Statements = new StatementList(); // Now leave the body empty... // Making condition: i<n BinaryExpression condition = new BinaryExpression(); condition.NodeType = NodeType.Lt; condition.Operand1 = Identifier.For("_i" + (level + i).ToString()); condition.Operand2 = dimensions[i]; condition.SourceContext = sourceContext; forStatement.Condition = condition; // Making incrementer: i+=1 forStatement.Incrementer = new StatementList(); AssignmentStatement assignment = new AssignmentStatement(); assignment.NodeType = NodeType.AssignmentStatement; assignment.Operator = NodeType.Add; // Hope this means += // assignment.OperatorOverload assignment.Source = new Literal((int)1, SystemTypes.Int32); assignment.SourceContext = sourceContext; assignment.Target = Identifier.For("_i" + (level + i).ToString()); forStatement.Incrementer.Add(assignment); // Making initializer: i=0 forStatement.Initializer = new StatementList(); AssignmentStatement initializer = new AssignmentStatement(); initializer.NodeType = NodeType.AssignmentStatement; initializer.Operator = NodeType.Nop; // this means "normal" assignment, but not += etc. initializer.Source = new Literal(0, SystemTypes.Int32); initializer.Target = Identifier.For("_i" + (level + i).ToString()); initializer.SourceContext = sourceContext; forStatement.Initializer.Add(initializer); owner.Statements.Add(forStatement); owner = forStatement.Body; // for next iteration } // Adding element initializers generated in advance. owner.Statements.Add(elem_initializers); return(block); } else if (type is OBJECT_TYPE) { // Check if the type is VAL-object. if (!((OBJECT_TYPE)type).ObjectUnit.modifiers.Value) { return(null); } Block block = new Block(new StatementList()); // Generate 'new obj' DECLARATION objct = ((OBJECT_TYPE)type).ObjectUnit; // We do it for only own value types. They have // extra constcutor that takes ont fictive intgere. Might have // Chtck and call it Construct construct = new Construct(); // Strange thing: CCI expects _class_ in Construst.Constructor, // but not a constructor itself!.. // construct.Constructor = new MemberBinding(null,((TypeNode)objct.convert()).GetConstructors()[0]); // NODE.convertTypeName(objct); construct.Constructor = new MemberBinding(null, (TypeNode)objct.convert()); construct.Constructor.Type = SystemTypes.Type; construct.Operands = new ExpressionList(); construct.SourceContext = sourceContext; construct.Type = (TypeNode)objct.convert(); construct.Operands.Add(new Literal(1, SystemTypes.Int32)); // Generate x[i0,i1,...] = new obj; AssignmentStatement main_initializer = new AssignmentStatement(); main_initializer.NodeType = NodeType.AssignmentStatement; main_initializer.Operator = NodeType.Nop; // this means "normal" assignment, but not += etc. main_initializer.Source = construct; main_initializer.Target = indexer; main_initializer.SourceContext = sourceContext; block.Statements.Add(main_initializer); return(block); } else if (type is EXTERNAL_TYPE) { // Only value types might need extra calls Struct str = ((EXTERNAL_TYPE)type).entity as Struct; InstanceInitializer ctr = str.GetConstructor(new TypeNode[] { SystemTypes.Int32 }); bool possibly_was_our_structure = (ctr != null); if (ctr == null) { ctr = str.GetConstructor(new TypeNode[0] { }); } // TO_DO: When metadata is available replace this with // more consistent check Block block = new Block(new StatementList()); // Generate 'new obj' Construct construct = new Construct(); construct.Constructor = new MemberBinding(null, ctr); construct.Operands = new ExpressionList(); construct.Type = str; // We do it for only own value types. They have // extra constcutor that takes ont fictive intgere. Might have // Chtck and call it if (possibly_was_our_structure) { construct.Operands.Add(Literal.Int32MinusOne); } // Generate x[i0,i1,...] = new obj; AssignmentStatement main_initializer = new AssignmentStatement(); main_initializer.NodeType = NodeType.AssignmentStatement; main_initializer.Operator = NodeType.Nop; // this means "normal" assignment, but not += etc. main_initializer.Source = construct; main_initializer.Target = indexer; main_initializer.SourceContext = sourceContext; indexer.Type = construct.Type; block.Statements.Add(main_initializer); return(block); } else { return(null); } }
public override Expression VisitConstructArray(ConstructArray consArr) { throw new ApplicationException("unimplemented"); }
private static string constructarray2str(ConstructArray ca) { return "anew " + ca.ElementType.FullName + "[" + exprlist2str(ca.Operands) + "]" + ((ca.Initializers == null) ? "" : ( "{" + exprlist2str(ca.Initializers)) + "}"); }
public override Expression VisitConstructArray(ConstructArray consArr) { if (consArr == null) return null; return base.VisitConstructArray((ConstructArray)consArr.Clone()); }
public virtual Expression VisitConstructArray(ConstructArray consArr){ if (consArr == null) return null; consArr.ElementType = this.VisitTypeReference(consArr.ElementType); consArr.Operands = this.VisitExpressionList(consArr.Operands); #if !MinimalReader consArr.Initializers = this.VisitExpressionList(consArr.Initializers); consArr.Owner = this.VisitExpression(consArr.Owner); #endif return consArr; }
public virtual void CoerceArguments(ParameterList parameters, ref ExpressionList arguments, bool doNotVisitArguments, CallingConventionFlags callingConvention) { if (arguments == null) arguments = new ExpressionList(); int n = arguments.Count; int m = parameters == null ? 0 : parameters.Count; //if fewer arguments than parameters, supply default values for (; n < m; n++) { Parameter p = parameters[n]; TypeNode type = p == null ? null : p.Type; if (type == null) type = SystemTypes.Object; type = TypeNode.StripModifiers(type); if (p.DefaultValue != null) arguments.Add(p.DefaultValue); else { //There should already have been a complaint. Just recover. TypeNode elementType = parameters[n].GetParamArrayElementType(); if (elementType != null) break; arguments.Add(new UnaryExpression(new Literal(type, SystemTypes.Type), NodeType.DefaultValue, type)); } } if (m > 0) { TypeNode elementType = TypeNode.StripModifiers(parameters[m-1].GetParamArrayElementType()); TypeNode lastArgType = null; if (elementType != null && (n > m || (n == m - 1) || n == m && (lastArgType = TypeNode.StripModifiers(arguments[m-1].Type)) != null && !this.GetTypeView(lastArgType).IsAssignableTo(TypeNode.StripModifiers(parameters[m-1].Type)) && !(arguments[m-1].Type == SystemTypes.Object && arguments[m-1] is Literal && ((Literal)arguments[m-1]).Value == null))) { ExpressionList varargs = new ExpressionList(n-m+1); for (int i = m-1; i < n; i++) varargs.Add(arguments[i]); Debug.Assert(m <= n || m == n+1); while (m > n++) arguments.Add(null); arguments[m-1] = new ConstructArray(parameters[m-1].GetParamArrayElementType(), varargs); arguments.Count = m; n = m; } } if (n > m) { // Handle Varargs Debug.Assert(n == m+1); Debug.Assert((callingConvention & CallingConventionFlags.VarArg) != 0); ArglistArgumentExpression ale = arguments[n-1] as ArglistArgumentExpression; if (ale != null) { // rewrite nested arguments to one level. // otherwise, the method does not match and I expect the Checker to issue a nice message. ExpressionList newArgs = new ExpressionList(n - 1 + ale.Operands.Count); for (int i=0; i<n-1; i++) { newArgs.Add(arguments[i]); } for (int i=0; i<ale.Operands.Count; i++) { newArgs.Add(ale.Operands[i]); } arguments = newArgs; // adjust formal parameters to actuals parameters = (ParameterList)parameters.Clone(); for (int i=0; i<ale.Operands.Count; i++) { if (arguments[i+m] != null) { TypeNode pType = arguments[i+m].Type; Reference r = pType as Reference; if (r != null) pType = r.ElementType; parameters.Add(new Parameter(null, pType)); } else { parameters.Add(new Parameter(null, SystemTypes.Object)); } } m = arguments.Count; n = m; } else { // leave arguments and let type coercion fail // adjust formal parameters to actuals parameters = (ParameterList)parameters.Clone(); parameters.Add(Resolver.ArglistDummyParameter); n = parameters.Count; } } if (doNotVisitArguments) { for (int i = 0; i < n; i++) { Parameter p = this.typeSystem.currentParameter = parameters[i]; Literal lit = arguments[i] as Literal; if (lit != null && lit.Value is TypeNode && p.Type == SystemTypes.Type) arguments[i] = lit; else { if (!this.DoNotVisitArguments(p.DeclaringMethod)) { Expression e = arguments[i] = this.typeSystem.ImplicitCoercion(arguments[i], p.Type, this.TypeViewer); if (e is BinaryExpression && e.NodeType == NodeType.Box) e = arguments[i] = ((BinaryExpression)e).Operand1; } } } } else { for (int i = 0; i < n; i++) { Parameter p = this.typeSystem.currentParameter = parameters[i]; bool savedMayReferenceThisAndBase = this.MayReferenceThisAndBase; if (p.IsOut && this.currentMethod is InstanceInitializer) { // allow calls "f(out this.x)" before the explicit base ctor call this.MayReferenceThisAndBase = true; } arguments[i] = this.CoerceArgument(this.VisitExpression(arguments[i]), p); this.MayReferenceThisAndBase = savedMayReferenceThisAndBase; } } this.typeSystem.currentParameter = null; }
private Expression CreateOwnerIsMethodCall(ConstructArray consArr) { if (consArr == null || consArr.Owner == null) return consArr; Method OwnerIsMethod = this.GetTypeView(SystemTypes.AssertHelpers).GetMethod(Identifier.For("OwnerIs"), SystemTypes.Object, SystemTypes.Object); Expression visitedConsArr = base.VisitConstructArray(consArr); MethodCall mc = new MethodCall(new MemberBinding(null, OwnerIsMethod), new ExpressionList(consArr.Owner, visitedConsArr), NodeType.Call, OptionalModifier.For(SystemTypes.NonNullType, SystemTypes.Object), consArr.SourceContext); consArr.Owner = null; // Anything downstream shouldn't even see the owner: it is only for the static analysis return this.typeSystem.ExplicitCoercion(mc, consArr.Type, this.TypeViewer); }
public virtual object[] ConvertToCompileTimeArray(ConstructArray consArr){ if (consArr == null) return null; TypeNode elemType = consArr.ElementType; ExpressionList elems = consArr.Initializers; int n = elems == null ? 0 : elems.Count; object[] result = new object[n]; for (int i = 0; i < n; i++){ Expression e = this.VisitExpression(elems[i]); BinaryExpression binExp = e as BinaryExpression; if (binExp != null && binExp.NodeType == NodeType.Box) e = binExp.Operand1; Literal lit = e as Literal; if (lit == null) lit = this.ConvertToCompileTimeType(e) as Literal; if (lit == null) continue; result[i] = lit.Value; } return result; }
/// <summary> /// Generate a statement that keeps an old value an input expression. If the expression is an array, /// a certain level of deep copy is performed. /// </summary> /// <param name="l">The l-value into which the old value of e is going to stored</param> /// <param name="e">The expression whose old value is going to keep.</param> /// <param name="levelOfDeepCopyForArrayExp">If e is an array (of arrays of arrays ...), the level /// of deep copy we shall make. </param> /// <returns></returns> private Statement initializeOldExp(Expression l, Expression e, int levelOfDeepCopyForArrayExp) //^ requires levelOfDeepCopyForArrayExp >=0; //^ requires (e.Type is ArrayType && !((e.Type as ArrayType).ElementType is ArrayType)) ==> levelOfDeepCopyForArrayExp <=1; { Statement/*?*/ result; bool isNonNull; TypeNode eType = e.Type.StripOptionalModifiers(out isNonNull); ArrayType arrayType = eType as ArrayType; if (arrayType != null && levelOfDeepCopyForArrayExp > 0) { ExpressionList sizes = new ExpressionList(); Member getLength = arrayType.BaseType.GetMethod(Identifier.For("get_Length")); Expression arrayLengthMB = new MemberBinding(e, getLength, e.SourceContext); Expression arrayLength = new MethodCall(arrayLengthMB, new ExpressionList(), NodeType.Callvirt); arrayLength.Type = SystemTypes.Int32; sizes.Add(arrayLength); Expression callCopy = new ConstructArray(arrayType.ElementType, sizes, null); callCopy.Type = arrayType; Block b = new Block(new StatementList()); b.Statements.Add(new AssignmentStatement(l, callCopy, e.SourceContext)); Block loopBody = new Block(new StatementList()); Local foreachLocal = new Local(SystemTypes.Int32); Expression copyElement = new Indexer(l, new ExpressionList(foreachLocal)); copyElement.Type = arrayType.ElementType; Expression originalElement = new Indexer(e, new ExpressionList(foreachLocal)); originalElement.Type = arrayType.ElementType; Statement copyStatement = this.initializeOldExp(copyElement, originalElement, levelOfDeepCopyForArrayExp - 1); // new AssignmentStatement(copyElement, originalElement, oldExpression.SourceContext); loopBody.Statements.Add(copyStatement); StatementList initializer = new StatementList(new AssignmentStatement(foreachLocal, new Literal(0, SystemTypes.Int32, e.SourceContext))); Expression condition = new BinaryExpression(foreachLocal, arrayLength, NodeType.Lt); condition.Type = SystemTypes.Boolean; Expression foreachLocalPlusOne = new BinaryExpression(foreachLocal, new Literal(1, SystemTypes.Int32), NodeType.Add); foreachLocalPlusOne.Type = SystemTypes.Int32; StatementList incrementor = new StatementList(new AssignmentStatement(foreachLocal, foreachLocalPlusOne, e.SourceContext)); b.Statements.Add(new For(initializer, condition, incrementor, loopBody)); result = this.VisitBlock(b); } else result = new AssignmentStatement(l, e, e.SourceContext); //^ assert result != null; return result; }
public override Expression VisitConstructArray(ConstructArray consArr){ if (consArr == null) return null; ArrayType arrayType = this.typeSystem.Unwrap(consArr.Type) as ArrayType; if (arrayType == null){Debug.Assert(consArr.Type == null); return null;} consArr.Operands = this.VisitExpressionList(consArr.Operands); ExpressionList initializers = consArr.Initializers; consArr.Initializers = null; int rank = consArr.Rank; if (initializers == null){ if (consArr.Operands == null) return null; rank = consArr.Operands.Count; if (rank == 1) return CreateOwnerIsMethodCall(consArr); if (consArr.Type == null) return null; TypeNode[] types = new TypeNode[rank]; for (int i = 0; i < rank; i++) types[i] = SystemTypes.Int32; InstanceInitializer ctor = this.GetTypeView(arrayType).GetConstructor(types); if (ctor == null){Debug.Assert(false); return null;} return CreateOwnerIsMethodCall(new Construct(new MemberBinding(null, ctor), consArr.Operands)); } if (consArr.Operands == null || consArr.Operands.Count == 0){ consArr.Operands = new ExpressionList(rank); ExpressionList inits = initializers; for (int i = 0; i < rank; i++){ int m = inits == null ? 0 : inits.Count; consArr.Operands.Add(new Literal(m, SystemTypes.Int32)); if (i == rank-1 || m < 1) break; ConstructArray cArr = inits[0] as ConstructArray; if (cArr == null) return null; inits = cArr.Initializers; } } int n = initializers.Count; bool isNonNullArray = this.typeSystem.IsPossibleNonNullType(consArr.ElementType); if (n == 0) { if (isNonNullArray) { StatementList stmts = new StatementList(2); stmts.Add(new ExpressionStatement(CreateOwnerIsMethodCall(consArr))); stmts.Add(new ExpressionStatement(CreateAssertNonNullArrayCall(arrayType))); return new BlockExpression(new Block(stmts), consArr.Type); /* return CreateOwnerIsMethodCall(consArr); */ } else { return CreateOwnerIsMethodCall(consArr); } } TypeNode elemType = this.typeSystem.GetUnderlyingType(consArr.ElementType); // // If this is a non-null array with initializers, we add a call to // NonNullType.AssertInitialized so that the analysis in definiteassignment // will know the "commit point" of the array. int numStatements = (isNonNullArray) ? n + 2 : n + 1; StatementList statements = new StatementList(numStatements); if (rank > 1){ TypeNode[] types = new TypeNode[rank]; for (int i = 0; i < rank; i++) types[i] = SystemTypes.Int32; InstanceInitializer ctor = this.GetTypeView(arrayType).GetConstructor(types); if (ctor == null){Debug.Assert(false); return null;} statements.Add(new ExpressionStatement(CreateOwnerIsMethodCall(new Construct(new MemberBinding(null, ctor), consArr.Operands)))); Int32List indices = new Int32List(rank); for (int i = 0; i < rank; i++) indices.Add(0); MemberBinding setter = new MemberBinding(new Expression(NodeType.Dup), arrayType.Setter); for (int i = 0; i < n; i++){ indices[0] = i; this.InitializeMultiDimArray(rank-1, 1, indices, ((ConstructArray)initializers[i]).Initializers, setter, statements); } if (isNonNullArray) { // insert a call to AssertNonNullInit statements.Add(new ExpressionStatement(CreateAssertNonNullArrayCall(arrayType))); } return new BlockExpression(new Block(statements), consArr.Type); } statements.Add(new ExpressionStatement(CreateOwnerIsMethodCall(consArr))); for (int i = 0; i < n; i++){ ExpressionList arguments = new ExpressionList(1); arguments.Add(new Literal(i, SystemTypes.Int32)); Expression indexer = new Indexer(new Expression(NodeType.Dup, arrayType), arguments, elemType); if (elemType.IsValueType && !elemType.IsPrimitive) indexer = new AddressDereference(new UnaryExpression(indexer, NodeType.AddressOf, indexer.Type.GetReferenceType()), elemType); statements.Add(new AssignmentStatement(indexer, this.VisitExpression(initializers[i]))); } if (isNonNullArray) { // insert a call to AssertNonNullInit statements.Add(new ExpressionStatement(CreateAssertNonNullArrayCall(arrayType))); } return new BlockExpression(new Block(statements), consArr.Type); }
private ConstructArray/*!*/ ParseNewArray() { TypeNode type = (TypeNode)this.GetMemberFromToken(); ExpressionList sizes = new ExpressionList(); sizes.Add(PopOperand()); ConstructArray result = new ConstructArray(type, sizes, null); result.Type = type.GetArrayType(1); return result; }
public override Expression VisitConstructArray(ConstructArray consArr){ if (consArr == null) return null; this.AbstractSealedUsedAsType = Error.AbstractSealedArrayElementType; consArr.ElementType = this.VisitTypeReference(consArr.ElementType, true); this.AbstractSealedUsedAsType = Error.NotAType; consArr.Operands = this.VisitExpressionList(consArr.Operands); consArr.Initializers = this.VisitExpressionList(consArr.Initializers); consArr.Owner = this.VisitExpression(consArr.Owner); return consArr; }
private Expression Translate(CodeArrayCreateExpression expr){ if (expr == null) return null; ConstructArray cons = new ConstructArray(); cons.ElementType = this.TranslateToTypeNode(expr.CreateType); ExpressionList initializers = cons.Initializers = this.Translate(expr.Initializers); cons.Operands = new ExpressionList(1); if (expr.SizeExpression != null) cons.Operands.Add(this.Translate(expr.SizeExpression)); else{ int size = 0; if (initializers != null) size = initializers.Count; if (expr.Size > size) size = expr.Size; cons.Operands.Add(new Literal(size, SystemTypes.Int32)); } return cons; }
public override Expression VisitConstructArray(ConstructArray consArr){ if (consArr == null) return null; this.VisitResolvedTypeReference(consArr.ElementType, consArr.ElementTypeExpression); return base.VisitConstructArray(consArr); }
public override Expression VisitConstructArray(ConstructArray consArr){ if (consArr == null) return consArr; TypeNode et = consArr.ElementType = this.VisitTypeReference(consArr.ElementType); ExpressionList dims = consArr.Operands = this.VisitExpressionList(consArr.Operands); consArr.Initializers = this.VisitExpressionList(consArr.Initializers); if (et == null && consArr.ElementTypeExpression == null) { TypeNodeList tl = new TypeNodeList(); for (int i = 0, n = consArr.Initializers == null ? 0 : consArr.Initializers.Count; i < n; i++) { Expression e = consArr.Initializers[i]; if (e == null || e.Type == null) continue; Literal lit = e as Literal; if (lit != null && lit.Value == null) continue; //This prevents null from participating in the type unification, which is by design. if (e.Type == null) continue; //e is a bad expression tl.Add(e.Type); } et = this.typeSystem.UnifiedType(tl, this.TypeViewer); if (et == null) et = SystemTypes.Object; consArr.ElementType = et; } if (et is DelegateNode) { for (int i = 0, n = consArr.Initializers == null ? 0 : consArr.Initializers.Count; i < n; i++) { Expression e = consArr.Initializers[i]; if (e is MemberBinding && ((MemberBinding)e).BoundMember is Method) consArr.Initializers[i] = this.VisitExpression(new Construct(new MemberBinding(null, et), new ExpressionList(e))); } } consArr.Owner = this.VisitExpression(consArr.Owner); consArr.Type = SystemTypes.Object; if (et == null) return null; consArr.Type = et.GetArrayType(consArr.Rank); if (this.currentPreprocessorDefinedSymbols != null && this.NonNullChecking) consArr.Type = OptionalModifier.For(SystemTypes.NonNullType, consArr.Type); return consArr; }
protected virtual void VisitConstructArray(ConstructArray consArr){ if (consArr == null || consArr.Operands == null || consArr.Operands.Count == 0) return; this.Visit(consArr.Operands[0]); this.ILGenerator.Emit(OpCodes.Newarr, consArr.ElementType.GetRuntimeType()); }
public override Expression VisitConstructArray(ConstructArray consArr) { if (consArr == null) return null; TypeNode elemType = consArr.ElementType = this.VisitTypeReference(consArr.ElementType); elemType = TypeNode.StripModifiers(elemType); if (elemType == SystemTypes.DynamicallyTypedReference || elemType == SystemTypes.ArgIterator) { this.HandleError(consArr, Error.ArrayElementCannotBeTypedReference, this.GetTypeName(elemType)); return null; } ExpressionList sizes = consArr.Operands; int n = sizes == null ? 0 : sizes.Count; long[] knownSizes = new long[n]; for (int i = 0; i < n; i++) { knownSizes[i] = -1; Expression e = this.VisitExpression(sizes[i]); MemberBinding mb = e as MemberBinding; Field f = mb == null ? null : mb.BoundMember as Field; Literal lit; if (f != null && f.IsLiteral) lit = f.DefaultValue; else lit = e as Literal; if (lit == null) sizes[i] = this.typeSystem.CoerceToIndex(e, this.TypeViewer); else { if (this.typeSystem.ImplicitLiteralCoercionFromTo(lit, lit.Type, SystemTypes.Int32)) { lit = this.typeSystem.ImplicitLiteralCoercion(lit, lit.Type, SystemTypes.Int32, this.TypeViewer); if (n == 1) sizes[i] = this.typeSystem.ExplicitPrimitiveCoercion(lit, SystemTypes.Int32, SystemTypes.IntPtr); else sizes[i] = lit; if (lit == null || !(lit.Value is int)) return null; int siz = (int)lit.Value; if (siz < 0) { this.HandleError(lit, Error.NegativeArraySize); return null; } knownSizes[i] = siz; } else if (this.typeSystem.ImplicitLiteralCoercionFromTo(lit, lit.Type, SystemTypes.Int64)) { lit = this.typeSystem.ImplicitLiteralCoercion(lit, lit.Type, SystemTypes.Int64, this.TypeViewer); sizes[i] = this.typeSystem.ExplicitPrimitiveCoercion(lit, SystemTypes.Int64, SystemTypes.IntPtr); //REVIEW: what if array has rank > 1? if (lit == null || !(lit.Value is long)) return null; long siz = (long)lit.Value; if (siz < 0) { this.HandleError(lit, Error.NegativeArraySize); return null; } knownSizes[i] = siz; } else sizes[i] = this.typeSystem.CoerceToIndex(e, this.TypeViewer); } } consArr.Operands = sizes; ExpressionList initializers = consArr.Initializers = this.VisitExpressionList(consArr.Initializers); int m = initializers == null ? 0 : initializers.Count; if (n > 0 && initializers != null) { if (knownSizes[0] < 0) this.HandleError(sizes[0], Error.ConstantExpected); else if (knownSizes[0] != m) this.HandleError(consArr, Error.ArrayInitializerLengthMismatch, m.ToString(), knownSizes[0].ToString()); //TODO: check that nested array initializers match known sizes of other dimensions } int rank = consArr.Type is OptionalModifier ? ((ArrayType)((OptionalModifier)consArr.Type).ModifiedType).Rank : ((ArrayType)consArr.Type).Rank; if (rank > 1) elemType = elemType.GetArrayType(rank-1); for (int i = 0; i < m; i++) initializers[i] = this.typeSystem.ImplicitCoercion(initializers[i], elemType, this.TypeViewer); //TODO: check that all nested array initializers are of the same size if (consArr.Owner != null) { this.VisitExpression(consArr.Owner); TypeNode ownerType = consArr.Owner.Type; if (ownerType == null) { // must have been an error somewhere else consArr.Owner = null; } else if (ownerType.IsValueType) { consArr.Owner = this.typeSystem.ImplicitCoercion(consArr.Owner, SystemTypes.Object, this.TypeViewer); } } return consArr; }
public static void report(Node node, int shift) { if (node == null) { indent(shift); Console.WriteLine("NULL ENTITY"); return; } switch (node.NodeType) { case NodeType.AliasDefinition: { AliasDefinition alias = node as AliasDefinition; indent(shift); Console.WriteLine("using {0} = {1};", alias.Alias.Name, alias.AliasedUri.Name); break; } case NodeType.CompilationUnit: case NodeType.CompilationUnitSnippet: { CompilationUnit cu = node as CompilationUnit; for (int i = 0, n = cu.Nodes.Length; i < n; i++) { report(cu.Nodes[i], 0); } break; } case NodeType.Namespace: { Namespace ns = node as Namespace; if (ns.UsedNamespaces != null && ns.UsedNamespaces.Length != 0) { indent(shift); Console.WriteLine("using "); for (int i = 0, n = ns.UsedNamespaces.Length; i < n; i++) { Console.Write("{0}", ns.UsedNamespaces[i].Namespace.Name); if (i < n - 1) { Console.Write(", "); } } Console.WriteLine(); } indent(shift); Console.WriteLine("namespace {0}", ns.FullNameId.Name); indent(shift); Console.WriteLine("{"); if (ns.AliasDefinitions != null && ns.AliasDefinitions.Length != 0) { for (int i = 0, n = ns.AliasDefinitions.Length; i < n; i++) { report(ns.AliasDefinitions[i], shift + ind); } } if (ns.NestedNamespaces != null && ns.NestedNamespaces.Length != 0) { for (int i = 0, n = ns.NestedNamespaces.Length; i < n; i++) { report(ns.NestedNamespaces[i], shift + ind); } } if (ns.Types != null && ns.Types.Length != 0) { for (int i = 0, n = ns.Types.Length; i < n; i++) { report(ns.Types[i], shift + ind); } } indent(shift); Console.WriteLine("}"); break; } case NodeType.Class: { Class cls = node as Class; if (cls == SystemTypes.Object) { Console.Write(cls.Name); break; } indent(shift); if (cls.IsAbstract) { Console.Write("abstract "); } if (cls.IsPrivate) { Console.Write("private "); } else if (cls.IsPublic) { Console.Write("public "); } else { Console.Write("internal "); // ?????????????? } if (cls.IsSealed) { Console.Write("sealed "); } Console.Write("class "); if (cls.DeclaringType != null) { Console.Write("{0}::", cls.DeclaringType.Name.Name); } Console.Write("{0}", cls.Name != null?cls.Name.Name:"<NONAME>"); if (cls.BaseClass != null) { Console.Write(" : {0}", cls.BaseClass.Name.Name); } if (cls.Interfaces != null && cls.Interfaces.Length != 0) { if (cls.BaseClass != null) { Console.Write(","); } else { Console.Write(" :"); } for (int i = 0, n = cls.Interfaces.Length; i < n; i++) { Interface interfac = cls.Interfaces[i]; if (interfac != null) { Console.Write(" {0}", interfac.Name.Name); } if (i < n - 1) { Console.Write(","); } } } Console.WriteLine(); indent(shift); Console.WriteLine("{"); if (cls.Members != null && cls.Members.Length != 0) { for (int i = 0, n = cls.Members.Length; i < n; i++) { Member member = cls.Members[i]; if (member == null) { indent(shift + ind); Console.WriteLine("<UNRESOLVED MEMBER>"); continue; } report(member, shift + ind); } } indent(shift); Console.WriteLine("}"); break; } case NodeType.Struct: { Struct struc = node as Struct; indent(shift); if (struc.IsAbstract) { Console.Write("abstract "); } if (struc.IsPrivate) { Console.Write("private "); } else if (struc.IsPublic) { Console.Write("public "); } else { Console.Write("internal "); // ?????????????? } if (struc.IsSealed) { Console.Write("sealed "); } Console.Write("struct "); if (struc.DeclaringType != null) { Console.Write("{0}::", struc.DeclaringType.Name.Name); } Console.Write("{0}", struc.Name != null?struc.Name.Name:"<NONAME>"); if (struc.Interfaces != null && struc.Interfaces.Length != 0) { Console.Write(" :"); for (int i = 0, n = struc.Interfaces.Length; i < n; i++) { Interface interfac = struc.Interfaces[i]; if (interfac != null) { Console.Write(" {0}", interfac.Name.Name); } if (i < n - 1) { Console.Write(","); } } } Console.WriteLine(); indent(shift); Console.WriteLine("{"); if (struc.Members != null && struc.Members.Length != 0) { for (int i = 0, n = struc.Members.Length; i < n; i++) { Member member = struc.Members[i]; if (member == null) { indent(shift + ind); Console.WriteLine("<UNRESOLVED MEMBER>"); continue; } report(member, shift + ind); } } indent(shift); Console.WriteLine("}"); break; } case NodeType.EnumNode: { EnumNode enume = node as EnumNode; indent(shift); if (enume.Name != null && enume.Name.Name != null) { Console.Write("enum {0} = ", enume.Name.Name); } else { Console.Write("enum <NONAME> = "); } Console.Write("{"); for (int i = 0, n = enume.Members.Length; i < n; i++) { Field enumerator = (Field)enume.Members[i]; Console.Write("{0}", enumerator.Name.Name); if (enumerator.DefaultValue != null) { Console.Write(" = {0}", enumerator.DefaultValue.ToString()); } if (i < n - 1) { Console.Write(", "); } } Console.WriteLine("};"); break; } case NodeType.Interface: { Interface interfac = node as Interface; indent(shift); if (interfac.IsAbstract) { Console.Write("abstract "); } if (interfac.IsPrivate) { Console.Write("private "); } else if (interfac.IsPublic) { Console.Write("public "); } else { Console.Write("internal "); // ??????????? } Console.WriteLine("interface {0}", interfac.Name.Name); indent(shift); Console.WriteLine("{"); if (interfac.Members != null && interfac.Members.Length != 0) { for (int i = 0, n = interfac.Members.Length; i < n; i++) { Member member = interfac.Members[i]; if (member == null) { indent(shift + ind); Console.WriteLine("<UNRESOLVED MEMBER>"); continue; } report(member, shift + ind); } } indent(shift); Console.WriteLine("}"); break; } case NodeType.Method: case NodeType.InstanceInitializer: { Method method = node as Method; indent(shift); if (method.IsAbstract) { Console.Write("abstract "); } if (method.IsPublic) { Console.Write("public "); } if (method.IsStatic) { Console.Write("static "); } if (method.IsVirtual) { Console.Write("virtual "); } if (method.IsPrivate) { Console.Write("private "); } if (method.OverriddenMethod != null) { Console.Write("override "); } if (method.ReturnType != null && method.ReturnType.Name != null) { Console.Write("{0} ", method.ReturnType.Name.Name); } if (method.Name != null) { if (method.ImplementedInterfaceMethods != null && method.ImplementedInterfaceMethods.Length != 0) { Method interf = method.ImplementedInterfaceMethods[0]; if (interf != null) { string name = interf.DeclaringType.Name.Name; Console.Write("{0}.", name); } } Console.Write("{0}", method.Name.Name); } Console.Write(" ("); if (method.Parameters != null && method.Parameters.Length != 0) { for (int i = 0, n = method.Parameters.Length; i < n; i++) { Parameter par = method.Parameters[i]; if (par == null) { continue; } if ((par.Flags & ParameterFlags.In) != 0) { Console.Write("in "); } if ((par.Flags & ParameterFlags.Out) != 0) { Console.Write("out "); } if (par.Type != null && par.Type.Name != null) { Console.Write("{0}", par.Type.Name.Name); } else { report(par.Type, 0); } Console.Write(" {0}", par.Name.Name); if (i < n - 1) { Console.Write(", "); } } } Console.Write(" )"); // method body if (method.Body != null) { Console.WriteLine(); report(method.Body, shift); } else { Console.WriteLine(";"); } break; } case NodeType.DelegateNode: { DelegateNode dn = node as DelegateNode; indent(shift); Console.Write("delegate "); if (dn.ReturnType != null && dn.ReturnType.Name != null) { Console.Write("{0} ", dn.ReturnType.Name.Name); } if (dn.Name != null) { Console.Write("{0}", dn.Name.Name); } Console.Write(" ("); if (dn.Parameters != null && dn.Parameters.Length != 0) { for (int i = 0, n = dn.Parameters.Length; i < n; i++) { Parameter par = dn.Parameters[i]; if (par == null) { continue; } if ((par.Flags & ParameterFlags.In) != 0) { Console.Write("in "); } if ((par.Flags & ParameterFlags.Out) != 0) { Console.Write("out "); } if (par.Type != null && par.Type.Name != null) { Console.Write("{0}", par.Type.Name.Name); } else { report(par.Type, 0); } Console.Write(" {0}", par.Name.Name); if (i < n - 1) { Console.Write(", "); } } } Console.WriteLine(" );"); break; } case NodeType.StaticInitializer: { StaticInitializer si = node as StaticInitializer; indent(shift); Console.WriteLine("static {0} ( )", si.Name.Name); // body if (si.Body != null) { report(si.Body, shift); } else { Console.WriteLine("NO BODY"); } break; } case NodeType.FieldInitializerBlock: { FieldInitializerBlock initializers = node as FieldInitializerBlock; indent(shift); if (initializers.IsStatic) { Console.Write("static "); } Console.WriteLine("init {"); for (int i = 0, n = initializers.Statements.Length; i < n; i++) { report(initializers.Statements[i], shift + ind); } indent(shift); Console.WriteLine("}"); break; } case NodeType.Base: { Console.Write("base"); break; } case NodeType.Field: { Field field = node as Field; indent(shift); if (field.IsPrivate) { Console.Write("private "); } else if (field.IsPublic) { Console.Write("public "); } if (field.IsStatic) { Console.Write("static "); } if (field.IsInitOnly) { Console.Write("readonly "); } if (field.Type != null) { if (field.Type.Name != null) { Console.Write("{0}", field.Type.Name.Name); } else { report(field.Type, 0); } } Console.Write(" {0}", field.Name.Name); if (field.Initializer != null) { Console.Write(" = "); report(field.Initializer, 0); } Console.WriteLine(";"); break; } case NodeType.VariableDeclaration: { VariableDeclaration variable = node as VariableDeclaration; indent(shift); if (variable.Type != null && variable.Type.Name != null) { Console.Write("{0}", variable.Type.Name.Name); } else { report(variable.Type, 0); } Console.Write(" {0}", variable.Name.Name); if (variable.Initializer != null) { Console.Write(" = "); report(variable.Initializer, 0); } Console.WriteLine(";"); break; } case NodeType.LocalDeclarationsStatement: { LocalDeclarationsStatement stmt = node as LocalDeclarationsStatement; indent(shift); TypeNode type = stmt.Type; if (type != null && type.Name != null) { Console.Write("{0}", type.Name.Name); } else { report(type, 0); } Console.Write(" "); LocalDeclarationList list = stmt.Declarations; for (int i = 0, n = list.Length; i < n; i++) { LocalDeclaration local = list[i]; Console.Write("{0}", local.Name.Name); if (local.InitialValue != null) { Console.Write(" = "); report(local.InitialValue, 0); } if (i < n - 1) { Console.Write(", "); } } Console.WriteLine(";"); break; } case NodeType.Property: { Property property = node as Property; indent(shift); if (property.IsPrivate) { Console.Write("private "); } else if (property.IsPublic) { Console.Write("public "); } if (property.IsStatic) { Console.Write("static "); } if (property != null) { if (property.Type != null && property.Type.Name != null) { Console.Write("{0} ", property.Type.Name.Name); } if (property.ImplementedTypes != null) { TypeNode typ = property.ImplementedTypes[0]; Console.Write("{0}.", typ.Name.Name); } if (property.Name != null) { Console.WriteLine("{0}", property.Name.Name); } } indent(shift); Console.WriteLine("{"); if (property.Getter != null) { report(property.Getter, shift + ind); } if (property.Setter != null) { report(property.Setter, shift + ind); } indent(shift); Console.WriteLine("}"); break; } case NodeType.Lock: { Lock _lock = node as Lock; indent(shift); Console.Write("lock("); report(_lock.Guard, shift); Console.WriteLine(")"); report(_lock.Body, shift + ind); indent(shift); Console.WriteLine("}"); break; } case NodeType.Block: { Block block = node as Block; if (block == null || block.Statements == null) { break; } indent(shift); Console.WriteLine("{"); for (int i = 0, n = block.Statements.Length; i < n; i++) { report(block.Statements[i], shift + ind); Console.WriteLine(); } indent(shift); Console.WriteLine("}"); break; } case NodeType.MemberBinding: { MemberBinding mb = node as MemberBinding; if (mb.TargetObject != null) { report(mb.TargetObject, 0); } else if (mb.BoundMember != null && mb.BoundMember.DeclaringType != null) { Console.Write(mb.BoundMember.DeclaringType.Name); } Console.Write("."); if (mb.BoundMember.Name != null) { Console.Write(mb.BoundMember.Name.Name); } else { report(mb.BoundMember, 0); } break; } case NodeType.AssignmentStatement: { AssignmentStatement assignment = node as AssignmentStatement; indent(shift); report(assignment.Target, 0); switch (assignment.Operator) { case NodeType.Nop: Console.Write(" = "); break; case NodeType.Add: Console.Write(" += "); break; case NodeType.Add_Ovf: Console.Write(" += "); break; case NodeType.Add_Ovf_Un: Console.Write(" += "); break; case NodeType.Sub: Console.Write(" -= "); break; case NodeType.Sub_Ovf: Console.Write(" -= "); break; case NodeType.Sub_Ovf_Un: Console.Write(" -= "); break; case NodeType.Mul: Console.Write(" *= "); break; case NodeType.Mul_Ovf: Console.Write(" *= "); break; case NodeType.Mul_Ovf_Un: Console.Write(" *= "); break; } report(assignment.Source, 0); Console.Write(";"); break; } case NodeType.ExpressionStatement: { ExpressionStatement exprStatement = node as ExpressionStatement; indent(shift); report(exprStatement.Expression, 0); Console.Write(";"); break; } case NodeType.Return: { Return return_stmt = node as Return; indent(shift); Console.Write("return"); if (return_stmt.Expression != null) { Console.Write(" "); report(return_stmt.Expression, 0); } Console.Write(";"); break; } case NodeType.Branch: { Branch branch = node as Branch; indent(shift); Console.WriteLine("break; (???)"); break; } case NodeType.For: { For for_stmt = node as For; indent(shift); Console.Write("for ( "); for (int i = 0, n = for_stmt.Initializer.Length; i < n; i++) { report(for_stmt.Initializer[i], 0); } report(for_stmt.Condition, 0); Console.Write("; "); for (int i = 0, n = for_stmt.Incrementer.Length; i < n; i++) { report(for_stmt.Incrementer[i], 0); } Console.WriteLine(")"); indent(shift); Console.WriteLine("{"); report(for_stmt.Body, shift + ind); indent(shift); Console.WriteLine("}"); break; } case NodeType.While: { While while_loop = node as While; indent(shift); Console.Write("while ( "); report(while_loop.Condition, 0); Console.WriteLine(" )"); report(while_loop.Body, shift); break; } case NodeType.DoWhile: { DoWhile repeat = node as DoWhile; indent(shift); Console.WriteLine("do"); report(repeat.Body, shift); indent(shift); Console.Write("while ("); report(repeat.Condition, 0); Console.WriteLine(" );"); break; } case NodeType.If: { If if_stmt = node as If; indent(shift); Console.Write("if ( "); report(if_stmt.Condition, 0); Console.WriteLine(" )"); report(if_stmt.TrueBlock, shift); if (if_stmt.FalseBlock == null || if_stmt.FalseBlock.Statements == null || if_stmt.FalseBlock.Statements.Length == 0) { break; } indent(shift); Console.WriteLine("else"); report(if_stmt.FalseBlock, shift); break; } case NodeType.Switch: { Switch swtch = node as Switch; indent(shift); Console.Write("switch ( "); report(swtch.Expression, 0); Console.WriteLine(" )"); indent(shift); Console.WriteLine("{"); for (int i = 0, n = swtch.Cases.Length; i < n; i++) { indent(shift + ind); if (swtch.Cases[i].Label != null) { Console.Write("case "); report(swtch.Cases[i].Label, 0); Console.WriteLine(":"); } else { Console.WriteLine("default:"); } report(swtch.Cases[i].Body, shift + ind); } indent(shift); Console.WriteLine("}"); break; } case NodeType.Throw: { Throw thro = node as Throw; indent(shift); Console.Write("throw ("); report(thro.Expression, 0); Console.Write(");"); break; } case NodeType.Exit: { indent(shift); Console.WriteLine("exit;"); break; } case NodeType.Continue: { indent(shift); Console.WriteLine("continue;"); break; } case NodeType.Try: { Try trys = node as Try; indent(shift); Console.WriteLine("try {"); report(trys.TryBlock, shift + ind); indent(shift); Console.WriteLine("}"); if (trys.Catchers != null) { for (int i = 0, n = trys.Catchers.Length; i < n; i++) { indent(shift); if (trys.Catchers[i].Type != null) { Console.Write("catch ( {0} ", trys.Catchers[i].Type.FullName); } else { Console.Write("catch ( "); } if (trys.Catchers[i].Variable != null) { report(trys.Catchers[i].Variable, 0); } Console.WriteLine(" ) {"); report(trys.Catchers[i].Block, shift + ind); indent(shift); Console.WriteLine("}"); } } if (trys.Finally != null && trys.Finally.Block != null) { indent(shift); Console.WriteLine("finally"); report(trys.Finally.Block, shift); } break; } case NodeType.BlockExpression: { BlockExpression be = node as BlockExpression; Console.WriteLine("("); StatementList sl = be.Block.Statements; for (int i = 0, n = sl.Length; i < n; i++) { report(sl[i], shift + ind); } indent(shift); Console.Write(")"); break; } case NodeType.ArrayTypeExpression: { ArrayTypeExpression array = node as ArrayTypeExpression; indent(shift); if (array.ElementType != null && array.ElementType.Name != null && array.ElementType.Name.Name != null) { Console.Write(array.ElementType.Name.Name); } else { report(array.ElementType, 0); } Console.Write("["); for (int i = 0, n = array.Rank; i < n; i++) { if (array.Sizes != null) { Console.Write(array.Sizes[i]); } if (i < n - 1) { Console.Write(","); } } Console.Write("]"); break; } case NodeType.Construct: { Construct construct = node as Construct; indent(shift); Console.Write("new "); report(construct.Constructor, 0); Console.Write("("); if (construct.Operands != null) { for (int i = 0, n = construct.Operands.Length; i < n; i++) { report(construct.Operands[i], 0); if (i < n - 1) { Console.Write(","); } } } Console.Write(")"); break; } case NodeType.ConstructArray: { ConstructArray initializer = node as ConstructArray; Console.Write("new "); if (initializer.ElementType != null && initializer.ElementType.Name != null && initializer.ElementType.Name.Name != null) { Console.Write(initializer.ElementType.Name.Name); } else { report(initializer.ElementType, 0); } Console.Write("["); for (int i = 0, n = initializer.Operands.Length; i < n; i++) { report(initializer.Operands[i], 0); if (i < n - 1) { Console.Write(","); } } Console.Write("]"); break; } case NodeType.ConstructDelegate: { ConstructDelegate cd = node as ConstructDelegate; // Console.Write("new {0}({1})",cd.DelegateType.Name.Name,cd.MethodName.Name); Console.Write("new {0}(", cd.DelegateType.Name.Name); report(cd.TargetObject, 0); Console.Write(".{0})", cd.MethodName.Name); // cd.Type; break; } default: { if (node is ZonnonCompilation) { ZonnonCompilation zc = node as ZonnonCompilation; report(zc.CompilationUnits[0], shift); } // Expression? else if (node is MethodCall) { MethodCall call = node as MethodCall; report(call.Callee, 0); Console.Write("("); if (call.Operands != null && call.Operands.Length != 0) { for (int i = 0, n = call.Operands.Length; i < n; i++) { report(call.Operands[i], 0); if (i < n - 1) { Console.Write(","); } } } Console.Write(")"); } else if (node is Variable) { Variable variable = node as Variable; Console.Write("{0}", variable.Name.Name); } else if (node is Identifier) { Identifier identifier = node as Identifier; Console.Write("{0}", identifier.Name); } else if (node is QualifiedIdentifier) { QualifiedIdentifier qualid = node as QualifiedIdentifier; report(qualid.Qualifier, 0); Console.Write(".{0}", qualid.Identifier == null?"<UNRESOLVED>":qualid.Identifier.Name); } else if (node is Literal) { Literal literal = node as Literal; if (literal.Value == null) { Console.Write("null"); } else { if (literal.Value is string) { Console.Write("\""); } else if (literal.Value is char) { Console.Write("'"); } Console.Write("{0}", literal.Value.ToString()); if (literal.Value is string) { Console.Write("\""); } else if (literal.Value is char) { Console.Write("'"); } } } else if (node is Indexer) { Indexer indexer = node as Indexer; report(indexer.Object, 0); Console.Write("["); for (int i = 0, n = indexer.Operands.Length; i < n; i++) { report(indexer.Operands[i], 0); if (i < n - 1) { Console.Write(","); } } Console.Write("]"); } else if (node is UnaryExpression) { UnaryExpression unexpr = node as UnaryExpression; bool add_pars = unexpr.Operand is BinaryExpression || unexpr.Operand is UnaryExpression; switch (unexpr.NodeType) { case NodeType.Add: Console.Write("+"); break; case NodeType.Sub: Console.Write("-"); break; case NodeType.Neg: Console.Write("-"); break; case NodeType.Not: Console.Write("~"); break; case NodeType.UnaryPlus: Console.Write("+"); break; case NodeType.LogicalNot: Console.Write("!"); break; case NodeType.Conv_U2: Console.Write("(UInt16)"); break; case NodeType.RefAddress: Console.Write("ref "); break; case NodeType.Ckfinite: Console.Write("(Ckfinite)"); break; default: Console.Write("???"); break; } if (add_pars) { Console.Write("("); } report(unexpr.Operand, 0); if (add_pars) { Console.Write(")"); } } else if (node is BinaryExpression) { BinaryExpression binexpr = node as BinaryExpression; bool add_pars = binexpr.Operand1 is BinaryExpression || binexpr.Operand1 is UnaryExpression; if (binexpr.NodeType == NodeType.Castclass) { Console.Write("("); report(binexpr.Operand2, 0); Console.Write(")"); if (add_pars) { Console.Write("("); } report(binexpr.Operand1, 0); if (add_pars) { Console.Write(")"); } break; } if (add_pars) { Console.Write("("); } report(binexpr.Operand1, 0); if (add_pars) { Console.Write(")"); } switch (binexpr.NodeType) { case NodeType.Add: Console.Write(" + "); break; case NodeType.Add_Ovf: Console.Write(" + "); break; case NodeType.Add_Ovf_Un: Console.Write(" + "); break; case NodeType.Sub: Console.Write(" - "); break; case NodeType.Sub_Ovf: Console.Write(" - "); break; case NodeType.Sub_Ovf_Un: Console.Write(" - "); break; case NodeType.Mul: Console.Write(" * "); break; case NodeType.Mul_Ovf: Console.Write(" * "); break; case NodeType.Mul_Ovf_Un: Console.Write(" * "); break; case NodeType.Div: Console.Write(" / "); break; // case NodeType.Div : Console.Write(" DIV "); break; // "DIV" ????? case NodeType.Rem: Console.Write(" % "); break; // "MOD" ????? case NodeType.Or: Console.Write(" | "); break; case NodeType.And: Console.Write(" & "); break; case NodeType.Eq: Console.Write(" == "); break; case NodeType.Ne: Console.Write(" != "); break; case NodeType.Lt: Console.Write(" < "); break; case NodeType.Le: Console.Write(" <= "); break; case NodeType.Gt: Console.Write(" > "); break; case NodeType.Ge: Console.Write(" >= "); break; case NodeType.LogicalOr: Console.Write(" || "); break; case NodeType.LogicalAnd: Console.Write(" && "); break; case NodeType.Is: Console.Write(" is "); break; case NodeType.Comma: Console.Write(","); break; // case OPERATORS.In : expression.NodeType = NodeType // "IN" break; // case OPERATORS.Implements : expression.NodeType = NodeType // "IMPLEMENTS" break; default: Console.Write(" !! "); break; } add_pars = binexpr.Operand2 is BinaryExpression || binexpr.Operand2 is UnaryExpression; if (add_pars) { Console.Write("("); } report(binexpr.Operand2, 0); if (add_pars) { Console.Write(")"); } } else if (node is TernaryExpression) { TernaryExpression ter = node as TernaryExpression; if (ter.NodeType == NodeType.Conditional) { report(ter.Operand1, 0); Console.Write(" ? "); report(ter.Operand2, 0); Console.Write(" : "); report(ter.Operand3, 0); } } else if (node is PostfixExpression) { PostfixExpression postfixExpr = node as PostfixExpression; report(postfixExpr.Expression, 0); switch (postfixExpr.Operator) { case NodeType.Increment: Console.Write("++"); break; case NodeType.Decrement: Console.Write("--"); break; default: Console.Write("???"); break; } } else if (node is LabeledStatement) { LabeledStatement lbst = node as LabeledStatement; indent(shift); report(lbst.Label, 0); Console.Write(" : "); report(lbst.Statement, 0); } else if (node is Goto) { Goto gt = node as Goto; indent(shift); Console.Write("goto "); report(gt.TargetLabel, 0); } else { indent(shift); Console.WriteLine("No code for reporting {0}:{1}", node.UniqueKey, node.ToString()); } break; } } }
public virtual Differences VisitConstructArray(ConstructArray consArr1, ConstructArray consArr2){ Differences differences = new Differences(consArr1, consArr2); if (consArr1 == null || consArr2 == null){ if (consArr1 != consArr2) differences.NumberOfDifferences++; else differences.NumberOfSimilarities++; return differences; } ConstructArray changes = (ConstructArray)consArr2.Clone(); ConstructArray deletions = (ConstructArray)consArr2.Clone(); ConstructArray insertions = (ConstructArray)consArr2.Clone(); Differences diff = this.VisitTypeNode(consArr1.ElementType, consArr2.ElementType); if (diff == null){Debug.Assert(false); return differences;} changes.ElementType = diff.Changes as TypeNode; deletions.ElementType = diff.Deletions as TypeNode; insertions.ElementType = diff.Insertions as TypeNode; //Debug.Assert(diff.Changes == changes.ElementType && diff.Deletions == deletions.ElementType && diff.Insertions == insertions.ElementType); differences.NumberOfDifferences += diff.NumberOfDifferences; differences.NumberOfSimilarities += diff.NumberOfSimilarities; ExpressionList exprChanges, exprDeletions, exprInsertions; diff = this.VisitExpressionList(consArr1.Initializers, consArr2.Initializers, out exprChanges, out exprDeletions, out exprInsertions); if (diff == null){Debug.Assert(false); return differences;} changes.Operands = exprChanges; deletions.Operands = exprDeletions; insertions.Operands = exprInsertions; differences.NumberOfDifferences += diff.NumberOfDifferences; differences.NumberOfSimilarities += diff.NumberOfSimilarities; diff = this.VisitExpressionList(consArr1.Operands, consArr2.Operands, out exprChanges, out exprDeletions, out exprInsertions); if (diff == null){Debug.Assert(false); return differences;} changes.Operands = exprChanges; deletions.Operands = exprDeletions; insertions.Operands = exprInsertions; differences.NumberOfDifferences += diff.NumberOfDifferences; differences.NumberOfSimilarities += diff.NumberOfSimilarities; if (consArr1.Rank == consArr2.Rank) differences.NumberOfSimilarities++; else differences.NumberOfDifferences++; diff = this.VisitExpression(consArr1.Owner, consArr2.Owner); if (diff == null) { Debug.Assert(false); return differences; } changes.Owner = diff.Changes as Expression; deletions.Owner = diff.Deletions as Expression; insertions.Owner = diff.Insertions as Expression; Debug.Assert(diff.Changes == changes.Owner && diff.Deletions == deletions.Owner && diff.Insertions == insertions.Owner); differences.NumberOfDifferences += diff.NumberOfDifferences; differences.NumberOfSimilarities += diff.NumberOfSimilarities; if (differences.NumberOfDifferences == 0){ differences.Changes = null; differences.Deletions = null; differences.Insertions = null; }else{ differences.Changes = changes; differences.Deletions = deletions; differences.Insertions = insertions; } return differences; }
public static ConversionResult ConvertPPS(ConversionState state, ConversionResult arg, MethodStruct methodStruct, Identifier receiveBufferIdentifier) { #region // 1st stage // store new size in variable Int32 kernelIndex = state.GetNextKernelIndex(); // get problem global size Identifier kernelSizeIdentifier = Identifier.For(String.Format("_kernel{0}Size", kernelIndex)); ConversionHelper.GenerateKernelSizeArrayField(state, kernelSizeIdentifier); state.Constructor.Body.Statements.Add( NodeHelper.GetAssignmentStatementForNewSizeArray(kernelSizeIdentifier, arg.Type.Rank) ); for (Int32 index = 0; index < arg.Type.Rank; index++) { state.Constructor.Body.Statements.Add( NodeHelper.GetAssignmentStatementForIndices(kernelSizeIdentifier, index, arg.SizeIdentifier, index) ); } Dictionary <String, KernelArgumentDetails> arguments = arg.KernelArguments; String kernelSource = ComputeKernelTemplates.pps1; kernelSource = kernelSource.Replace("{type}", arg.Type.ScalarType.OpenCLTypeName); kernelSource = kernelSource.Replace("{expression}", arg.AccessExpression); kernelSource = kernelSource.Replace("{operation}", methodStruct.Operation); kernelSource = kernelSource.Replace("{identity}", methodStruct.Identity); List <Identifier> waitHandles = arg.WaitHandles; Func <List <Identifier>, Expression, Identifier> generate = (buffers, kernelExpression) => { Identifier kernelIdentifier = Identifier.For("_kernel" + kernelIndex.ToString()); // get kernel ConversionHelper.GenerateGetKernelForProgram(state, kernelIdentifier, kernelExpression); Identifier globalSizeIdent = Identifier.For("globalSize"); state.CodeletMethod.Body.Statements.Add(new VariableDeclaration { Name = globalSizeIdent, Type = SystemTypes.UInt64.GetArrayType(1), Initializer = new ConstructArray { ElementType = SystemTypes.UInt64, Rank = 1, Operands = new ExpressionList(Literal.Int32One), Initializers = new ExpressionList(new Literal(2048 /* FIXME */, SystemTypes.UInt64)) } }); Expression localSize = new ConstructArray { ElementType = SystemTypes.UInt64, Rank = 1, Operands = new ExpressionList(Literal.Int32One), Initializers = new ExpressionList(new Literal(64 /* FIXME */, SystemTypes.UInt64)) }; // localSize is 64 elements Expression localSizeMem = new BinaryExpression { NodeType = NodeType.Mul, Operand1 = new Literal(64 /* FIXME */, SystemTypes.UInt64), Operand2 = new Literal(arg.Type.ScalarType.ByteSize, SystemTypes.UInt64) }; // set kernel arguments Int32 index = 0; ConversionHelper.GenerateKernelSetValueArgument(state, kernelIdentifier, index++, NodeHelper.GetSizeMultiplicationClosure(kernelSizeIdentifier, arg.Type.Rank)); ConversionHelper.GenerateKernelSetLocalArgument(state, kernelIdentifier, index++, localSizeMem); foreach (var buffer in buffers) { ConversionHelper.GenerateKernelSetGlobalArgument(state, kernelIdentifier, index, buffer); index += 1; } Identifier kernelPredecessorsIdentifier = Identifier.For(String.Format("kernel{0}predecessors", kernelIndex)); ConversionHelper.GenerateKernelPredecessors(state, kernelPredecessorsIdentifier, waitHandles); Identifier waitHandleIdentifier = Identifier.For("_eventObject" + kernelIndex.ToString()); ConversionHelper.GenerateEventObjectAndStartKernel(state, waitHandleIdentifier, kernelIdentifier, globalSizeIdent, localSize, kernelPredecessorsIdentifier); ConversionHelper.GenerateFlushCommandQueue(state); return(waitHandleIdentifier); }; String completeExpression = string.Format("{0}({1})", methodStruct.Name, arg.CompleteExpression); ConversionResult firstStage = new ConversionResult( new KernelDetails(kernelSource, generate), "value", arg.Type, kernelSizeIdentifier, arguments, new List <Identifier>(), completeExpression ); arg = ConversionHelper.GenerateKernelExecution(state, firstStage, null); #endregion #region // 2nd stage // store new size in variable kernelIndex = state.GetNextKernelIndex(); kernelSizeIdentifier = Identifier.For(String.Format("_kernel{0}Size", kernelIndex)); // get problem global size ConversionHelper.GenerateKernelSizeArrayField(state, kernelSizeIdentifier); state.Constructor.Body.Statements.Add( NodeHelper.GetAssignmentStatementForNewSizeArray(kernelSizeIdentifier, 1) ); state.Constructor.Body.Statements.Add(new AssignmentStatement { Target = NodeHelper.GetConstantIndexerForExpression(kernelSizeIdentifier, 0), Source = new BinaryExpression { NodeType = NodeType.Div, Operand1 = new Literal(2048 /* FIXME */, SystemTypes.UInt64), Operand2 = new Literal(64 /* FIXME */, SystemTypes.UInt64) } }); arguments = arg.KernelArguments; kernelSource = ComputeKernelTemplates.pps2; kernelSource = kernelSource.Replace("{type}", arg.Type.ScalarType.OpenCLTypeName); kernelSource = kernelSource.Replace("{expression}", arg.AccessExpression); kernelSource = kernelSource.Replace("{operation}", methodStruct.Operation); kernelSource = kernelSource.Replace("{identity}", methodStruct.Identity); waitHandles = arg.WaitHandles; generate = (buffers, kernelExpression) => { Identifier kernelIdentifier = Identifier.For("_kernel" + kernelIndex.ToString()); // get kernel ConversionHelper.GenerateGetKernelForProgram(state, kernelIdentifier, kernelExpression); // set kernel arguments Int32 index = 0; ConversionHelper.GenerateKernelSetValueArgument(state, kernelIdentifier, index++, NodeHelper.GetConstantIndexerForExpression(kernelSizeIdentifier, 0)); //ConversionHelper.GenerateKernelSetLocalArgument(state, kernelIdentifier, index++, localSize); foreach (var buffer in buffers) { ConversionHelper.GenerateKernelSetGlobalArgument(state, kernelIdentifier, index, buffer); index += 1; } Identifier kernelPredecessorsIdentifier = Identifier.For(String.Format("kernel{0}predecessors", kernelIndex)); ConversionHelper.GenerateKernelPredecessors(state, kernelPredecessorsIdentifier, waitHandles); Identifier waitHandleIdentifier = Identifier.For("_eventObject" + kernelIndex.ToString()); ConversionHelper.GenerateEventObjectAndStartKernel(state, waitHandleIdentifier, kernelIdentifier, kernelSizeIdentifier, Literal.Null, kernelPredecessorsIdentifier); ConversionHelper.GenerateFlushCommandQueue(state); return(waitHandleIdentifier); }; completeExpression = string.Format("{0}({1})", methodStruct.Name, arg.CompleteExpression); return(new ConversionResult( new KernelDetails(kernelSource, generate), "value", arg.Type, kernelSizeIdentifier, arguments, new List <Identifier>(), completeExpression )); #endregion }
public virtual Expression VisitConstructArray(ConstructArray consArr, ConstructArray changes, ConstructArray deletions, ConstructArray insertions){ this.UpdateSourceContext(consArr, changes); if (consArr == null) return changes; if (changes != null){ if (deletions == null || insertions == null) Debug.Assert(false); else{ consArr.ElementType = this.VisitTypeReference(consArr.ElementType, changes.ElementType); consArr.Initializers = this.VisitExpressionList(consArr.Initializers, changes.Initializers, deletions.Initializers, insertions.Initializers); consArr.Operands = this.VisitExpressionList(consArr.Operands, changes.Operands, deletions.Operands, insertions.Operands); consArr.Rank = changes.Rank; consArr.Owner = this.VisitExpression(consArr.Owner, changes.Owner, deletions.Owner, insertions.Owner); } }else if (deletions != null) return null; return consArr; }
public virtual Expression VisitConstructArray(ConstructArray consArr1, ConstructArray consArr2) { if (consArr1 == null) return null; if (consArr2 == null) { consArr1.ElementType = this.VisitTypeReference(consArr1.ElementType, null); consArr1.Operands = this.VisitExpressionList(consArr1.Operands, null); consArr1.Initializers = this.VisitExpressionList(consArr1.Initializers, null); consArr1.Owner = this.VisitExpression(consArr1.Owner, null); } else { consArr1.ElementType = this.VisitTypeReference(consArr1.ElementType, consArr2.ElementType); consArr1.Operands = this.VisitExpressionList(consArr1.Operands, consArr2.Operands); consArr1.Initializers = this.VisitExpressionList(consArr1.Initializers, consArr2.Initializers); consArr1.Owner = this.VisitExpression(consArr1.Owner, consArr2.Owner); } return consArr1; }