# Dynamic variable names Template( TextInterpolation(PhpOpen), ExpressionStatement(AssignmentExpression( DynamicVariable(VariableName), AssignOp, VariableName))) # Exponentiation Template( TextInterpolation(PhpOpen), ExpressionStatement( AssignmentExpression( VariableName, AssignOp, BinaryExpression(Integer, ArithOp, Integer) ) ), ExpressionStatement( AssignmentExpression( VariableName, AssignOp, Integer)), EchoStatement(echo, BinaryExpression(VariableName, ArithOp, UnaryExpression(ArithOp, VariableName)) ), ExpressionStatement( BinaryExpression( VariableName, ArithOp, UpdateExpression( VariableName, UpdateOp, VariableName ) ) ), ExpressionStatement( BinaryExpression( VariableName, ArithOp, AssignmentExpression( VariableName, AssignOp, VariableName ) ) ) ) # Reserved Identifiers as Names Template( TextInterpolation(PhpOpen), ExpressionStatement(AssignmentExpression( VariableName, AssignOp, NewExpression(new, Name, ArgList)))) # Unary op with assignment expressions Template( TextInterpolation(PhpOpen), IfStatement(if, ParenthesizedExpression(UnaryExpression(LogicOp, AssignmentExpression( VariableName, AssignOp, VariableName))), Block)) # Capitalized logical operators Template( TextInterpolation(PhpOpen), ExpressionStatement( BinaryExpression( CallExpression(Name, ArgList), LogicOp, BinaryExpression( CallExpression(Name, ArgList), LogicOp, CallExpression(Name, ArgList))))) # Reserved words as function calls current()); ==> Template( TextInterpolation(PhpOpen), ExpressionStatement(AssignmentExpression( VariableName, AssignOp, NewExpression(new, Name, ArgList( CallExpression(MemberExpression(VariableName, Name), ArgList)))))) # Scoped self call expressions Template( TextInterpolation(PhpOpen), ExpressionStatement( CallExpression(ScopedExpression(Name, ClassMemberName(Name)), ArgList))) # Symmetric array destructuring Template( TextInterpolation(PhpOpen), ExpressionStatement( AssignmentExpression( VariableName, AssignOp, ArrayExpression( ArrayExpression(Integer, String), ArrayExpression(Integer, String) ) ) ), LineComment, ExpressionStatement( AssignmentExpression( ListExpression(list, ValueList(VariableName,VariableName)), AssignOp, SubscriptExpression( VariableName, Integer ) ) ), LineComment, ExpressionStatement( AssignmentExpression( ListExpression(list,ValueList(VariableName,VariableName)), AssignOp, SubscriptExpression( VariableName, Integer ) ) ), LineComment, ExpressionStatement( AssignmentExpression( ListExpression(list,ValueList(VariableName)), AssignOp, SubscriptExpression( VariableName, Integer ) ) ), LineComment, ExpressionStatement( AssignmentExpression( ArrayExpression(VariableName,VariableName), AssignOp, SubscriptExpression( VariableName, Integer ) ) ), LineComment, ExpressionStatement( AssignmentExpression( ArrayExpression( VariableName, VariableName ), AssignOp, SubscriptExpression( VariableName, Integer ) ) ), LineComment, ExpressionStatement( AssignmentExpression( ArrayExpression(VariableName), AssignOp, SubscriptExpression( VariableName, Integer ) ) ), ExpressionStatement( AssignmentExpression( ArrayExpression( VariableName, VariableName ), AssignOp, CallExpression( ScopedExpression(Name, ClassMemberName(Name)), ArgList(VariableName) ) ) ) ) # Precedence of assignment, `or`, `xor`, and `and` Template( TextInterpolation(PhpOpen), ExpressionStatement( BinaryExpression( AssignmentExpression( VariableName, AssignOp, Boolean), LogicOp, Boolean)), ExpressionStatement( BinaryExpression( AssignmentExpression( VariableName, AssignOp, Boolean), LogicOp, Boolean)), ExpressionStatement( BinaryExpression( AssignmentExpression( VariableName, AssignOp, Boolean), LogicOp, Boolean)), ExpressionStatement( BinaryExpression( BinaryExpression( AssignmentExpression( VariableName, AssignOp, Boolean), LogicOp, Boolean), LogicOp, BinaryExpression( Boolean, LogicOp, BinaryExpression( Boolean, LogicOp, Boolean))))) # Associativity of conditional ==> Template( TextInterpolation(PhpOpen), ExpressionStatement( ConditionalExpression( ConditionalExpression(Boolean, LogicOp, Boolean, Boolean), LogicOp, String, String)), TextInterpolation(PhpClose)) # Associativity of null-coalescence ==> Template( TextInterpolation(PhpOpen), ExpressionStatement( BinaryExpression( null, LogicOp, BinaryExpression( null, LogicOp, Integer))), TextInterpolation(PhpClose)) # Associativity of negation ==> Template( TextInterpolation(PhpOpen), ExpressionStatement( BinaryExpression( UnaryExpression(ArithOp, Integer), ArithOp, UnaryExpression(ArithOp, Integer))), ExpressionStatement( UnaryExpression(LogicOp, BinaryExpression(VariableName, LogicOp, Name))), TextInterpolation(PhpClose)) # Augmented assignment ==> Template( TextInterpolation(PhpOpen), ExpressionStatement( UpdateExpression( VariableName, UpdateOp, AssignmentExpression( VariableName, AssignOp, String))), ExpressionStatement( UpdateExpression( VariableName, UpdateOp, UpdateExpression( VariableName, UpdateOp, Integer))), ExpressionStatement( UpdateExpression( VariableName, UpdateOp, BinaryExpression(String, ConcatOp, String))), ExpressionStatement( BinaryExpression( String, ConcatOp, UpdateExpression( VariableName, UpdateOp, String))), TextInterpolation(PhpClose)) # Nested assignemnts Template( TextInterpolation(PhpOpen), ExpressionStatement( AssignmentExpression( VariableName, AssignOp, AssignmentExpression( SubscriptExpression(VariableName, Integer), AssignOp, AssignmentExpression( SubscriptExpression(VariableName, Integer), AssignOp, VariableName))))) # All binary op precedence levels 12 << 13 + 14 * (int) 15 instanceof foo; (int) 1 instanceof foo / 3 - 4 >> 5 <= 6 <=> 7 & 8 ^ 9 | 10 && 11 || 12 ?? $i += 13 and 14 xor 15 or 16; ==> Template( TextInterpolation(PhpOpen), ExpressionStatement( BinaryExpression( Integer, LogicOp, BinaryExpression( Integer, LogicOp, BinaryExpression( Integer, LogicOp, UpdateExpression( VariableName, UpdateOp, BinaryExpression( Integer, LogicOp, BinaryExpression( Integer, LogicOp, BinaryExpression( Integer, LogicOp, BinaryExpression( Integer, BitOp, BinaryExpression( Integer, BitOp, BinaryExpression( Integer, BitOp, BinaryExpression( Integer, CompareOp, BinaryExpression( Integer, CompareOp, BinaryExpression( Integer, BitOp, BinaryExpression( Integer, ArithOp, BinaryExpression( Integer, ArithOp, BinaryExpression( CastExpression( NamedType(Name), Integer), LogicOp, Name))))))))))))))))), ExpressionStatement( BinaryExpression( BinaryExpression( BinaryExpression( BinaryExpression( BinaryExpression( BinaryExpression( BinaryExpression( BinaryExpression( BinaryExpression( BinaryExpression( BinaryExpression( BinaryExpression( BinaryExpression( BinaryExpression( BinaryExpression( CastExpression( NamedType(Name), Integer), LogicOp, Name), ArithOp, Integer), ArithOp, Integer), BitOp, Integer), CompareOp, Integer), CompareOp, Integer), BitOp, Integer), BitOp, Integer), BitOp, Integer), LogicOp, Integer), LogicOp, Integer), LogicOp, UpdateExpression( VariableName, UpdateOp, Integer)), LogicOp, Integer), LogicOp, Integer), LogicOp, Integer))) # Concatenation precedence Template( TextInterpolation(PhpOpen), ExpressionStatement( BinaryExpression( String, ConcatOp, BinaryExpression( String, ArithOp, Integer ) ) ) ) # Arrays "orange", "bar" => "apple", "baz" => "lemon"]); $a = [...$values]; ?> ==> Template( TextInterpolation(PhpOpen), ExpressionStatement(CallExpression( Name, ArgList(ArrayExpression(Integer, Integer, Integer)))), ExpressionStatement( CallExpression( Name, ArgList( ArrayExpression(Pair(String, String), Pair(String, String), Pair(String, String))))), ExpressionStatement( AssignmentExpression( VariableName, AssignOp, ArrayExpression(VariadicUnpacking(VariableName)) ) ), TextInterpolation(PhpClose)) # Anonymous functions Template( TextInterpolation(PhpOpen), ExpressionStatement( CallExpression( Name, ArgList( FunctionExpression(function, ParamList, Block(EchoStatement(echo, String)))))), ExpressionStatement( CallExpression( Name, ArgList( FunctionExpression(function, ParamList(Parameter(VariableName)), use, UseList(VariableName), Block(ExpressionStatement(UpdateExpression( VariableName, UpdateOp, VariableName)))), Integer))), ExpressionStatement( CallExpression( Name, ArgList( FunctionExpression(function, ParamList(Parameter(VariableName)), use, UseList(VariableName), Block(ExpressionStatement(UpdateExpression( VariableName, UpdateOp, VariableName)))), Integer)))) # Throw expressions createNotFoundException(); throw static::createNotFoundException(); throw $userIsAuthorized ? new ForbiddenException() : new UnauthorizedException(); throw $maybeNullException ?? new Exception(); throw $exception = new Exception(); throw $condition1 && $condition2 ? new Exception1() : new Exception2(); throw $exception ??= new Exception(); ==> Template( TextInterpolation(PhpOpen), ExpressionStatement( ThrowExpression(throw, NewExpression(new, Name, ArgList(Name) ) ) ), ExpressionStatement( AssignmentExpression( VariableName, AssignOp, ConditionalExpression( UnaryExpression(LogicOp, CallExpression(Name, ArgList(VariableName))), LogicOp, CallExpression(Name, ArgList(VariableName)), ThrowExpression(throw, NewExpression(new, Name, ArgList)) ) ) ), ExpressionStatement( BinaryExpression( VariableName, LogicOp, ThrowExpression(throw, NewExpression(new, Name, ArgList) ) ) ), ExpressionStatement( BinaryExpression( VariableName, LogicOp, ThrowExpression(throw, NewExpression(new, Name, ArgList) ) ) ), ExpressionStatement( BinaryExpression( VariableName, LogicOp, ThrowExpression(throw, NewExpression(new, Name, ArgList) ) ) ), ExpressionStatement( BinaryExpression( VariableName, LogicOp, ThrowExpression(throw, NewExpression(new, Name, ArgList) ) ) ), ExpressionStatement( ThrowExpression(throw, CallExpression(MemberExpression(VariableName, Name), ArgList) ) ), ExpressionStatement( ThrowExpression(throw, CallExpression( ScopedExpression(Name, ClassMemberName(Name)), ArgList ) ) ), ExpressionStatement( ThrowExpression(throw, ConditionalExpression( VariableName, LogicOp, NewExpression(new, Name, ArgList), NewExpression(new, Name, ArgList) ) ) ), ExpressionStatement( ThrowExpression(throw, BinaryExpression( VariableName, LogicOp, NewExpression(new, Name, ArgList) ) ) ), ExpressionStatement( ThrowExpression(throw, AssignmentExpression( VariableName, AssignOp, NewExpression(new, Name, ArgList) ) ) ), ExpressionStatement( ThrowExpression(throw, ConditionalExpression( BinaryExpression( VariableName, LogicOp, VariableName ), LogicOp, NewExpression(new, Name, ArgList), NewExpression(new, Name, ArgList) ) ) ), ExpressionStatement( ThrowExpression(throw, UpdateExpression( VariableName, UpdateOp, NewExpression(new, Name, ArgList) ) ) ) ) # Nullsafe operator b; $a?->b($c); new $a?->b; $country = $session?->user?->getAddress()?->country; ==> Template( TextInterpolation(PhpOpen), ExpressionStatement( MemberExpression( VariableName, Name ) ), ExpressionStatement( CallExpression( MemberExpression(VariableName, Name), ArgList(VariableName) ) ), ExpressionStatement( NewExpression(new, MemberExpression(VariableName, Name)) ), ExpressionStatement( AssignmentExpression( VariableName, AssignOp, MemberExpression( CallExpression( MemberExpression(MemberExpression(VariableName, Name), Name), ArgList ), Name ) ) ) ) # Match expressions $b, Lexer::T_UPDATE => updateStatement(), Lexer::T_DELETE => $this->DeleteStatement(), default => $this->syntaxError('SELECT, UPDATE or DELETE'), }; ==> Template( TextInterpolation(PhpOpen), ExpressionStatement( AssignmentExpression( VariableName, AssignOp, MatchExpression(match, ParenthesizedExpression(VariableName), MatchBlock( MatchArm( ScopedExpression(Name, ClassMemberName(Name)), VariableName VariableName ), MatchArm( ScopedExpression(Name, ClassMemberName(Name)), CallExpression(Name, ArgList) ), MatchArm( ScopedExpression(Name, ClassMemberName(Name)) CallExpression(MemberExpression(VariableName, Name), ArgList) ), MatchArm( default, CallExpression(MemberExpression(VariableName, Name), ArgList(String)) ) ) ) ) ) ) # Arrow functions $a; fn($x = 42) => $x; static fn(&$x) => $x; fn&($x) => $x; fn($x, ...$rest) => $rest; fn(): int => $x; $fn1 = fn($x) => $x + $y; ==> Template( TextInterpolation(PhpOpen), ExpressionStatement( ArrowFunction(fn, ParamList( Parameter( NamedType(Name), VariableName ) ), VariableName ) ), ExpressionStatement( ArrowFunction(fn, ParamList( Parameter( VariableName, AssignOp, Integer) ), VariableName ) ), ExpressionStatement( ArrowFunction(static, fn, ParamList(Parameter(VariableName)), VariableName ) ), ExpressionStatement( ArrowFunction(fn, ParamList(Parameter(VariableName)), VariableName ) ), ExpressionStatement( ArrowFunction(fn, ParamList( Parameter(VariableName), VariadicParameter(VariableName)), VariableName)), ExpressionStatement( ArrowFunction(fn, ParamList, NamedType(Name), VariableName ) ), ExpressionStatement( AssignmentExpression( VariableName, AssignOp, ArrowFunction(fn, ParamList( Parameter(VariableName) ), BinaryExpression(VariableName, ArithOp, VariableName) ) ) ) ) # Functions with named arguments Template( TextInterpolation(PhpOpen), ExpressionStatement( CallExpression( Name, ArgList( NamedArgument(Name, Integer), NamedArgument(Name, Integer), NamedArgument(Name, VariableName) ) ) ) ) # Precedence between concatenation and shift Template( TextInterpolation(PhpOpen), ExpressionStatement( BinaryExpression( VariableName, ConcatOp, BinaryExpression(VariableName, BitOp, VariableName))))