================================================================================
Call expressions
================================================================================

class C {
  def main() {
    a()
    a(
      123,
      234,
    )
    ::(123)
    a(b, c)
    a.map(x => x + 1)
    a { 123 }
    a { b }
    a.map{ x => x + 1 }
    /* comment */ a.exists { case ((i, _)) => i }
  }
}

--------------------------------------------------------------------------------

(compilation_unit
  (class_definition
    (identifier)
    (template_body
      (function_definition
        (identifier)
        (parameters)
        (block
          (call_expression
            (identifier)
            (arguments))
          (call_expression
            (identifier)
            (arguments
              (integer_literal)
              (integer_literal)))
          (call_expression
            (operator_identifier)
            (arguments
              (integer_literal)))
          (call_expression
            (identifier)
            (arguments
              (identifier)
              (identifier)))
          (call_expression
            (field_expression
              (identifier)
              (identifier))
            (arguments
              (lambda_expression
                (identifier)
                (infix_expression
                  (identifier)
                  (operator_identifier)
                  (integer_literal)))))
          (call_expression
            (identifier)
            (block
              (integer_literal)))
          (call_expression
            (identifier)
            (block
              (identifier)))
          (call_expression
            (field_expression
              (identifier)
              (identifier))
            (block
              (lambda_expression
                (identifier)
                (infix_expression
                  (identifier)
                  (operator_identifier)
                  (integer_literal)))))
          (block_comment)
          (call_expression
            (field_expression
              (identifier)
              (identifier))
            (case_block
              (case_clause
                (tuple_pattern
                  (tuple_pattern
                    (identifier)
                    (wildcard)))
                (identifier)))))))))

================================================================================
Call expressions (Scala 3 syntax)
================================================================================

class C {
  a(b, c)(using A.B)

  foo(new A:
    def a = new B:
      def b = 1)
}

--------------------------------------------------------------------------------

(compilation_unit
  (class_definition
    (identifier)
    (template_body
      (call_expression
        (call_expression
          (identifier)
          (arguments
            (identifier)
            (identifier)))
        (arguments
          (field_expression
            (identifier)
            (identifier))))
      (call_expression
        (identifier)
        (arguments
          (instance_expression
            (type_identifier)
            (template_body
              (function_definition
                (identifier)
                (instance_expression
                  (type_identifier)
                  (template_body
                    (function_definition
                      (identifier)
                      (integer_literal))))))))))))

================================================================================
SIP-44 Fewer braces (Scala 3 syntax)
================================================================================

class C:
  xs.map: x =>
    x + 1

  xs.map:
    x =>
      x + 1

  xs:
    println("")

  xs `++`:
    val x = 1
    List(x)

  xs.map:
    case x => x

  // This is ascription
  xs: Int
  // This is call_expression
  xs:
    Int

--------------------------------------------------------------------------------

(compilation_unit
  (class_definition
    (identifier)
    (template_body
      (call_expression
        (field_expression
          (identifier)
          (identifier))
        (colon_argument
          (identifier)
          (indented_block
            (infix_expression
              (identifier)
              (operator_identifier)
              (integer_literal)))))
      (call_expression
        (field_expression
          (identifier)
          (identifier))
        (colon_argument
          (indented_block
            (lambda_expression
              (identifier)
              (indented_block
                (infix_expression
                  (identifier)
                  (operator_identifier)
                  (integer_literal)))))))
      (call_expression
        (identifier)
        (colon_argument
          (indented_block
            (call_expression
              (identifier)
              (arguments
                (string))))))
      (infix_expression
        (identifier)
        (identifier)
        (colon_argument
          (indented_block
            (val_definition
              (identifier)
              (integer_literal))
            (call_expression
              (identifier)
              (arguments
                (identifier))))))
      (call_expression
        (field_expression
          (identifier)
          (identifier))
        (colon_argument
          (indented_cases
            (case_clause
              (identifier)
              (identifier))
            (comment))))
      (ascription_expression
        (identifier)
        (type_identifier))
      (comment)
      (call_expression
        (identifier)
        (colon_argument
          (indented_block
            (identifier)))))))

