internal void Analyze(Analyzer /*!*/ analyzer, bool isBaseCtorCallConstrained) { // TODO: isBaseCtorCallConstrained ExInfoFromParent info = new ExInfoFromParent(this); analyzer.EnterActParam(); if (analyzer.ActParamDeclIsUnknown()) { // we don't know whether the parameter will be passed by reference at run-time: if (expression.AllowsPassByReference) { info.Access = AccessType.ReadUnknown; // Although we prepare to pass reference, value can be really passed. // That's why we report warning when user use '&' in calling, // because it has no influence. if (ampersand) { analyzer.ErrorSink.Add(Warnings.ActualParamWithAmpersand, analyzer.SourceUnit, position); } } else { info.Access = AccessType.Read; } } else { if (analyzer.ActParamPassedByRef()) { if (expression.AllowsPassByReference) { info.Access = AccessType.ReadRef; } else { analyzer.ErrorSink.Add(Errors.NonVariablePassedByRef, analyzer.SourceUnit, expression.Position); analyzer.LeaveActParam(); return; } } else { info.Access = AccessType.Read; if (ampersand) { analyzer.ErrorSink.Add(Warnings.ActualParamWithAmpersand, analyzer.SourceUnit, position); } } } expression = expression.Analyze(analyzer, info).Literalize(); analyzer.LeaveActParam(); }
public void Analyze(ActualParam/*!*/node, Analyzer/*!*/ analyzer, bool isBaseCtorCallConstrained) { // TODO: isBaseCtorCallConstrained ExInfoFromParent info = new ExInfoFromParent(node); analyzer.EnterActParam(); if (node.IsVariadic) throw new NotImplementedException(); if (analyzer.ActParamDeclIsUnknown()) { // we don't know whether the parameter will be passed by reference at run-time: if (node.Expression.AllowsPassByReference) { info.Access = AccessType.ReadUnknown; // Although we prepare to pass reference, value can be really passed. // That's why we report warning when user use '&' in calling, // because it has no influence. if (node.Ampersand) analyzer.ErrorSink.Add(Warnings.ActualParamWithAmpersand, analyzer.SourceUnit, node.Span); } else { info.Access = AccessType.Read; } } else { if (analyzer.ActParamPassedByRef()) { if (node.Expression.AllowsPassByReference) { info.Access = AccessType.ReadRef; } else { analyzer.ErrorSink.Add(Errors.NonVariablePassedByRef, analyzer.SourceUnit, node.Expression.Span); analyzer.LeaveActParam(); return; } } else { info.Access = AccessType.Read; if (node.Ampersand) analyzer.ErrorSink.Add(Warnings.ActualParamWithAmpersand, analyzer.SourceUnit, node.Span); } } node._expression = node.Expression.Analyze(analyzer, info).Literalize(); // TODO: if signature is known, act. param has type hint and expression has known type; check if type hint matches expression analyzer.LeaveActParam(); }
internal void Analyze(Analyzer/*!*/ analyzer, bool isBaseCtorCallConstrained) { // TODO: isBaseCtorCallConstrained ExInfoFromParent info = new ExInfoFromParent(this); analyzer.EnterActParam(); if (analyzer.ActParamDeclIsUnknown()) { // we don't know whether the parameter will be passed by reference at run-time: if (expression.AllowsPassByReference) { info.Access = AccessType.ReadUnknown; // Although we prepare to pass reference, value can be really passed. // That's why we report warning when user use '&' in calling, // because it has no influence. if (ampersand) analyzer.ErrorSink.Add(Warnings.ActualParamWithAmpersand, analyzer.SourceUnit, position); } else { info.Access = AccessType.Read; } } else { if (analyzer.ActParamPassedByRef()) { if (expression.AllowsPassByReference) { info.Access = AccessType.ReadRef; } else { analyzer.ErrorSink.Add(Errors.NonVariablePassedByRef, analyzer.SourceUnit, expression.Position); analyzer.LeaveActParam(); return; } } else { info.Access = AccessType.Read; if (ampersand) analyzer.ErrorSink.Add(Warnings.ActualParamWithAmpersand, analyzer.SourceUnit, position); } } expression = expression.Analyze(analyzer, info).Literalize(); analyzer.LeaveActParam(); }
public void Analyze(ActualParam /*!*/ node, Analyzer /*!*/ analyzer, bool isBaseCtorCallConstrained) { // TODO: isBaseCtorCallConstrained ExInfoFromParent info = new ExInfoFromParent(node); analyzer.EnterActParam(); if (node.IsVariadic) { throw new NotImplementedException(); } if (analyzer.ActParamDeclIsUnknown()) { // we don't know whether the parameter will be passed by reference at run-time: if (node.Expression.AllowsPassByReference) { info.Access = AccessType.ReadUnknown; // Although we prepare to pass reference, value can be really passed. // That's why we report warning when user use '&' in calling, // because it has no influence. if (node.Ampersand) { analyzer.ErrorSink.Add(Warnings.ActualParamWithAmpersand, analyzer.SourceUnit, node.Span); } } else { info.Access = AccessType.Read; } } else { if (analyzer.ActParamPassedByRef()) { if (node.Expression.AllowsPassByReference) { info.Access = AccessType.ReadRef; } else { analyzer.ErrorSink.Add(Errors.NonVariablePassedByRef, analyzer.SourceUnit, node.Expression.Span); analyzer.LeaveActParam(); return; } } else { info.Access = AccessType.Read; if (node.Ampersand) { analyzer.ErrorSink.Add(Warnings.ActualParamWithAmpersand, analyzer.SourceUnit, node.Span); } } } node._expression = node.Expression.Analyze(analyzer, info).Literalize(); // TODO: if signature is known, act. param has type hint and expression has known type; check if type hint matches expression analyzer.LeaveActParam(); }
public override Evaluation Analyze(AssignEx node, Analyzer analyzer, ExInfoFromParent info) { access = info.Access; var valueassignex = (ValueAssignEx)node; ExInfoFromParent lvalue_info = new ExInfoFromParent(node); // x[] = y if (node.LValue is ItemUse && ((ItemUse)node.LValue).Index == null) { if (node.Operation != Operations.AssignValue) { var oldop = node.Operation; valueassignex.operation = Operations.AssignValue; // x[] .= y -> x[] = null . y if (oldop == Operations.AssignAppend) { valueassignex.rvalue = new BinaryEx(node.Span, Operations.Concat, new NullLiteral(node.Span), valueassignex.rvalue); } // x[] += y -> x[] = 0 + y else if (oldop == Operations.AssignAdd) { valueassignex.rvalue = new BinaryEx(node.Span, Operations.Add, new NullLiteral(node.Span), valueassignex.rvalue); } // x[] -= y -> x[] = 0 - y else if (oldop == Operations.AssignSub) { valueassignex.rvalue = new BinaryEx(node.Span, Operations.Sub, new NullLiteral(node.Span), valueassignex.rvalue); } // x[] *= y -> x[] = 0 * y else if (oldop == Operations.AssignMul) { valueassignex.rvalue = new BinaryEx(node.Span, Operations.Mul, new NullLiteral(node.Span), valueassignex.rvalue); } // x[] **= y -> x[] = 0 * y else if (oldop == Operations.AssignPow) { valueassignex.rvalue = new BinaryEx(node.Span, Operations.Pow, new NullLiteral(node.Span), valueassignex.rvalue); } // x[] /= y -> x[] = 0 / y else if (oldop == Operations.AssignDiv) { valueassignex.rvalue = new BinaryEx(node.Span, Operations.Div, new NullLiteral(node.Span), valueassignex.rvalue); } // x[] &= y -> x[] = 0 & y else if (oldop == Operations.AssignAnd) { valueassignex.rvalue = new BinaryEx(node.Span, Operations.BitAnd, new NullLiteral(node.Span), valueassignex.rvalue); } else { Debug.Fail("Unhandled operation " + oldop.ToString() + " must be reduced!"); valueassignex.operation = oldop; // change it back, this will result in compile time exception } } } // stop evaluation: valueassignex.rvalue = valueassignex.rvalue.Analyze(analyzer, ExInfoFromParent.DefaultExInfo).Literalize(); if (node.Operation == Operations.AssignValue) { // elimination of $x = $x . expr var concat = valueassignex.rvalue as ConcatEx; DirectVarUse vur; DirectVarUse vul = valueassignex.lvalue as DirectVarUse; if (concat != null && concat.Expressions.Length >= 2 && vul != null && vul.IsMemberOf == null) { if ((vur = concat.Expressions[0] as DirectVarUse) != null && vur.VarName.Equals(vul.VarName) && vur.IsMemberOf == null) { // $x = $x.a.b.c // => // $x .= a.b.c valueassignex.operation = Operations.AssignAppend; lvalue_info.Access = AccessType.ReadAndWrite; //rvalue = concat.RightExpr; concat.Expressions = concat.Expressions.TakeArray(1, concat.Expressions.Length - 1); } else if ((vur = concat.Expressions[concat.Expressions.Length - 1] as DirectVarUse) != null && vur.VarName.Equals(vul.VarName) && vur.IsMemberOf == null) { // $x = a.b.c.$x // => // $x =. a.b.c valueassignex.operation = Operations.AssignPrepend; lvalue_info.Access = AccessType.ReadAndWrite; //rvalue = (Expression)concat.LeftExpr; concat.Expressions = concat.Expressions.TakeArray(0, concat.Expressions.Length - 1); } else { lvalue_info.Access = AccessType.Write; } } else { lvalue_info.Access = AccessType.Write; } } else { lvalue_info.Access = AccessType.ReadAndWrite; } // If this ValueAssignEx is actual param that is to be passed by reference, // AccessType of the destVar has to be changed, because its reference will be // (potencially) passeed ActualParam ap = info.Parent as ActualParam; if (ap != null) { if (analyzer.ActParamDeclIsUnknown()) { if (lvalue_info.Access == AccessType.Write) { lvalue_info.Access = AccessType.WriteAndReadUnknown; } else { lvalue_info.Access = AccessType.ReadAndWriteAndReadUnknown; } } else if (analyzer.ActParamPassedByRef()) { if (lvalue_info.Access == AccessType.Write) { lvalue_info.Access = AccessType.WriteAndReadRef; } else { lvalue_info.Access = AccessType.ReadAndWriteAndReadRef; } } } valueassignex.lvalue.Analyze(analyzer, lvalue_info); //retval not needed ... return(new Evaluation(node)); }
/// <include file='Doc/Nodes.xml' path='doc/method[@name="Expression.Analyze"]/*'/> internal override Evaluation Analyze(Analyzer/*!*/ analyzer, ExInfoFromParent info) { access = info.Access; ExInfoFromParent lvalue_info = new ExInfoFromParent(this); // x[] = y if (lvalue is ItemUse && ((ItemUse)lvalue).Index == null) if (operation != Operations.AssignValue) { var oldop = operation; operation = Operations.AssignValue; // x[] .= y -> x[] = null . y if (oldop == Operations.AssignAppend) rvalue = new BinaryEx(Position, Operations.Concat, new NullLiteral(Position), rvalue); // x[] += y -> x[] = 0 + y else if (oldop == Operations.AssignAdd) rvalue = new BinaryEx(Position, Operations.Add, new NullLiteral(Position), rvalue); // x[] -= y -> x[] = 0 - y else if (oldop == Operations.AssignSub) rvalue = new BinaryEx(Position, Operations.Sub, new NullLiteral(Position), rvalue); // x[] *= y -> x[] = 0 * y else if (oldop == Operations.AssignMul) rvalue = new BinaryEx(Position, Operations.Mul, new NullLiteral(Position), rvalue); // x[] /= y -> x[] = 0 / y else if (oldop == Operations.AssignDiv) rvalue = new BinaryEx(Position, Operations.Div, new NullLiteral(Position), rvalue); // x[] &= y -> x[] = 0 & y else if (oldop == Operations.AssignAnd) rvalue = new BinaryEx(Position, Operations.BitAnd, new NullLiteral(Position), rvalue); else { Debug.Fail("Unhandled operation " + oldop.ToString() + " must be reduced!"); operation = oldop; // change it back, this will result in compile time exception } } // stop evaluation: rvalue = rvalue.Analyze(analyzer, ExInfoFromParent.DefaultExInfo).Literalize(); if (operation == Operations.AssignValue) { // elimination of $x = $x . expr var concat = rvalue as ConcatEx; DirectVarUse vur; DirectVarUse vul = lvalue as DirectVarUse; if (concat != null && concat.Expressions.Count >= 2 && vul != null && vul.IsMemberOf == null) { if ((vur = concat.Expressions[0] as DirectVarUse) != null && vur.VarName.Equals(vul.VarName) && vur.IsMemberOf == null) { // $x = $x.a.b.c // => // $x .= a.b.c operation = Operations.AssignAppend; lvalue_info.Access = AccessType.ReadAndWrite; //rvalue = concat.RightExpr; concat.Expressions.RemoveAt(0); } else if ((vur = concat.Expressions[concat.Expressions.Count - 1] as DirectVarUse) != null && vur.VarName.Equals(vul.VarName) && vur.IsMemberOf == null) { // $x = a.b.c.$x // => // $x =. a.b.c operation = Operations.AssignPrepend; lvalue_info.Access = AccessType.ReadAndWrite; //rvalue = (Expression)concat.LeftExpr; concat.Expressions.RemoveAt(concat.Expressions.Count - 1); } else lvalue_info.Access = AccessType.Write; } else lvalue_info.Access = AccessType.Write; } else lvalue_info.Access = AccessType.ReadAndWrite; // If this ValueAssignEx is actual param that is to be passed by reference, // AccessType of the destVar has to be changed, because its reference will be // (potencially) passeed ActualParam ap = info.Parent as ActualParam; if (ap != null) { if (analyzer.ActParamDeclIsUnknown()) { if (lvalue_info.Access == AccessType.Write) lvalue_info.Access = AccessType.WriteAndReadUnknown; else lvalue_info.Access = AccessType.ReadAndWriteAndReadUnknown; } else if (analyzer.ActParamPassedByRef()) { if (lvalue_info.Access == AccessType.Write) lvalue_info.Access = AccessType.WriteAndReadRef; else lvalue_info.Access = AccessType.ReadAndWriteAndReadRef; } } lvalue.Analyze(analyzer, lvalue_info); //retval not needed ... return new Evaluation(this); }