public override void OnSlicingExpression(SlicingExpression node) { BoundSpillSequenceBuilder builder = null; var target = VisitExpression(ref builder, node.Target); BoundSpillSequenceBuilder indicesBuilder = null; var indices = VisitSliceCollection(ref indicesBuilder, node.Indices); if (indicesBuilder != null) { // spill the array if there were await expressions in the indices if (builder == null) { builder = new BoundSpillSequenceBuilder(); } target = Spill(builder, target); } if (builder != null) { builder.Include(indicesBuilder); indicesBuilder = builder; } node.Target = target; node.Indices = indices; ReplaceCurrentNode(UpdateExpression(indicesBuilder, node)); }
void ProcessDuckSlicingPropertySet(BinaryExpression node) { SlicingExpression slice = (SlicingExpression)node.Left; ArrayLiteralExpression args = new ArrayLiteralExpression(); foreach (Slice index in slice.Indices) { if (AstUtil.IsComplexSlice(index)) { throw CompilerErrorFactory.NotImplemented(index, "complex slice for duck"); } args.Items.Add(index.Begin); } args.Items.Add(node.Right); BindExpressionType(args, TypeSystemServices.ObjectArrayType); Expression target = slice.Target; string memberName = ""; if (NodeType.MemberReferenceExpression == target.NodeType) { MemberReferenceExpression mre = ((MemberReferenceExpression)target); target = mre.Target; memberName = mre.Name; } MethodInvocationExpression mie = CodeBuilder.CreateMethodInvocation( RuntimeServices_SetSlice, target, CodeBuilder.CreateStringLiteral(memberName), args); Replace(mie); }
override public void OnSlicingExpression(SlicingExpression node) { Visit(node.Target); Write("["); WriteCommaSeparatedList(node.Indices); Write("]"); }
void CompleteOmittedExpressions(SlicingExpression node) { foreach (var index in node.Indices.Where(slice => slice.Begin == OmittedExpression.Default)) { index.Begin = CodeBuilder.CreateIntegerLiteral(0); } }
private MethodInvocationExpression ComplexStringSlicingExpressionFor(SlicingExpression node) { var slice = node.Indices[0]; if (IsNullOrOmitted(slice.End)) { if (NeedsNormalization(slice.Begin)) { var mie = CodeBuilder.CreateEvalInvocation(node.LexicalInfo); mie.ExpressionType = TypeSystemServices.StringType; var temp = DeclareTempLocal(TypeSystemServices.StringType); mie.Arguments.Add( CodeBuilder.CreateAssignment( CodeBuilder.CreateReference(temp), node.Target)); mie.Arguments.Add( CodeBuilder.CreateMethodInvocation( CodeBuilder.CreateReference(temp), MethodCache.String_Substring_Int, CodeBuilder.CreateMethodInvocation( MethodCache.RuntimeServices_NormalizeStringIndex, CodeBuilder.CreateReference(temp), slice.Begin))); return(mie); } return(CodeBuilder.CreateMethodInvocation(node.Target, MethodCache.String_Substring_Int, slice.Begin)); } return(CodeBuilder.CreateMethodInvocation(MethodCache.RuntimeServices_Mid, node.Target, slice.Begin, slice.End)); }
void ImplementRegularICallableCall( Method call, InternalCallableType type, ClassDefinition node, CallableSignature signature) { MethodInvocationExpression mie = CreateInvokeInvocation(type); IParameter[] parameters = signature.Parameters; for (int i = 0; i < parameters.Length; ++i) { SlicingExpression slice = CodeBuilder.CreateSlicing( CodeBuilder.CreateReference(call.Parameters[0]), i); mie.Arguments.Add(slice); } if (TypeSystemServices.VoidType == signature.ReturnType) { call.Body.Add(mie); } else { call.Body.Add(new ReturnStatement(mie)); } }
public override void PropagateChanges(MethodInvocationExpression eval, List chain) { ExpressionCollection items = new ExpressionCollection(); foreach (object local1 in chain.Reversed) { if (!(local1 is ProcessAssignmentsToSpecialMembers.ChainItem)) { } ProcessAssignmentsToSpecialMembers.ChainItem item = (ProcessAssignmentsToSpecialMembers.ChainItem)RuntimeServices.Coerce(local1, typeof(ProcessAssignmentsToSpecialMembers.ChainItem)); if (item.Container is MethodInvocationExpression) { break; } if (item.Container is SlicingExpression) { SlicingExpression expression = (SlicingExpression)item.Container; Expression[] expressionArray1 = new Expression[] { expression.Target.CloneNode(), expression.Indices[0].Begin.CloneNode(), this.CodeBuilder.CreateReference(item.Local) }; items.Add(this.CreateConstructorInvocation(this._sliceValueTypeChangeConstructor, expressionArray1)); break; } MemberReferenceExpression container = (MemberReferenceExpression)item.Container; Expression[] args = new Expression[] { container.Target.CloneNode(), this.CodeBuilder.CreateStringLiteral(container.Name), this.CodeBuilder.CreateReference(item.Local) }; items.Add(this.CreateConstructorInvocation(this._valueTypeChangeConstructor, args)); } MethodInvocationExpression expression3 = this.CodeBuilder.CreateMethodInvocation(this._propagateChanges); IArrayType arrayType = this._valueTypeChangeType.MakeArrayType(1); expression3.Arguments.Add(this.CodeBuilder.CreateArray(arrayType, items)); eval.Arguments.Add(expression3); }
private static SlicingExpression CreateRawArraySlicing(ReferenceExpression arrayRef, Expression numRef, IType elementType) { SlicingExpression expression = new SlicingExpression(arrayRef.CloneNode(), numRef.CloneNode()); expression.ExpressionType = elementType; AstAnnotations.MarkRawArrayIndexing(expression); return(expression); }
public override void Switch(IAstTransformer transformer, out Node resultingNode) { SlicingExpression thisNode = (SlicingExpression)this; Expression resultingTypedNode = thisNode; transformer.OnSlicingExpression(thisNode, ref resultingTypedNode); resultingNode = resultingTypedNode; }
private static string GetSlicingMemberName(SlicingExpression node) { if (NodeType.MemberReferenceExpression == node.Target.NodeType) { MemberReferenceExpression mre = ((MemberReferenceExpression)node.Target); return(mre.Name); } return(""); }
private ArrayLiteralExpression GetArrayForIndices(SlicingExpression node) { var args = new ArrayLiteralExpression(); foreach (var index in node.Indices) { args.Items.Add(index.Begin); } BindExpressionType(args, TypeSystemServices.ObjectArrayType); return(args); }
override public void LeaveSlicingExpression(SlicingExpression node) { if (IsDuckTyped(node.Target)) { BindDuck(node); } else { base.LeaveSlicingExpression(node); } }
override public void OnSlicingExpression(SlicingExpression node) { var tern = ProcessTargets(node); if (tern != null) { Visit(node.Indices); ReplaceCurrentNode(tern); } base.OnSlicingExpression(node); }
private static Expression GetSlicingTarget(SlicingExpression node) { Expression target = node.Target; if (NodeType.MemberReferenceExpression == target.NodeType) { MemberReferenceExpression mre = ((MemberReferenceExpression)target); return(mre.Target); } return(target); }
void ExpandComplexArraySlicing(SlicingExpression node) { if (node.Indices.Count > 1) { MethodInvocationExpression mie = null; var computeEnd = new ArrayLiteralExpression(); var collapse = new ArrayLiteralExpression(); var ranges = new ArrayLiteralExpression(); for (int i = 0; i < node.Indices.Count; i++) { ranges.Items.Add(node.Indices[i].Begin); if (node.Indices[i].End == null) { var end = new BinaryExpression(BinaryOperatorType.Addition, node.Indices[i].Begin, new IntegerLiteralExpression(1)); ranges.Items.Add(end); BindExpressionType(end, GetExpressionType(node.Indices[i].Begin)); computeEnd.Items.Add(new BoolLiteralExpression(false)); collapse.Items.Add(new BoolLiteralExpression(true)); } else if (node.Indices[i].End == OmittedExpression.Default) { var end = new IntegerLiteralExpression(0); ranges.Items.Add(end); BindExpressionType(end, GetExpressionType(node.Indices[i].Begin)); computeEnd.Items.Add(new BoolLiteralExpression(true)); collapse.Items.Add(new BoolLiteralExpression(false)); } else { ranges.Items.Add(node.Indices[i].End); computeEnd.Items.Add(new BoolLiteralExpression(false)); collapse.Items.Add(new BoolLiteralExpression(false)); } } mie = CodeBuilder.CreateMethodInvocation(MethodCache.RuntimeServices_GetMultiDimensionalRange1, node.Target, ranges); mie.Arguments.Add(computeEnd); mie.Arguments.Add(collapse); BindExpressionType(ranges, TypeSystemServices.Map(typeof(int[]))); BindExpressionType(computeEnd, TypeSystemServices.Map(typeof(bool[]))); BindExpressionType(collapse, TypeSystemServices.Map(typeof(bool[]))); node.ParentNode.Replace(node, mie); } else { var slice = node.Indices[0]; var mie = IsNullOrOmitted(slice.End) ? CodeBuilder.CreateMethodInvocation(MethodCache.RuntimeServices_GetRange1, node.Target, slice.Begin) : CodeBuilder.CreateMethodInvocation(MethodCache.RuntimeServices_GetRange2, node.Target, slice.Begin, slice.End); node.ParentNode.Replace(node, mie); } }
private ArrayLiteralExpression GetArrayForIndices(SlicingExpression node) { ArrayLiteralExpression args = new ArrayLiteralExpression(); foreach (Slice index in node.Indices) { if (AstUtil.IsComplexSlice(index)) { throw CompilerErrorFactory.NotImplemented(index, "complex slice for duck"); } args.Items.Add(index.Begin); } BindExpressionType(args, TypeSystemServices.ObjectArrayType); return(args); }
private void ProcessAssignment(BinaryExpression node) { if (NodeType.SlicingExpression == node.Left.NodeType) { SlicingExpression slice = (SlicingExpression)node.Left; if (IsDuckTyped(slice.Target)) { ProcessDuckSlicingPropertySet(node); } } else if (TypeSystemServices.IsQuackBuiltin(node.Left)) { ProcessQuackPropertySet(node); } }
public SlicingExpression CreateSlicing(Expression target, int begin) { SlicingExpression expression = new SlicingExpression(target, CreateIntegerLiteral(begin)); IType expressionType = _tss.ObjectType; IArrayType arrayType = target.ExpressionType as IArrayType; if (null != arrayType) { expressionType = arrayType.GetElementType(); } expression.ExpressionType = expressionType; return(expression); }
public override void OnSlicingExpression(SlicingExpression node) { base.OnSlicingExpression(node); var arrayType = GetExpressionType(node.Target) as IArrayType; if (arrayType == null) { return; } if (arrayType.Rank != node.Indices.Count) { Error(CompilerErrorFactory.InvalidArrayRank(node, node.Target.ToCodeString(), arrayType.Rank, node.Indices.Count)); } }
public override void OnSlicingExpression(SlicingExpression node) { Switch(node.Target); Write("["); Switch(node.Begin); if (null != node.End || WasOmitted(node.Begin)) { Write(":"); } Switch(node.End); if (null != node.Step) { Write(":"); Switch(node.Step); } Write("]"); }
void ProcessDuckSlicingPropertySet(BinaryExpression node) { SlicingExpression slice = (SlicingExpression)node.Left; ArrayLiteralExpression args = GetArrayForIndices(slice); args.Items.Add(node.Right); MethodInvocationExpression mie = CodeBuilder.CreateMethodInvocation( node.LexicalInfo, RuntimeServices_SetSlice, GetSlicingTarget(slice), CodeBuilder.CreateStringLiteral(GetSlicingMemberName(slice)), args); Replace(mie); }
public override void OnSlicingExpression(SlicingExpression node) { base.OnSlicingExpression(node); if (!node.IsComplexSlicing()) { return; } if (node.IsTargetOfAssignment()) { return; } CompleteOmittedExpressions(node); ExpandComplexSlicing(node); }
void ImplementRegularICallableCall( Method call, InternalCallableType type, ClassDefinition node, CallableSignature signature) { MethodInvocationExpression mie = CreateInvokeInvocation(type); IParameter[] parameters = signature.Parameters; int fixedParametersLength = signature.AcceptVarArgs ? parameters.Length - 1 : parameters.Length; for (int i = 0; i < fixedParametersLength; ++i) { SlicingExpression slice = CodeBuilder.CreateSlicing( CodeBuilder.CreateReference(call.Parameters[0]), i); mie.Arguments.Add(slice); } if (signature.AcceptVarArgs) { if (parameters.Length == 1) { mie.Arguments.Add(CodeBuilder.CreateReference(call.Parameters[0])); } else { mie.Arguments.Add( CodeBuilder.CreateMethodInvocation( RuntimeServices_GetRange1, CodeBuilder.CreateReference(call.Parameters[0]), CodeBuilder.CreateIntegerLiteral(fixedParametersLength))); } } if (TypeSystemServices.VoidType == signature.ReturnType) { call.Body.Add(mie); } else { call.Body.Add(new ReturnStatement(mie)); } CheckMethodGenerics(call, node); }
override public void LeaveSlicingExpression(SlicingExpression node) { if (!IsDuckTyped(node.Target)) { return; } if (AstUtil.IsLhsOfAssignment(node)) { return; } // todo // a[foo] // RuntimeServices.GetSlice(a, "", (foo,)) ArrayLiteralExpression args = new ArrayLiteralExpression(); foreach (Slice index in node.Indices) { if (AstUtil.IsComplexSlice(index)) { throw CompilerErrorFactory.NotImplemented(index, "complex slice for duck"); } args.Items.Add(index.Begin); } BindExpressionType(args, TypeSystemServices.ObjectArrayType); Expression target = node.Target; string memberName = ""; if (NodeType.MemberReferenceExpression == target.NodeType) { MemberReferenceExpression mre = ((MemberReferenceExpression)target); target = mre.Target; memberName = mre.Name; } MethodInvocationExpression mie = CodeBuilder.CreateMethodInvocation( RuntimeServices_GetSlice, target, CodeBuilder.CreateStringLiteral(memberName), args); Replace(mie); }
void ExpandComplexListSlicing(SlicingExpression node) { var slice = node.Indices[0]; MethodInvocationExpression mie; if (IsNullOrOmitted(slice.End)) { mie = CodeBuilder.CreateMethodInvocation(node.Target, MethodCache.List_GetRange1); mie.Arguments.Add(slice.Begin); } else { mie = CodeBuilder.CreateMethodInvocation(node.Target, MethodCache.List_GetRange2); mie.Arguments.Add(slice.Begin); mie.Arguments.Add(slice.End); } node.ParentNode.Replace(node, mie); }
public override void OnSlicingExpression(SlicingExpression node) { ClearResult(); Visit(node.Target); if (node.Indices.Count > 0) { Slice slice = node.Indices[0]; if (slice.End != null) { // Boo slice, returns a part of the source -> same type as source return; } } IReturnType rt = (resolveResult != null) ? resolveResult.ResolvedType : null; if (rt == null) { ClearResult(); return; } List <IProperty> indexers = rt.GetProperties(); // remove non-indexers: for (int i = 0; i < indexers.Count; i++) { if (!indexers[i].IsIndexer) { indexers.RemoveAt(i--); } } IReturnType[] parameters = new IReturnType[node.Indices.Count]; for (int i = 0; i < parameters.Length; i++) { Expression expr = node.Indices[i].Begin as Expression; if (expr != null) { ClearResult(); Visit(expr); parameters[i] = (resolveResult != null) ? resolveResult.ResolvedType : null; } } MakeResult(MemberLookupHelper.FindOverload(indexers.ToArray(), parameters)); }
private void ExpandComplexSlicing(SlicingExpression node) { var targetType = GetExpressionType(node.Target); if (IsString(targetType)) { ExpandComplexStringSlicing(node); } else if (IsList(targetType)) { ExpandComplexListSlicing(node); } else if (targetType.IsArray) { ExpandComplexArraySlicing(node); } else { NotImplemented(node, "complex slicing for anything but lists, arrays and strings"); } }
void PropagateByRefParameterChanges(Method call, IParameter[] parameters, InternalLocal[] temporaries) { int byRefIndex = 0; for (int i = 0; i < parameters.Length; ++i) { if (!parameters[i].IsByRef) { continue; } SlicingExpression slice = CodeBuilder.CreateSlicing( CodeBuilder.CreateReference(call.Parameters[0]), i); call.Body.Add( CodeBuilder.CreateAssignment( slice, CodeBuilder.CreateReference(temporaries[byRefIndex]))); ++byRefIndex; } }
public override void OnMethodInvocationExpression(MethodInvocationExpression node) { base.OnMethodInvocationExpression(node); var target = node.Target as MemberReferenceExpression; if (target == null) { return; } var method = target.Entity as IMethod; if (method == null || !method.IsSpecialName) { return; } if (target.Name == "set_Item") { var indexerArgs = node.Arguments.Take(node.Arguments.Count - 1).Select(arg => new Slice(arg)).ToArray(); var slicingExpression = new SlicingExpression(target.Target, indexerArgs); var right = node.Arguments.Last(); node.ParentNode.Replace(node, new BinaryExpression(BinaryOperatorType.Assign, slicingExpression, right)); return; } if (target.Name == "get_Item" || target.Name == "get_Chars") { var indexerArgs = node.Arguments.Take(node.Arguments.Count).Select(arg => new Slice(arg)).ToArray(); var slicingExpression = new SlicingExpression(target.Target, indexerArgs); node.ParentNode.Replace(node, slicingExpression); } }
override public void LeaveBinaryExpression(BinaryExpression node) { if (BinaryOperatorType.Assign == node.Operator) { if (NodeType.SlicingExpression == node.Left.NodeType) { SlicingExpression slice = (SlicingExpression)node.Left; if (IsDuckTyped(slice.Target)) { ProcessDuckSlicingPropertySet(node); } } else if (TypeSystemServices.IsQuackBuiltin(node.Left)) { ProcessQuackPropertySet(node); } return; } if (!AstUtil.IsOverloadableOperator(node.Operator)) { return; } if (!IsDuckTyped(node.Left) && !IsDuckTyped(node.Right)) { return; } MethodInvocationExpression mie = CodeBuilder.CreateMethodInvocation( RuntimeServices_InvokeBinaryOperator, CodeBuilder.CreateStringLiteral( AstUtil.GetMethodNameForOperator(node.Operator)), node.Left, node.Right); Replace(mie); }