================================================================================
Generic functions
================================================================================

class C {
  def main() {
    a[
      A1,
      A2,
    ]()
    List[Traversable[ClassPath]]()
  }
}

--------------------------------------------------------------------------------

(compilation_unit
  (class_definition
    (identifier)
    (template_body
      (function_definition
        (identifier)
        (parameters)
        (block
          (call_expression
            (generic_function
              (identifier)
              (type_arguments
                (type_identifier)
                (type_identifier)))
            (arguments))
          (call_expression
            (generic_function
              (identifier)
              (type_arguments
                (generic_type
                  (type_identifier)
                  (type_arguments
                    (type_identifier)))))
            (arguments)))))))

================================================================================
Assignments
================================================================================

class C {
  def main() {
    a = b
    a(1) = c
  }
}

--------------------------------------------------------------------------------

(compilation_unit
  (class_definition
    (identifier)
    (template_body
      (function_definition
        (identifier)
        (parameters)
        (block
          (assignment_expression
            (identifier)
            (identifier))
          (assignment_expression
            (call_expression
              (identifier)
              (arguments
                (integer_literal)))
            (identifier)))))))

================================================================================
If expressions
================================================================================

class C {
  def main() {
    if (a) b()
    if (c) {
      d()
      e()
    } else if (f) {
      g()
    } else {
      h()
    }
  }
}

def other() {
  if (a) {
    b
  };
  else c()
}

def another() {
  if (a) b match {
    case _ => c
  } else d
}

--------------------------------------------------------------------------------

(compilation_unit
  (class_definition
    (identifier)
    (template_body
      (function_definition
        (identifier)
        (parameters)
        (block
          (if_expression
            (parenthesized_expression
              (identifier))
            (call_expression
              (identifier)
              (arguments)))
          (if_expression
            (parenthesized_expression
              (identifier))
            (block
              (call_expression
                (identifier)
                (arguments))
              (call_expression
                (identifier)
                (arguments)))
            (if_expression
              (parenthesized_expression
                (identifier))
              (block
                (call_expression
                  (identifier)
                  (arguments)))
              (block
                (call_expression
                  (identifier)
                  (arguments)))))))))
  (function_definition
    (identifier)
    (parameters)
    (block
      (if_expression
        (parenthesized_expression
          (identifier))
        (block
          (identifier))
        (call_expression
          (identifier)
          (arguments)))))
  (function_definition
    (identifier)
    (parameters)
    (block
      (if_expression
        (parenthesized_expression
          (identifier))
        (match_expression
          (identifier)
          (case_block
            (case_clause
              (wildcard)
              (identifier))))
        (identifier)))))

================================================================================
If expressions (Scala 3 syntax)
================================================================================

class C:
  def main() =
    if a then b()
    end if

    if
      val c = false
      c
    then
      d()
      1
    else if f then
      g()
    else
      h()

    if true then
      ()

    // comment
    else
      ()

    if (a) || b(c) then return true

    if (a) && b.c then
      ()

--------------------------------------------------------------------------------

(compilation_unit
  (class_definition
    (identifier)
    (template_body
      (function_definition
        (identifier)
        (parameters)
        (indented_block
          (if_expression
            (identifier)
            (call_expression
              (identifier)
              (arguments)))
          (if_expression
            (indented_block
              (val_definition
                (identifier)
                (boolean_literal))
              (identifier))
            (indented_block
              (call_expression
                (identifier)
                (arguments))
              (integer_literal))
            (if_expression
              (identifier)
              (indented_block
                (call_expression
                  (identifier)
                  (arguments)))
              (indented_block
                (call_expression
                  (identifier)
                  (arguments)))))
          (if_expression
            (boolean_literal)
            (indented_block
              (unit)
              (comment))
            (indented_block
              (unit)))
          (if_expression
            (infix_expression
              (parenthesized_expression
                (identifier))
              (operator_identifier)
              (call_expression
                (identifier)
                (arguments
                  (identifier))))
            (return_expression
              (boolean_literal)))
          (if_expression
            (infix_expression
              (parenthesized_expression
                (identifier))
              (operator_identifier)
              (field_expression
                (identifier)
                (identifier)))
            (indented_block
              (unit))))))))

