=====================================
Math Expressions
=====================================

1 + x + 1
0xDEAD * x / 0.01
0xDEAD * (x / 0.01)

---

(source
  (expression_statement
    (binary_operator (binary_operator (integer) (identifier)) (integer)))
  (expression_statement
    (binary_operator (binary_operator (integer) (identifier)) (float)))
  (expression_statement
    (binary_operator (integer) (parenthesized_expression
      (binary_operator (identifier) (float))))))

=====================================
Boolean Operators
=====================================

x and (x && true)
x or (x || true)
not x and (!x)

---

(source
  (expression_statement
    (binary_operator
      (identifier)
      (parenthesized_expression
        (binary_operator
          (identifier)
          (true)))))
  (expression_statement
    (binary_operator
      (identifier)
      (parenthesized_expression
        (binary_operator
          (identifier)
          (true)))))
  (expression_statement
    (binary_operator
      (unary_operator (identifier))
      (parenthesized_expression
        (unary_operator (identifier))))))

=====================================
Is Operator
=====================================

x is y
x is int()
(1 + 1) is Name

---

(source
  (expression_statement (binary_operator (identifier) (identifier)))
  (expression_statement (binary_operator (identifier) (call (identifier) (argument_list))))
  (expression_statement (binary_operator
    (parenthesized_expression
      (binary_operator (integer) (integer)))
    (identifier))))

=====================================
As Operator
=====================================

x as Y
x() as Y

---

(source
  (expression_statement (binary_operator (identifier) (identifier)))
  (expression_statement (binary_operator (call (identifier) (argument_list)) (identifier))))

=====================================
Array
=====================================

[1]
[1, 2]
[1, "a", 2]
[
	1,
]
[,]

---

(source
  (expression_statement (array (integer)))
  (expression_statement (array (integer) (integer)))
  (expression_statement (array (integer) (string) (integer)))
  (expression_statement (array (integer)))
  (expression_statement (array (ERROR)))
  )

=====================================
Dictionary
=====================================

{a = 0.1, c:1, "e":$hello}
{a = 0xBEEF, c:1 + 1, "e":f,}
{(1 + 1) : "a"}
{(1 + 1) = "a"}
{,}

---

(source
  (expression_statement
    (dictionary
      (pair (identifier) (float))
      (pair (identifier) (integer))
      (pair (string) (get_node))))
  (expression_statement
    (dictionary
      (pair (identifier) (integer))
      (pair (identifier) (binary_operator (integer) (integer)))
      (pair (string) (identifier))))
  (expression_statement
    (dictionary
      (pair
        (parenthesized_expression (binary_operator (integer) (integer)))
        (string))))
  (expression_statement
    (dictionary
      (ERROR
        (parenthesized_expression (binary_operator (integer) (integer)))
        (string))))
  (expression_statement
    (dictionary (ERROR))))

=====================================
NodePath
=====================================

@"Node/Path"
@'Node/Path'
@ 'node/path'
var x = @"NodePath"

---

(source
  (expression_statement (node_path))
  (expression_statement (node_path))
  (ERROR (UNEXPECTED ' ')) (expression_statement (string))
  (variable_statement (name) (node_path)))

=====================================
Get Node
=====================================

$node/path
$'node/path'
$"node/path"
$ "node/path"
var x = $"node/path"

---

(source
  (expression_statement (get_node))
  (expression_statement (get_node))
  (expression_statement (get_node))
  (ERROR (UNEXPECTED ' ')) (expression_statement (string))
  (variable_statement (name) (get_node)))

=====================================
Breakpoint Statement
=====================================

breakpoint
breakpoint; hi()

---

(source
  (breakpoint_statement)
  (breakpoint_statement)
  (expression_statement (call (identifier) (argument_list))))

=====================================
Variables
=====================================

var x
var x = "hello"
var x := "hello"
var x: Type
var x: Type = "hello"

---

(source
  (variable_statement (name))
  (variable_statement (name) (string))
  (variable_statement (name) (inferred_type) (string))
  (variable_statement (name) (type))
  (variable_statement (name) (type) (string)))

