========================================================================
Arithmetic expressions
========================================================================

codeunit 50100 Test
{
    procedure Foo()
    begin
        x := 1 + 2 * 3;
    end;
}

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

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_keyword)
      (identifier)
      (code_block
        (assignment_statement
          (identifier)
          (additive_expression
            (integer)
            (multiplicative_expression
              (integer)
              (integer))))))))

========================================================================
Division and modulo operators
========================================================================

codeunit 50100 Test
{
    procedure Foo()
    begin
        y := x div 10;
        z := x mod 3;
    end;
}

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

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_keyword)
      (identifier)
      (code_block
        (assignment_statement
          (identifier)
          (multiplicative_expression
            (identifier)
            (integer)))
        (assignment_statement
          (identifier)
          (multiplicative_expression
            (identifier)
            (integer)))))))

========================================================================
Comparison expressions
========================================================================

codeunit 50100 Test
{
    procedure Foo()
    begin
        if x = 0 then
            exit;
        if x <> y then
            exit;
        if x >= 10 then
            exit;
    end;
}

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

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_keyword)
      (identifier)
      (code_block
        (if_statement
          (if_keyword)
          (comparison_expression
            (identifier)
            (comparison_operator)
            (integer))
          (then_keyword)
          (exit_statement
            (exit_keyword)))
        (if_statement
          (if_keyword)
          (comparison_expression
            (identifier)
            (comparison_operator)
            (identifier))
          (then_keyword)
          (exit_statement
            (exit_keyword)))
        (if_statement
          (if_keyword)
          (comparison_expression
            (identifier)
            (comparison_operator)
            (integer))
          (then_keyword)
          (exit_statement
            (exit_keyword)))))))

========================================================================
Logical expressions
========================================================================

codeunit 50100 Test
{
    procedure Foo()
    begin
        if (x > 0) and (y < 10) then
            exit;
        if not Found then
            exit;
    end;
}

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

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_keyword)
      (identifier)
      (code_block
        (if_statement
          (if_keyword)
          (logical_expression
            (parenthesized_expression
              (comparison_expression
                (identifier)
                (comparison_operator)
                (integer)))
            (parenthesized_expression
              (comparison_expression
                (identifier)
                (comparison_operator)
                (integer))))
          (then_keyword)
          (exit_statement
            (exit_keyword)))
        (if_statement
          (if_keyword)
          (unary_expression
            (identifier))
          (then_keyword)
          (exit_statement
            (exit_keyword)))))))

========================================================================
String concatenation
========================================================================

codeunit 50100 Test
{
    procedure Foo()
    begin
        s := 'Hello' + ' ' + 'World';
    end;
}

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

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_keyword)
      (identifier)
      (code_block
        (assignment_statement
          (identifier)
          (additive_expression
            (additive_expression
              (string_literal)
              (string_literal))
            (string_literal)))))))

========================================================================
Member access chain
========================================================================

codeunit 50100 Test
{
    procedure Foo()
    begin
        x := Rec.Name;
        y := Rec."Field Name";
    end;
}

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

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_keyword)
      (identifier)
      (code_block
        (assignment_statement
          (identifier)
          (member_expression
            (identifier)
            (identifier)))
        (assignment_statement
          (identifier)
          (member_expression
            (identifier)
            (quoted_identifier)))))))

========================================================================
Function call with multiple arguments
========================================================================

codeunit 50100 Test
{
    procedure Foo()
    begin
        Message('Hello %1 %2', Name, Age);
    end;
}

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

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_keyword)
      (identifier)
      (code_block
        (call_expression
          (identifier)
          (argument_list
            (string_literal)
            (identifier)
            (identifier)))))))

========================================================================
Subscript expression
========================================================================

codeunit 50100 Test
{
    procedure Foo()
    begin
        x := MyArray[1];
        y := MyArray[i + 1];
    end;
}

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

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_keyword)
      (identifier)
      (code_block
        (assignment_statement
          (identifier)
          (subscript_expression
            (identifier)
            (integer)))
        (assignment_statement
          (identifier)
          (subscript_expression
            (identifier)
            (additive_expression
              (identifier)
              (integer))))))))

========================================================================
Parenthesized expression
========================================================================

codeunit 50100 Test
{
    procedure Foo()
    begin
        x := (a + b) * c;
    end;
}

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

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_keyword)
      (identifier)
      (code_block
        (assignment_statement
          (identifier)
          (multiplicative_expression
            (parenthesized_expression
              (additive_expression
                (identifier)
                (identifier)))
            (identifier)))))))

========================================================================
Qualified enum value
========================================================================

codeunit 50100 Test
{
    procedure Foo()
    begin
        x := Status::Active;
    end;
}

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

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_keyword)
      (identifier)
      (code_block
        (assignment_statement
          (identifier)
          (qualified_enum_value
            (identifier)
            (identifier)))))))