================================================================================
Try expressions
================================================================================

def main() {
  try a() finally depth -= 1
  try {
    doThing()
  } catch {
    case e: SomeException => prinlnt(e.message)
    case NonFatal(ex) => throw new SomeException(ex)
  } finally {
    tryAnotherThing()
  }
  try b()
  catch { case e => println(e) }
  finally doFinalThing()
  try a()
  finally b()
}

--------------------------------------------------------------------------------

(compilation_unit
  (function_definition
    (identifier)
    (parameters)
    (block
      (try_expression
        (call_expression
          (identifier)
          (arguments))
        (finally_clause
          (infix_expression
            (identifier)
            (operator_identifier)
            (integer_literal))))
      (try_expression
        (block
          (call_expression
            (identifier)
            (arguments)))
        (catch_clause
          (case_block
            (case_clause
              (typed_pattern
                (identifier)
                (type_identifier))
              (call_expression
                (identifier)
                (arguments
                  (field_expression
                    (identifier)
                    (identifier)))))
            (case_clause
              (case_class_pattern
                (type_identifier)
                (identifier))
              (throw_expression
                (instance_expression
                  (type_identifier)
                  (arguments
                    (identifier)))))))
        (finally_clause
          (block
            (call_expression
              (identifier)
              (arguments)))))
      (try_expression
        (call_expression
          (identifier)
          (arguments))
        (catch_clause
          (case_block
            (case_clause
              (identifier)
              (call_expression
                (identifier)
                (arguments
                  (identifier))))))
        (finally_clause
          (call_expression
            (identifier)
            (arguments))))
      (try_expression
        (call_expression
          (identifier)
          (arguments))
        (finally_clause
          (call_expression
            (identifier)
            (arguments)))))))

================================================================================
Try expressions (Scala 3 syntax)
================================================================================

def main(): Unit =
  try a() finally depth -= 1

  try
    a()
    b()
  catch
    case e: SomeException => prinlnt(e.message)
    case NonFatal(ex)     => throw new SomeException(ex)
  finally
    tryAnotherThing()
    tryAnotherThing2()
  try a catch case b: C => e finally f
  try a catch case b: C =>
    e

--------------------------------------------------------------------------------

(compilation_unit
  (function_definition
    (identifier)
    (parameters)
    (type_identifier)
    (indented_block
      (try_expression
        (call_expression
          (identifier)
          (arguments))
        (finally_clause
          (infix_expression
            (identifier)
            (operator_identifier)
            (integer_literal))))
      (try_expression
        (indented_block
          (call_expression
            (identifier)
            (arguments))
          (call_expression
            (identifier)
            (arguments)))
        (catch_clause
          (indented_cases
            (case_clause
              (typed_pattern
                (identifier)
                (type_identifier))
              (call_expression
                (identifier)
                (arguments
                  (field_expression
                    (identifier)
                    (identifier)))))
            (case_clause
              (case_class_pattern
                (type_identifier)
                (identifier))
              (throw_expression
                (instance_expression
                  (type_identifier)
                  (arguments
                    (identifier)))))))
        (finally_clause
          (indented_block
            (call_expression
              (identifier)
              (arguments))
            (call_expression
              (identifier)
              (arguments)))))
      (try_expression
        (identifier)
        (catch_clause
          (typed_pattern
            (identifier)
            (type_identifier))
          (identifier))
        (finally_clause
          (identifier)))
      (try_expression
        (identifier)
        (catch_clause
          (typed_pattern
            (identifier)
            (type_identifier))
          (identifier))))))