=====================================
Variable Assign Expressions
=====================================

var x = 1 + x + 1

---

(source
  (variable_statement (name)
      (binary_operator (binary_operator (integer) (identifier)) (integer))))

=====================================
Remote Variables
=====================================

remote var hello
master var hello
puppet var hello
remotesync var hello
mastersync var hello
puppetsync var hello

---

(source
  (variable_statement (remote_keyword) (name))
  (variable_statement (remote_keyword) (name))
  (variable_statement (remote_keyword) (name))
  (variable_statement (remote_keyword) (name))
  (variable_statement (remote_keyword) (name))
  (variable_statement (remote_keyword) (name)))

=====================================
Export Variables
=====================================

export var a
export var a = "a"
export remote var a

export(Type) var a
export(Type) var a = "a"
export(Type) remote var a

export(Type, Param) var a
export(Type, "Param") var a = "a"

export(Type,) var a
export(,) var a

---

(source
  (export_variable_statement (name))
  (export_variable_statement (name) (string))
  (export_variable_statement (remote_keyword) (name))
  (export_variable_statement (export_argument_list (identifier)) (name))
  (export_variable_statement (export_argument_list (identifier)) (name) (string))
  (export_variable_statement (export_argument_list (identifier)) (remote_keyword) (name))
  (export_variable_statement (export_argument_list (identifier) (identifier)) (name))
  (export_variable_statement (export_argument_list (identifier) (string)) (name) (string))
  (export_variable_statement (export_argument_list (identifier)) (name))
  (export_variable_statement (export_argument_list (ERROR)) (name)))

=====================================
SetGet Variables
=====================================

var x setget setter,getter
var x setget setter
var x setget ,getter

---

(source
  (variable_statement (name) (setget (setter) (getter)))
  (variable_statement (name) (setget (setter)))
  (variable_statement (name) (setget (getter)))
)

=====================================
Onready Variables
=====================================

onready var hello
onready var hello: World

---

(source
  (onready_variable_statement (name))
  (onready_variable_statement (name) (type)))

=====================================
Const Variables
=====================================

const CONST = 1
const CONST := 1
const CONST : int = 1

---

(source
  (const_statement (name) (integer))
  (const_statement (name) (inferred_type) (integer))
  (const_statement (name) (type) (integer)))


=====================================
Invalid Variables
=====================================

var x = var y
var x :=

---

(source
  (variable_statement (name) (ERROR (identifier)) (identifier))
  (ERROR (name)  (inferred_type)))

=====================================
Function Definitions
=====================================

func hello():
  pass

func hello() -> Type:
  pass

func hello(param):
  pass

func hello(param) -> Type:
  pass

func hello(default_param="string"):
  pass

func hello(default_param="string") -> Type:
  pass

func hello(typed_param: Type):
  pass

func hello(typed_param: Type) -> Type:
  pass

func hello(typed_default_param: Type="string"):
  pass

func hello(typed_default_param: Type="string") -> Type:
  pass

---

(source
  (function_definition (name) (parameters)
    (body (pass_statement)))
  (function_definition (name) (parameters) (return_type (type))
    (body (pass_statement)))
  (function_definition (name) (parameters (identifier))
    (body (pass_statement)))
  (function_definition (name) (parameters (identifier)) (return_type (type))
    (body (pass_statement)))
  (function_definition (name) (parameters (default_parameter (identifier) (string)))
    (body (pass_statement)))
  (function_definition (name) (parameters (default_parameter (identifier) (string))) (return_type (type))
    (body (pass_statement)))
  (function_definition (name) (parameters (typed_parameter (identifier) (type)))
    (body (pass_statement)))
  (function_definition (name) (parameters (typed_parameter (identifier) (type))) (return_type (type))
    (body (pass_statement)))
  (function_definition (name) (parameters (typed_default_parameter (identifier) (type) (string)))
    (body (pass_statement)))
  (function_definition (name) (parameters (typed_default_parameter (identifier) (type) (string))) (return_type (type))
    (body (pass_statement))))

=====================================
Remote Function Definitions
=====================================

