override public void VisitActualParam(ActualParam x) { _serializer.StartSerialize(typeof(ActualParam).Name, SerializeSpan(x.Span), new NodeObj("IsUnpack", x.IsUnpack.ToString())); base.VisitActualParam(x); _serializer.EndSerialize(); }
private static CallParameter ToCallParameter(ActualParam p) { return(new CallParameter( Parse(p.Expression), ampersand: p.Ampersand, is_unpack: p.IsUnpack )); }
public override void VisitActualParam(ActualParam x) { VisitSpecificElementProlog(); SerializeToken(nameof(x.Ampersand), x.Ampersand.ToString(), null); SerializeToken(nameof(x.IsUnpack), x.IsUnpack.ToString(), null); base.VisitActualParam(x); }
public override void VisitActualParam(ActualParam x) { if (x.IsUnpack) { ConsumeToken(Tokens.T_ELLIPSIS, "..."); } if (x.Ampersand) { ConsumeToken(Tokens.T_AMP, "&"); } VisitElement(x.Expression); }
public PhpTypeCode Emit(ActualParam /*!*/ node, CodeGenerator /*!*/ codeGenerator, bool ensureChainWritable = false) { codeGenerator.ChainBuilder.Create(); if (ensureChainWritable) { codeGenerator.ChainBuilder.EnsureWritable = true; } try { return(node.Expression.Emit(codeGenerator)); } finally { codeGenerator.ChainBuilder.End(); } }
/// <summary> /// Visit actual parameter expression. /// </summary> /// <param name="x"></param> virtual public void VisitActualParam(ActualParam x) { VisitElement(x.Expression); }
public static PhpTypeCode Emit(this ActualParam /*!*/ node, CodeGenerator /*!*/ codeGenerator, bool ensureChainWritable = false) { return(node.NodeCompiler <IActualParamCompiler>().Emit(node, codeGenerator, ensureChainWritable)); }
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)); }