================================================================================
Match expressions
================================================================================

def matchTest(x: Int): String = x match {
  case 0 =>
  case 1 => "one"; "uno"
  case 2 => "two"
  case 3 => {
    "3"
  }
  case 4 => 
    ;
  case A if a == 1 =>
  case A if a == 2 => 2
  case ((i, _)) => i
  case s"$l1 -- $l2" => 
    l1 + l2
  case _ =>
    val x = "many"
    "more"
  case a if b => c
}

--------------------------------------------------------------------------------

(compilation_unit
  (function_definition
    (identifier)
    (parameters
      (parameter
        (identifier)
        (type_identifier)))
    (type_identifier)
    (match_expression
      (identifier)
      (case_block
        (case_clause
          (integer_literal))
        (case_clause
          (integer_literal)
          (string)
          (string))
        (case_clause
          (integer_literal)
          (string))
        (case_clause
          (integer_literal)
          (block
            (string)))
        (case_clause
          (integer_literal))
        (case_clause
          (identifier)
          (guard
            (infix_expression
              (identifier)
              (operator_identifier)
              (integer_literal))))
        (case_clause
          (identifier)
          (guard
            (infix_expression
              (identifier)
              (operator_identifier)
              (integer_literal)))
          (integer_literal))
        (case_clause
          (tuple_pattern
            (tuple_pattern
              (identifier)
              (wildcard)))
          (identifier))
        (case_clause
          (interpolated_string_expression
            (identifier)
            (interpolated_string
              (interpolation
                (identifier))
              (interpolation
                (identifier))))
          (infix_expression
            (identifier)
            (operator_identifier)
            (identifier)))
        (case_clause
          (wildcard)
          (val_definition
            (identifier)
            (string))
          (string))
        (case_clause
          (identifier)
          (guard
            (identifier))
          (identifier))))))

================================================================================
Match expressions (Scala 3 syntax)
================================================================================

def matchTest(x: Int): String =
  x match
    case 0 =>
    case 1 => "one"; "uno"
    case 2 => "two"
    case x if x == 3 =>
      val x = "3"
      x
    case ((i, _)) => i
    case _ =>
      val x = "many"
      "more"

--------------------------------------------------------------------------------

(compilation_unit
  (function_definition
    (identifier)
    (parameters
      (parameter
        (identifier)
        (type_identifier)))
    (type_identifier)
    (indented_block
      (match_expression
        (identifier)
        (indented_cases
          (case_clause
            (integer_literal))
          (case_clause
            (integer_literal)
            (string)
            (string))
          (case_clause
            (integer_literal)
            (string))
          (case_clause
            (identifier)
            (guard
              (infix_expression
                (identifier)
                (operator_identifier)
                (integer_literal)))
            (val_definition
              (identifier)
              (string))
            (identifier))
          (case_clause
            (tuple_pattern
              (tuple_pattern
                (identifier)
                (wildcard)))
            (identifier))
          (case_clause
            (wildcard)
            (val_definition
              (identifier)
              (string))
            (string)))))))

================================================================================
Field expressions
================================================================================

class C {
  def main() {
    a.b = c
    a.b.d
    a
      .b
      // comment1
      /* 
         comment2 
      */
      .c
  }
}

--------------------------------------------------------------------------------

(compilation_unit
  (class_definition
    (identifier)
    (template_body
      (function_definition
        (identifier)
        (parameters)
        (block
          (assignment_expression
            (field_expression
              (identifier)
              (identifier))
            (identifier))
          (field_expression
            (field_expression
              (identifier)
              (identifier))
            (identifier))
          (field_expression
            (field_expression
              (identifier)
              (identifier))
            (comment)
            (block_comment)
            (identifier)))))))

================================================================================
Instance expressions
================================================================================

class C {
  def main() {
    val a = new B
    val c = new D(e, f)
    val e = new E:
      def app = 1
    val f = new:
      def app = 1
    val g = new G {}
    val i = new {
      "ok"
    }
    new Array: Array
  }
}