remote func hello(): pass
master func hello(): pass
puppet func hello(): pass
remotesync func hello(): pass
mastersync func hello(): pass
puppetsync func hello(): pass

---

(source
  (function_definition (remote_keyword) (name) (parameters)
    (body (pass_statement)))
  (function_definition (remote_keyword) (name) (parameters)
    (body (pass_statement)))
  (function_definition (remote_keyword) (name) (parameters)
    (body (pass_statement)))
  (function_definition (remote_keyword) (name) (parameters)
    (body (pass_statement)))
  (function_definition (remote_keyword) (name) (parameters)
    (body (pass_statement)))
  (function_definition (remote_keyword) (name) (parameters)
    (body (pass_statement))))

=====================================
Static Function Definitions
=====================================

static func hello(): pass

---

(source
  (function_definition (static_keyword) (name) (parameters)
    (body (pass_statement))))

=====================================
Constructor Definitions
=====================================

func _init(): pass
func _init().(): pass
func _init(a, b).(a,b): pass

---

(source
  (constructor_definition
    (parameters)
    (body (pass_statement)))
  (constructor_definition
    (parameters)
    (argument_list)
    (body (pass_statement)))
  (constructor_definition
    (parameters (identifier) (identifier))
    (argument_list (identifier) (identifier))
    (body (pass_statement))))

=====================================
Base Calls
=====================================

.hello()
var x = .hello()
var x = hello(.hello())

---

(source
  (expression_statement (base_call (identifier) (argument_list)))
  (variable_statement (name) (base_call (identifier) (argument_list)))
  (variable_statement
    (name)
    (call (identifier) (argument_list (base_call (identifier) (argument_list))))))

=====================================
Function Calls
=====================================

hello()
hello(world)
hello("world")
hello(1 + 1, "world")
hello(hello())
hello(hello("world"))

---

(source
  (expression_statement (call (identifier) (argument_list)))
  (expression_statement (call (identifier) (argument_list (identifier))))
  (expression_statement (call (identifier) (argument_list (string))))
  (expression_statement (call (identifier) (argument_list (binary_operator (integer) (integer)) (string))))
  (expression_statement (call (identifier) (argument_list (call (identifier) (argument_list)))))
  (expression_statement (call (identifier) (argument_list (call (identifier) (argument_list (string))))))
)

=====================================
Attribute Accessors
=====================================

x.y
x.y.z
x.y.z()
x.y().z
x().y

x.y[0]
x[0].z
x.y.z[0]
x['s'].y.z[0]

---

(source
  (expression_statement (attribute (identifier) (identifier)))
  (expression_statement (attribute (identifier) (identifier) (identifier)))
  (expression_statement (attribute (identifier) (identifier) (attribute_call (identifier) (argument_list))))
  (expression_statement (attribute (identifier) (attribute_call (identifier) (argument_list)) (identifier)))
  (expression_statement (attribute (call (identifier) (argument_list)) (identifier)))

  (expression_statement (attribute (identifier) (attribute_subscript (identifier) (integer))))
  (expression_statement (attribute (subscript (identifier) (integer)) (identifier)))
  (expression_statement (attribute (identifier) (identifier) (attribute_subscript (identifier) (integer))))
  (expression_statement (attribute (subscript (identifier) (string)) (identifier) (attribute_subscript (identifier) (integer))))
)

=====================================
Match Statements
=====================================

match x:
    1: pass
    _: pass
    TYPE_ARRAY: pass
    var new_var: pass

    []: pass
    [1, 3, "test", null]: pass
    [var start, _]: pass
    [42, ..]: pass

    {}: pass
    {"name": "Dennis"}: pass
    {"name": "Dennis", "age": var age}: pass
    {"key": "godotisawesome", ..}: pass

    1, 2, 3: pass

---