========================================================================
Qualified enum with quoted identifiers
========================================================================

codeunit 50100 Test
{
    procedure Foo()
    begin
        x := "Sales Line Type"::Item;
    end;
}

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

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_keyword)
      (identifier)
      (code_block
        (assignment_statement
          (identifier)
          (qualified_enum_value
            (quoted_identifier)
            (identifier)))))))

========================================================================
In expression
========================================================================

codeunit 50100 Test
{
    procedure Foo()
    begin
        if x in [1, 2, 3] then
            exit;
    end;
}

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

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_keyword)
      (identifier)
      (code_block
        (if_statement
          (if_keyword)
          (identifier)
          (in_keyword)
          (list_literal
            (integer)
            (integer)
            (integer))
          (then_keyword)
          (exit_statement
            (exit_keyword)))))))

========================================================================
Unary negation
========================================================================

codeunit 50100 Test
{
    procedure Foo()
    begin
        x := -y;
        z := +w;
    end;
}

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

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_keyword)
      (identifier)
      (code_block
        (assignment_statement
          (identifier)
          (unary_expression
            (identifier)))
        (assignment_statement
          (identifier)
          (unary_expression
            (identifier)))))))

========================================================================
Range expression
========================================================================

codeunit 50100 Test
{
    procedure Foo()
    begin
        if x in [1..10] then
            exit;
    end;
}

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

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_keyword)
      (identifier)
      (code_block
        (if_statement
          (if_keyword)
          (identifier)
          (in_keyword)
          (list_literal
            (range_expression
              (integer)
              (integer)))
          (then_keyword)
          (exit_statement
            (exit_keyword)))))))

========================================================================
Database reference
========================================================================

codeunit 50100 Test
{
    procedure Foo()
    begin
        x := DATABASE::"Customer";
    end;
}

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

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_keyword)
      (identifier)
      (code_block
        (assignment_statement
          (identifier)
          (database_reference
            (object_type_keyword)
            (quoted_identifier)))))))

========================================================================
Chained method calls
========================================================================

codeunit 50100 Test
{
    procedure Foo()
    begin
        Rec.SetRange("No.", '10000');
        Rec.FindFirst();
    end;
}

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

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_keyword)
      (identifier)
      (code_block
        (call_expression
          (member_expression
            (identifier)
            (identifier))
          (argument_list
            (quoted_identifier)
            (string_literal)))
        (call_expression
          (member_expression
            (identifier)
            (identifier))
          (argument_list))))))

========================================================================
Nested function calls
========================================================================

codeunit 50100 Test
{
    procedure Foo()
    begin
        x := Format(Abs(y));
    end;
}

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

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_keyword)
      (identifier)
      (code_block
        (assignment_statement
          (identifier)
          (call_expression
            (identifier)
            (argument_list
              (call_expression
                (identifier)
                (argument_list
                  (identifier))))))))))

========================================================================
XOR expression
========================================================================

codeunit 50100 Test
{
    procedure Foo()
    begin
        if a xor b then
            exit;
    end;
}

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

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_keyword)
      (identifier)
      (code_block
        (if_statement
          (if_keyword)
          (logical_expression
            (identifier)
            (identifier))
          (then_keyword)
          (exit_statement
            (exit_keyword)))))))

========================================================================
Complex expression precedence
========================================================================

codeunit 50100 Test
{
    procedure Foo()
    begin
        x := a + b * c - d / e;
    end;
}

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

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_keyword)
      (identifier)
      (code_block
        (assignment_statement
          (identifier)
          (additive_expression
            (additive_expression
              (identifier)
              (multiplicative_expression
                (identifier)
                (identifier)))
            (multiplicative_expression
              (identifier)
              (identifier))))))))

========================================================================
Empty argument list
========================================================================

codeunit 50100 Test
{
    procedure Foo()
    begin
        DoSomething();
    end;
}

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

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_keyword)
      (identifier)
      (code_block
        (call_expression
          (identifier)
          (argument_list))))))

========================================================================
Boolean literal in expression
========================================================================

codeunit 50100 Test
{
    procedure Foo()
    begin
        x := true;
        y := false;
    end;
}

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

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_keyword)
      (identifier)
      (code_block
        (assignment_statement
          (identifier)
          (boolean))
        (assignment_statement
          (identifier)
          (boolean))))))

========================================================================
Or expression
========================================================================

codeunit 50100 Test
{
    procedure Foo()
    begin
        if a or b then
            exit;
    end;
}

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

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_keyword)
      (identifier)
      (code_block
        (if_statement
          (if_keyword)
          (logical_expression
            (identifier)
            (identifier))
          (then_keyword)
          (exit_statement
            (exit_keyword)))))))