--------------------------------------------------------------------------------

(compilation_unit
  (class_definition
    (identifier)
    (template_body
      (function_definition
        (identifier)
        (parameters)
        (block
          (val_definition
            (identifier)
            (instance_expression
              (type_identifier)))
          (val_definition
            (identifier)
            (instance_expression
              (type_identifier)
              (arguments
                (identifier)
                (identifier))))
          (val_definition
            (identifier)
            (instance_expression
              (type_identifier)
              (template_body
                (function_definition
                  (identifier)
                  (integer_literal)))))
          (val_definition
            (identifier)
            (instance_expression
              (template_body
                (function_definition
                  (identifier)
                  (integer_literal)))))
          (val_definition
            (identifier)
            (instance_expression
              (type_identifier)
              (template_body)))
          (val_definition
            (identifier)
            (instance_expression
              (template_body
                (string))))
          (ascription_expression
            (instance_expression
              (type_identifier))
            (type_identifier)))))))

================================================================================
Infix expressions
================================================================================

class C {
  def main() {
    a = b max c
    d + e + f
    a ** b
  }
}

--------------------------------------------------------------------------------

(compilation_unit
  (class_definition
    (identifier)
    (template_body
      (function_definition
        (identifier)
        (parameters)
        (block
          (assignment_expression
            (identifier)
            (infix_expression
              (identifier)
              (identifier)
              (identifier)))
          (infix_expression
            (infix_expression
              (identifier)
              (operator_identifier)
              (identifier))
            (operator_identifier)
            (identifier))
          (infix_expression
            (identifier)
            (operator_identifier)
            (identifier)))))))

================================================================================
Prefix expressions
================================================================================

class C {
  def main() {
    !a
    +a + b
  }
}

--------------------------------------------------------------------------------

(compilation_unit
  (class_definition
    (identifier)
    (template_body
      (function_definition
        (identifier)
        (parameters)
        (block
          (prefix_expression
            (identifier))
          (infix_expression
            (prefix_expression
              (identifier))
            (operator_identifier)
            (identifier)))))))

================================================================================
Postfix expressions
================================================================================

object O {
  val v = "value" toUpperCase
  val c = 1 + 2 toString
}

--------------------------------------------------------------------------------

(compilation_unit
  (object_definition
    (identifier)
    (template_body
      (val_definition
        (identifier)
        (postfix_expression
          (string)
          (identifier)))
      (val_definition
        (identifier)
        (postfix_expression
          (infix_expression
            (integer_literal)
            (operator_identifier)
            (integer_literal))
          (identifier))))))

================================================================================
Ascription Expression
================================================================================

object O {
  val l = a: List
  val x = 2: Byte
  Nil: List[String]
  3: _*
  x: @unchecked
}

--------------------------------------------------------------------------------

(compilation_unit
  (object_definition
    (identifier)
    (template_body
      (val_definition
        (identifier)
        (ascription_expression
          (identifier)
          (type_identifier)))
      (val_definition
        (identifier)
        (ascription_expression
          (integer_literal)
          (type_identifier)))
      (ascription_expression
        (identifier)
        (generic_type
          (type_identifier)
          (type_arguments
            (type_identifier))))
      (ascription_expression
        (integer_literal)
        (repeated_parameter_type
          (wildcard)))
      (ascription_expression
        (identifier)
        (annotation
          (type_identifier))))))

================================================================================
Lambda Expression
================================================================================

object O {
  val l = a => a + 1
  val b = (x: Int, y: Int) => { x * y }
  val f = _ => 2
  foo { i => 
    val x = 2 + i 
    x
  }
  { x => 
    val y = 2 * x
    y * y
  }
  { b =>
   if (c) d.e }
  { a => implicit b => b }
  { (a: Int) ?=> (b: Int) => b }
  { (_, a) => a }
}

--------------------------------------------------------------------------------

