# Identifiers fn main() { abc; } ==> SourceFile( FunctionItem(fn,BoundIdentifier, ParamList, Block( ExpressionStatement(Identifier)))) # Raw identifiers fn main() { (r#abc as r#Def).r#ghi; } ==> SourceFile( FunctionItem(fn, BoundIdentifier, ParamList, Block( ExpressionStatement(FieldExpression( ParenthesizedExpression( TypeCastExpression(Identifier, as, TypeIdentifier)), FieldIdentifier))))) # Unary operator expressions -num; !bits; *boxed_thing; ==> SourceFile( ExpressionStatement(UnaryExpression(ArithOp, Identifier)), ExpressionStatement(UnaryExpression(LogicOp, Identifier)), ExpressionStatement(UnaryExpression(DerefOp, Identifier))) # Reference expressions &a; &mut self.name; ==> SourceFile( ExpressionStatement(ReferenceExpression(Identifier)), ExpressionStatement(ReferenceExpression(mut, FieldExpression(self, FieldIdentifier)))) # Try expressions a.unwrap()?; ==> SourceFile( ExpressionStatement(TryExpression(CallExpression(FieldExpression(Identifier, FieldIdentifier), ArgList)))) # Binary operator expressions a * b; a / b; a % b; a + b; a - b; a >> b; a << b; a == b; a && b; a || b; ==> SourceFile( ExpressionStatement(BinaryExpression(Identifier, ArithOp, Identifier)), ExpressionStatement(BinaryExpression(Identifier, ArithOp, Identifier)), ExpressionStatement(BinaryExpression(Identifier, ArithOp, Identifier)), ExpressionStatement(BinaryExpression(Identifier, ArithOp, Identifier)), ExpressionStatement(BinaryExpression(Identifier, ArithOp, Identifier)), ExpressionStatement(BinaryExpression(Identifier, BitOp, Identifier)), ExpressionStatement(BinaryExpression(Identifier, BitOp, Identifier)), ExpressionStatement(BinaryExpression(Identifier, CompareOp, Identifier)), ExpressionStatement(BinaryExpression(Identifier, LogicOp, Identifier)), ExpressionStatement(BinaryExpression(Identifier, LogicOp, Identifier))) # Grouped expressions (0); (2 * (3 + 4)); ==> SourceFile( ExpressionStatement(ParenthesizedExpression(Integer)), ExpressionStatement(ParenthesizedExpression(BinaryExpression( Integer, ArithOp, ParenthesizedExpression(BinaryExpression(Integer, ArithOp, Integer)))))) # Range expressions 1..2; 3..; ..4; ..; 1..b; a..b; ==> SourceFile( ExpressionStatement(RangeExpression(Integer, Integer)), ExpressionStatement(RangeExpression(Integer)), ExpressionStatement(RangeExpression(Integer)), ExpressionStatement(RangeExpression), ExpressionStatement(RangeExpression(Integer, Identifier)), ExpressionStatement(RangeExpression(Identifier, Identifier))) # Assignment expressions x = y; ==> SourceFile( ExpressionStatement(AssignmentExpression( Identifier, Identifier))) # Compound assignment expressions x += 1; x += y; ==> SourceFile( ExpressionStatement(AssignmentExpression(Identifier, UpdateOp, Integer)), ExpressionStatement(AssignmentExpression(Identifier, UpdateOp, Identifier))) # Type cast expressions 1000 as u8; let character = integer as char; let size: f64 = len(values) as f64; ==> SourceFile( ExpressionStatement(TypeCastExpression( Integer, as, TypeIdentifier)), LetDeclaration(let, BoundIdentifier, TypeCastExpression( Identifier, as, TypeIdentifier)), LetDeclaration(let, BoundIdentifier, TypeIdentifier, TypeCastExpression( CallExpression( Identifier, ArgList(Identifier)), as, TypeIdentifier))) # Call expressions foo(); add(1i32, 2i32); add( 1i32, 2i32, ); ==> SourceFile( ExpressionStatement(CallExpression( Identifier, ArgList)), ExpressionStatement(CallExpression( Identifier, ArgList(Integer, Integer))), ExpressionStatement(CallExpression( Identifier, ArgList(Integer, Integer)))) # Array expressions []; [1, 2, 3]; ["a", "b", "c"]; [0; 128]; ==> SourceFile( ExpressionStatement(ArrayExpression), ExpressionStatement(ArrayExpression( Integer, Integer, Integer)), ExpressionStatement(ArrayExpression( String, String, String)), ExpressionStatement(ArrayExpression( Integer, Integer))) # Tuple expressions (); (0,); let (x, y, z) = (1, 2, 3); ==> SourceFile( ExpressionStatement(UnitExpression), ExpressionStatement(TupleExpression(Integer)), LetDeclaration(let, TuplePattern(BoundIdentifier, BoundIdentifier, BoundIdentifier), TupleExpression(Integer, Integer, Integer))) # Struct expressions NothingInMe {}; Point {x: 10.0, y: 20.0}; let a = SomeStruct { field1, field2: expression, field3, }; let u = game::User {name: "Joe", age: 35, score: 100_000}; ==> SourceFile( ExpressionStatement(StructExpression(TypeIdentifier, FieldInitializerList)), ExpressionStatement(StructExpression(TypeIdentifier, FieldInitializerList( FieldInitializer(FieldIdentifier, Float), FieldInitializer(FieldIdentifier, Float)))), LetDeclaration(let, BoundIdentifier, StructExpression( TypeIdentifier, FieldInitializerList( ShorthandFieldInitializer( Identifier), FieldInitializer(FieldIdentifier, Identifier), ShorthandFieldInitializer( Identifier)))), LetDeclaration(let, BoundIdentifier, StructExpression( ScopedTypeIdentifier(ScopeIdentifier, TypeIdentifier), FieldInitializerList( FieldInitializer(FieldIdentifier, String), FieldInitializer(FieldIdentifier, Integer), FieldInitializer(FieldIdentifier, Integer))))) # Struct expressions with update initializers let u = User{name, ..current_user()}; ==> SourceFile( LetDeclaration(let, BoundIdentifier, StructExpression( TypeIdentifier, FieldInitializerList( ShorthandFieldInitializer( Identifier), BaseFieldInitializer(CallExpression(Identifier, ArgList)))))) # If expressions fn main() { if n == 1 { } else if n == 2 { } else { } } let y = if x == 5 { 10 } else { 15 }; ==> SourceFile( FunctionItem(fn, BoundIdentifier, ParamList, Block( ExpressionStatement(IfExpression(if, BinaryExpression( Identifier, CompareOp, Integer), Block, else, IfExpression(if, BinaryExpression( Identifier, CompareOp, Integer), Block, else, Block))))), LetDeclaration(let, BoundIdentifier, IfExpression(if, BinaryExpression( Identifier, CompareOp, Integer), Block(ExpressionStatement(Integer)), else, Block(ExpressionStatement(Integer))))) # If let expressions if let ("Bacon", b) = dish { } ==> SourceFile( ExpressionStatement(IfExpression(if, LetDeclaration(let, TuplePattern(LiteralPattern(String), BoundIdentifier), Identifier), Block))) # While let expressions while let ("Bacon", b) = dish { } ==> SourceFile( ExpressionStatement(WhileExpression(while, LetDeclaration(let, TuplePattern(LiteralPattern(String), BoundIdentifier), Identifier), Block))) # Match expressions match x { 1 => { "one" } 2 => "two", -1 => 1, -3.14 => 3, #[attr1] 3 => "three", macro!(4) => "four", _ => "something else", } let msg = match x { 0 | 1 | 10 => "one of zero, one, or ten", y if y < 20 => "less than 20, but not zero, one, or ten", y if y == 200 => if a { "200 (but this is not very stylish)" } _ => "something else", }; ==> SourceFile( ExpressionStatement(MatchExpression(match, Identifier, MatchBlock( MatchArm( LiteralPattern(Integer), Block( ExpressionStatement(String))), MatchArm( LiteralPattern(Integer), String), MatchArm( LiteralPattern(ArithOp, Integer), Integer), MatchArm( LiteralPattern(ArithOp, Float), Integer), MatchArm( Attribute( MetaItem( Identifier)), LiteralPattern(Integer), String), MatchArm( MacroPattern( Identifier, ParenthesizedTokens( Integer)), String), MatchArm(_, String)))), LetDeclaration(let, BoundIdentifier, MatchExpression(match, Identifier, MatchBlock( MatchArm( OrPattern(OrPattern(LiteralPattern(Integer), LiteralPattern(Integer)), LiteralPattern(Integer)), String), MatchArm( BoundIdentifier, Guard(if, BinaryExpression( Identifier, CompareOp, Integer)), String), MatchArm( BoundIdentifier, Guard(if, BinaryExpression( Identifier, CompareOp, Integer)), IfExpression(if, Identifier, Block( ExpressionStatement(String)))), MatchArm( _, String))))) # While expressions while !done { done = true; } ==> SourceFile( ExpressionStatement(WhileExpression(while, UnaryExpression(LogicOp, Identifier), Block( ExpressionStatement(AssignmentExpression( Identifier, Boolean)))))) # Loop expressions 'outer: loop { 'inner: loop { break 'outer; break true; } } ==> SourceFile( ExpressionStatement(LoopExpression(LoopLabel, loop, Block( ExpressionStatement(LoopExpression(LoopLabel, loop, Block( ExpressionStatement(BreakExpression(break,LoopLabel)), ExpressionStatement(BreakExpression(break,Boolean))))))))) # For expressions for e in v { bar(e); } for i in 0..256 { bar(i); } 'outer: for x in 0..10 { 'inner: for y in 0..10 { if x % 2 == 0 { continue 'outer; } if y % 2 == 0 { continue 'inner; } } } ==> SourceFile( ExpressionStatement(ForExpression(for,BoundIdentifier, in, Identifier, Block( ExpressionStatement(CallExpression(Identifier, ArgList(Identifier)))))), ExpressionStatement(ForExpression(for,BoundIdentifier, in, RangeExpression(Integer, Integer), Block( ExpressionStatement(CallExpression(Identifier, ArgList(Identifier)))))), ExpressionStatement(ForExpression(LoopLabel, for, BoundIdentifier, in, RangeExpression(Integer, Integer), Block( ExpressionStatement(ForExpression(LoopLabel, for, BoundIdentifier, in, RangeExpression(Integer, Integer), Block( ExpressionStatement(IfExpression(if,BinaryExpression(BinaryExpression(Identifier, ArithOp, Integer), CompareOp, Integer), Block(ExpressionStatement(ContinueExpression(continue,LoopLabel))))), ExpressionStatement(IfExpression(if,BinaryExpression(BinaryExpression(Identifier, ArithOp, Integer), CompareOp, Integer), Block(ExpressionStatement(ContinueExpression(continue,LoopLabel)))))))))))) # Field expressions mystruct.myfield; foo().x; value.0.1.iter(); 1.max(2); ==> SourceFile( ExpressionStatement(FieldExpression(Identifier, FieldIdentifier)), ExpressionStatement(FieldExpression(CallExpression(Identifier, ArgList), FieldIdentifier)), ExpressionStatement(CallExpression( FieldExpression( FieldExpression(FieldExpression(Identifier, Integer), Integer), FieldIdentifier), ArgList)), ExpressionStatement(CallExpression( FieldExpression(Integer, FieldIdentifier), ArgList(Integer)))) # Method call expressions mystruct.foo(); ==> SourceFile(ExpressionStatement(CallExpression(FieldExpression(Identifier, FieldIdentifier), ArgList))) # Index expressions ([1, 2, 3, 4])[0]; arr[10]; arr[n]; ==> SourceFile( ExpressionStatement(IndexExpression( ParenthesizedExpression( ArrayExpression(Integer, Integer, Integer, Integer)), Integer)), ExpressionStatement(IndexExpression(Identifier, Integer)), ExpressionStatement(IndexExpression(Identifier, Identifier))) # Scoped functions a::b(); C::::e(); ::f(); ::g::h(); ==> SourceFile( ExpressionStatement(CallExpression( ScopedIdentifier(ScopeIdentifier, Identifier), ArgList)), ExpressionStatement(CallExpression( ScopedIdentifier( ScopeIdentifier, TypeArgList(TypeIdentifier), Identifier), ArgList)), ExpressionStatement(CallExpression(ScopedIdentifier(Identifier), ArgList)), ExpressionStatement(CallExpression(ScopedIdentifier(ScopeIdentifier, Identifier), ArgList))) # Scoped functions with fully qualified syntax ::eat(d); ==> SourceFile( ExpressionStatement(CallExpression( ScopedIdentifier( QualifiedScope(TypeIdentifier, as, TypeIdentifier), Identifier), ArgList(Identifier)))) # Scoped functions with macros as types ::foo(); ==> SourceFile( ExpressionStatement(CallExpression( ScopedIdentifier( QualifiedScope(MacroInvocation(TypeIdentifier, BracketedTokens)), Identifier), ArgList))) # Generic functions std::sizeof::(); foo::<8>(); ==> SourceFile( ExpressionStatement(CallExpression( GenericFunction( ScopedIdentifier( ScopeIdentifier, Identifier), TypeArgList( TypeIdentifier)), ArgList)), ExpressionStatement(CallExpression( GenericFunction( Identifier, TypeArgList( Integer)), ArgList))) # Closures a.map(|(b, c)| b.push(c)); d.map(move |mut e| { f(e); g(e) }); h(|| -> i { j }); ==> SourceFile( ExpressionStatement(CallExpression( FieldExpression(Identifier, FieldIdentifier), ArgList( ClosureExpression( ParamList(Parameter(TuplePattern(BoundIdentifier, BoundIdentifier))), CallExpression( FieldExpression(Identifier, FieldIdentifier), ArgList(Identifier)))))), ExpressionStatement(CallExpression( FieldExpression(Identifier, FieldIdentifier), ArgList( ClosureExpression(move, ParamList(Parameter(mut, BoundIdentifier)), Block( ExpressionStatement(CallExpression(Identifier, ArgList(Identifier))), ExpressionStatement(CallExpression(Identifier, ArgList(Identifier)))))))), ExpressionStatement(CallExpression( Identifier, ArgList( ClosureExpression( ParamList, TypeIdentifier, Block(ExpressionStatement(Identifier))))))) # Closures with typed parameteres a.map(|b: usize| b.push(c)); ==> SourceFile( ExpressionStatement(CallExpression( FieldExpression(Identifier, FieldIdentifier), ArgList(ClosureExpression( ParamList(Parameter(BoundIdentifier, TypeIdentifier)), CallExpression(FieldExpression(Identifier, FieldIdentifier), ArgList(Identifier))))))) # Unsafe blocks const a : A = unsafe { foo() }; ==> SourceFile( ConstItem(const, BoundIdentifier, TypeIdentifier, UnsafeBlock(unsafe, Block(ExpressionStatement(CallExpression(Identifier, ArgList))))))