(source
  (match_statement (identifier) (match_body
    (pattern_section (integer) (body (pass_statement)))
    (pattern_section (underscore) (body (pass_statement)))
    (pattern_section (identifier) (body (pass_statement)))
    (pattern_section (pattern_binding (identifier)) (body (pass_statement)))

    (pattern_section (pattern_array) (body (pass_statement)))
    (pattern_section
      (pattern_array (integer) (integer) (string) (null))
      (body (pass_statement)))
    (pattern_section
      (pattern_array (pattern_binding (identifier)) (underscore))
      (body (pass_statement)))
    (pattern_section
      (pattern_array (integer) (pattern_open_ending))
      (body (pass_statement)))

    (pattern_section (pattern_dictionary) (body (pass_statement)))
    (pattern_section
      (pattern_dictionary (pattern_pair (string) (string)))
      (body (pass_statement)))
    (pattern_section
      (pattern_dictionary
        (pattern_pair (string) (string))
        (pattern_pair (string) (pattern_binding (identifier))))
      (body (pass_statement)))
    (pattern_section
      (pattern_dictionary
        (pattern_pair (string) (string))
        (pattern_open_ending))
      (body (pass_statement)))

    (pattern_section
      (integer)
      (integer)
      (integer)
      (body (pass_statement))))))

=====================================
Signal Statements
=====================================

signal x
signal x()
signal x(a, b)

signal x(a,)
signal x(,)

---

(source
  (signal_statement (name))
  (signal_statement (name) (signal_argument_list))
  (signal_statement (name) (signal_argument_list (identifier) (identifier)))
  (signal_statement (name) (signal_argument_list (identifier)))
  (signal_statement (name) (signal_argument_list (ERROR))))

=====================================
Class Name
=====================================

class_name Name
class_name Name, "icon"

---

(source
  (class_name_statement (name))
  (class_name_statement (name) (class_name_icon_path (string))))

=====================================
Tool and Extend
=====================================

tool
extends "class/path"
extends "class/path".Attr
extends "class/path".Attr.Attr
extends Ident
extends Ident.Attr
extends Ident.Attr.Attr

---
(source
  (tool_statement)
  (extends_statement (string))
  (extends_statement (string) (dotted_type (type)))
  (extends_statement (string) (dotted_type (type) (type)))
  (extends_statement (dotted_type (type)))
  (extends_statement (dotted_type (type) (type)))
  (extends_statement (dotted_type (type) (type) (type))))

=====================================
Inner Class
=====================================

class Name:
  func hello(): pass

class Name extends Type:
  func hello(): pass

class Name:
  extends Type

---

(source
  (class_definition (name)
    (body
      (function_definition (name) (parameters)
        (body (pass_statement)))))
  (class_definition (name) (extends_statement (dotted_type (type)))
    (body
      (function_definition (name) (parameters)
        (body (pass_statement)))))
  (class_definition (name)
    (body
      (extends_statement (dotted_type (type))))))

============================================
Enum declarations
============================================

enum Hello {
  val1,
  val2 = 5,
  val3
}

enum {
  val1,
  val2 = 5,
  val3
}

enum A {
  val1 = 1,
}

---

(source
  (enum_definition (name)
    (enumerator_list
      (enumerator (identifier))
      (enumerator (identifier) (integer))
      (enumerator (identifier))))
  (enum_definition
    (enumerator_list
      (enumerator (identifier))
      (enumerator (identifier) (integer))
      (enumerator (identifier))))
  (enum_definition (name)
    (enumerator_list
      (enumerator (identifier) (integer)))))

============================================
Enumerator Expressions
============================================

enum {
  A = 1 + 1,
  B = Hello.World,
  C = (Hello.World | 0xDEADBEEF),
  D = int(true),
  E = const_arr[0],
  F = {one = 1},
}

---

(source
  (enum_definition
    (enumerator_list
      (enumerator (identifier) (binary_operator (integer) (integer)))
      (enumerator (identifier) (attribute (identifier) (identifier)))
      (enumerator (identifier) (parenthesized_expression (binary_operator (attribute (identifier) (identifier)) (integer))))
      (enumerator (identifier) (call (identifier) (argument_list (true))))
      (enumerator (identifier) (subscript (identifier) (integer)))
      (enumerator (identifier)) (ERROR (dictionary (pair (identifier) (integer)))))))