(compilation_unit
  (object_definition
    (identifier)
    (template_body
      (val_definition
        (identifier)
        (lambda_expression
          (identifier)
          (infix_expression
            (identifier)
            (operator_identifier)
            (integer_literal))))
      (val_definition
        (identifier)
        (lambda_expression
          (bindings
            (binding
              (identifier)
              (type_identifier))
            (binding
              (identifier)
              (type_identifier)))
          (block
            (infix_expression
              (identifier)
              (operator_identifier)
              (identifier)))))
      (val_definition
        (identifier)
        (lambda_expression
          (wildcard)
          (integer_literal)))
      (call_expression
        (identifier)
        (block
          (lambda_expression
            (identifier)
            (indented_block
              (val_definition
                (identifier)
                (infix_expression
                  (integer_literal)
                  (operator_identifier)
                  (identifier)))
              (identifier)))))
      (block
        (lambda_expression
          (identifier)
          (indented_block
            (val_definition
              (identifier)
              (infix_expression
                (integer_literal)
                (operator_identifier)
                (identifier)))
            (infix_expression
              (identifier)
              (operator_identifier)
              (identifier)))))
      (block
        (lambda_expression
          (identifier)
          (indented_block
            (if_expression
              (parenthesized_expression
                (identifier))
              (field_expression
                (identifier)
                (identifier))))))
      (block
        (lambda_expression
          (identifier)
          (lambda_expression
            (identifier)
            (identifier))))
      (block
        (lambda_expression
          (bindings
            (binding
              (identifier)
              (type_identifier)))
          (lambda_expression
            (bindings
              (binding
                (identifier)
                (type_identifier)))
            (identifier))))
      (block
        (lambda_expression
          (bindings
            (binding
              (wildcard))
            (binding
              (identifier)))
          (identifier))))))

================================================================================
Unit expressions
================================================================================

val x = ()
def f(): Unit = { (   
); }

--------------------------------------------------------------------------------

(compilation_unit
  (val_definition
    (identifier)
    (unit))
  (function_definition
    (identifier)
    (parameters)
    (type_identifier)
    (block
      (unit))))

================================================================================
Return expressions
================================================================================

def f: Unit = return
def g(a: A): B = { f(); return null.asInstanceOf[B] }

--------------------------------------------------------------------------------

(compilation_unit
  (function_definition
    (identifier)
    (type_identifier)
    (return_expression))
  (function_definition
    (identifier)
    (parameters
      (parameter
        (identifier)
        (type_identifier)))
    (type_identifier)
    (block
      (call_expression
        (identifier)
        (arguments))
      (return_expression
        (generic_function
          (field_expression
            (null_literal)
            (identifier))
          (type_arguments
            (type_identifier)))))))

================================================================================
While loops
================================================================================

def f = {
  while (a) g()
  while (b < c) {
    d
  }
}

--------------------------------------------------------------------------------

(compilation_unit
  (function_definition
    (identifier)
    (block
      (while_expression
        (parenthesized_expression
          (identifier))
        (call_expression
          (identifier)
          (arguments)))
      (while_expression
        (parenthesized_expression
          (infix_expression
            (identifier)
            (operator_identifier)
            (identifier)))
        (block
          (identifier))))))

================================================================================
While loops (Scala 3 syntax)
================================================================================

def f: Unit =
  while a do g()

  while
    val x = 1
    b < x
  do
    ()

--------------------------------------------------------------------------------

(compilation_unit
  (function_definition
    (identifier)
    (type_identifier)
    (indented_block
      (while_expression
        (identifier)
        (call_expression
          (identifier)
          (arguments)))
      (while_expression
        (indented_block
          (val_definition
            (identifier)
            (integer_literal))
          (infix_expression
            (identifier)
            (operator_identifier)
            (identifier)))
        (indented_block
          (unit))))))

================================================================================
Do-while loops
================================================================================

def f() = {
  do g(a, b) while(c && d)
  do {
    g(a, b)
    h(a, b)
  } while (c < d)
}

--------------------------------------------------------------------------------

(compilation_unit
  (function_definition
    (identifier)
    (parameters)
    (block
      (do_while_expression
        (call_expression
          (identifier)
          (arguments
            (identifier)
            (identifier)))
        (parenthesized_expression
          (infix_expression
            (identifier)
            (operator_identifier)
            (identifier))))
      (do_while_expression
        (block
          (call_expression
            (identifier)
            (arguments
              (identifier)
              (identifier)))
          (call_expression
            (identifier)
            (arguments
              (identifier)
              (identifier))))
        (parenthesized_expression
          (infix_expression
            (identifier)
            (operator_identifier)
            (identifier)))))))

================================================================================
For comprehensions
================================================================================

def f() = {
  for (n <- nums) yield n + 1
  for (x <- xs; y <- ys) g(x, y)
  for {
    x <- xs
    a = b + c
    y <- g() if d
    (t, u) = y
  } yield {
    h(x, y)
  }
}

--------------------------------------------------------------------------------

(compilation_unit
  (function_definition
    (identifier)
    (parameters)
    (block
      (for_expression
        (enumerators
          (enumerator
            (identifier)
            (identifier)))
        (infix_expression
          (identifier)
          (operator_identifier)
          (integer_literal)))
      (for_expression
        (enumerators
          (enumerator
            (identifier)
            (identifier))
          (enumerator
            (identifier)
            (identifier)))
        (call_expression
          (identifier)
          (arguments
            (identifier)
            (identifier))))
      (for_expression
        (enumerators
          (enumerator
            (identifier)
            (identifier))
          (enumerator
            (identifier)
            (infix_expression
              (identifier)
              (operator_identifier)
              (identifier)))
          (enumerator
            (identifier)
            (call_expression
              (identifier)
              (arguments))
            (guard
              (identifier)))
          (enumerator
            (tuple_pattern
              (identifier)
              (identifier))
            (identifier)))
        (block
          (call_expression
            (identifier)
            (arguments
              (identifier)
              (identifier))))))))

================================================================================
For comprehensions (Scala 3 syntax)
================================================================================

def f(): Unit =
  for n <- nums yield n + 1

  for
    x <- xs
    y <- ys
  yield
    g(x, y)

  for
    annot <- annotations
    if shouldEmitAnnotation(annot)
  do
    ()
--------------------------------------------------------------------------------

(compilation_unit
  (function_definition
    (identifier)
    (parameters)
    (type_identifier)
    (indented_block
      (for_expression
        (enumerators
          (enumerator
            (identifier)
            (identifier)))
        (infix_expression
          (identifier)
          (operator_identifier)
          (integer_literal)))
      (for_expression
        (enumerators
          (enumerator
            (identifier)
            (identifier))
          (enumerator
            (identifier)
            (identifier)))
        (indented_block
          (call_expression
            (identifier)
            (arguments
              (identifier)
              (identifier)))))
      (for_expression
        (enumerators
          (enumerator
            (identifier)
            (identifier))
          (enumerator
            (guard
              (call_expression
                (identifier)
                (arguments
                  (identifier))))))
        (indented_block
          (unit))))))

================================================================================
Chained expressions
================================================================================

def main() {
  val myList = List(1, 2, 3)

  myList.map(_ * 2)

  myList
    .map(_ * 2)

  myList
    .length
}

--------------------------------------------------------------------------------

(compilation_unit
  (function_definition
    (identifier)
    (parameters)
    (block
      (val_definition
        (identifier)
        (call_expression
          (identifier)
          (arguments
            (integer_literal)
            (integer_literal)
            (integer_literal))))
      (call_expression
        (field_expression
          (identifier)
          (identifier))
        (arguments
          (infix_expression
            (wildcard)
            (operator_identifier)
            (integer_literal))))
      (call_expression
        (field_expression
          (identifier)
          (identifier))
        (arguments
          (infix_expression
            (wildcard)
            (operator_identifier)
            (integer_literal))))
      (field_expression
        (identifier)
        (identifier)))))

================================================================================
Macros (Scala 2 syntax)
================================================================================

class Foo {
  def a: A =
    macro B.b
}

--------------------------------------------------------------------------------

(compilation_unit
  (class_definition
    (identifier)
    (template_body
      (function_definition
        (identifier)
        (type_identifier)
        (indented_block
          (macro_body
            (field_expression
              (identifier)
              (identifier))))))))

================================================================================
Macros (Scala 3 syntax)
================================================================================

class A:
  inline def inspect(inline a: Any): Any =
    ${ inspectCode('a) }

  def foo =
    '{ $b }

--------------------------------------------------------------------------------

(compilation_unit
  (class_definition
    (identifier)
    (template_body
      (function_definition
        (modifiers
          (inline_modifier))
        (identifier)
        (parameters
          (parameter
            (inline_modifier)
            (identifier)
            (type_identifier)))
        (type_identifier)
        (indented_block
          (splice_expression
            (call_expression
              (identifier)
              (arguments
                (quote_expression
                  (identifier)))))))
      (function_definition
        (identifier)
        (indented_block
          (quote_expression
            (identifier)))))))

================================================================================
Inline matches (Scala 3)
================================================================================

def hello = 
  inline c match {
    case 1 => 
  }

--------------------------------------------------------------------------------

(compilation_unit
  (function_definition
    (identifier)
    (indented_block
      (match_expression
        (inline_modifier)
        (identifier)
        (case_block
          (case_clause
            (integer_literal)))))))

================================================================================
Inline if (Scala 3)
================================================================================

def hello =
  inline if (x) {} else {}

--------------------------------------------------------------------------------

(compilation_unit
  (function_definition
    (identifier)
    (indented_block
      (if_expression
        (inline_modifier)
        (parenthesized_expression
          (identifier))
        (block)
        (block)))))

================================================================================
Nested inline if and match (Scala 3)
================================================================================

def hello =
  inline if (x) {
    inline x match {

    }
  }

--------------------------------------------------------------------------------

(compilation_unit
  (function_definition
    (identifier)
    (indented_block
      (if_expression
        (inline_modifier)
        (parenthesized_expression
          (identifier))
        (block
          (match_expression
            (inline_modifier)
            (identifier)
            (case_block)))))))

================================================================================
Top-level expressions
================================================================================

var greeting = "Good bye"
greeting = "Hello"
val message = greeting + " from Scala script!"

if true then
  println(message)

addSbtPlugin("foo" % "bar" % "0.1")

--------------------------------------------------------------------------------

(compilation_unit
  (var_definition
    (identifier)
    (string))
  (assignment_expression
    (identifier)
    (string))
  (val_definition
    (identifier)
    (infix_expression
      (identifier)
      (operator_identifier)
      (string)))
  (if_expression
    (boolean_literal)
    (indented_block
      (call_expression
        (identifier)
        (arguments
          (identifier)))))
  (call_expression
    (identifier)
    (arguments
      (infix_expression
        (infix_expression
          (string)
          (operator_identifier)
          (string))
        (operator_identifier)
        (string)))))

================================================================================
Soft keywords used as identifiers (Scala 3)
================================================================================
infix()
opaque()
open()
transparent()
as()
derives()
end()
throws()
using()

--------------------------------------------------------------------------------

(compilation_unit
  (call_expression
    (identifier)
    (arguments))
  (call_expression
    (identifier)
    (arguments))
  (call_expression
    (identifier)
    (arguments))
  (call_expression
    (identifier)
    (arguments))
  (call_expression
    (identifier)
    (arguments))
  (call_expression
    (identifier)
    (arguments))
  (call_expression
    (identifier)
    (arguments))
  (call_expression
    (identifier)
    (arguments))
  (call_expression
    (identifier)
    (arguments)))
