============================================
Number literals
============================================

double a = {
  0xAC00,
  0.123,
  0b1010001,
  0xabc00ull,
  -0.1f,
  1'000'000.000'001,
  24e-5,
  0.1E,
  58.,
  4e2,
  123.456e-67,
  .1E4f,
  0x10.1p0,
};

---

(translation_unit
  (declaration
    (primitive_type)
    (init_declarator
      (identifier)
      (initializer_list
        (number_literal)
        (number_literal)
        (number_literal)
        (number_literal)
        (number_literal)
        (number_literal)
        (number_literal)
        (number_literal)
        (number_literal)
        (number_literal)
        (number_literal)
        (number_literal)
        (number_literal)
      ))))

============================================
Identifiers
============================================

int main() {
  _abc;
  d_EG123;
}

---

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator (identifier) (parameter_list))
    (compound_statement
      (expression_statement (identifier))
      (expression_statement (identifier)))))

============================================
Common constants
============================================

int main() {
  true;
  false;
  NULL;

  // regression test - identifiers starting w/ these strings should tokenize correctly.
  true_value;
  false_value;
  NULL_value;
}

---

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator (identifier) (parameter_list))
    (compound_statement
      (expression_statement (true))
      (expression_statement (false))
      (expression_statement (null))
      (comment)
      (expression_statement (identifier))
      (expression_statement (identifier))
      (expression_statement (identifier)))))

============================================
Function calls
============================================

int main() {
  printf("hi! %d\n", x);
}

---

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator (identifier) (parameter_list))
    (compound_statement
      (expression_statement (call_expression
        (identifier)
        (argument_list (string_literal (escape_sequence)) (identifier)))))))

============================================
String literals
============================================

int main() {
  "a";
  "b" "c" "d";
  "\"hi\"";
  L"bonjour";
  u"guten morgen";
  U"buenos dias";
  u8"buongiorno";
}

---

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator (identifier) (parameter_list))
    (compound_statement
      (expression_statement (string_literal))
      (expression_statement (concatenated_string (string_literal) (string_literal) (string_literal)))
      (expression_statement (string_literal (escape_sequence) (escape_sequence)))
      (expression_statement (string_literal))
      (expression_statement (string_literal))
      (expression_statement (string_literal))
      (expression_statement (string_literal)))))

============================================
Character literals
============================================

int main() {
  'a';
  '\0';
  '\t';
  '\'';
  L'b';
  u'c';
  U'\xa1';
  u8'\x1A';
}

---

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator (identifier) (parameter_list))
    (compound_statement
      (expression_statement (char_literal))
      (expression_statement (char_literal (escape_sequence)))
      (expression_statement (char_literal (escape_sequence)))
      (expression_statement (char_literal (escape_sequence)))
      (expression_statement (char_literal))
      (expression_statement (char_literal))
      (expression_statement (char_literal (escape_sequence)))
      (expression_statement (char_literal (escape_sequence))))))

============================================
Field access
============================================

int main() {
  s.data1;
  p->data2;
  q[data3];
}

---

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator (identifier) (parameter_list))
    (compound_statement
      (expression_statement (field_expression (identifier) (field_identifier)))
      (expression_statement (field_expression (identifier) (field_identifier)))
      (expression_statement (subscript_expression (identifier) (identifier))))))

============================================
Boolean operators
============================================

int main() {
  !x || !y && !z;
}

---

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator (identifier) (parameter_list))
    (compound_statement
      (expression_statement (binary_expression
        (unary_expression (identifier))
        (binary_expression
          (unary_expression (identifier))
          (unary_expression (identifier))))))))

============================================
Math operators
============================================

int main() {
  -a / b + c * -d;
  a++ - ++b + c-- + --d;
  ++L;
  }

---

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator (identifier) (parameter_list))
    (compound_statement
      (expression_statement (binary_expression
        (binary_expression
          (unary_expression (identifier))
          (identifier))
        (binary_expression
          (identifier)
          (unary_expression (identifier)))))
      (expression_statement
        (binary_expression
          (binary_expression
            (binary_expression
              (update_expression (identifier))
              (update_expression (identifier)))
            (update_expression (identifier)))
          (update_expression (identifier))))
       (expression_statement (update_expression (identifier))))))

============================================
The comma operator
============================================

int main() {
  i--, j--;
  (i--, j--);
}

---

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator (identifier) (parameter_list))
    (compound_statement
      (expression_statement
        (comma_expression
          (update_expression (identifier))
          (update_expression (identifier))))
      (expression_statement
        (parenthesized_expression
          (comma_expression
            (update_expression (identifier))
            (update_expression (identifier))))))))

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

int main() {
  static int a = 1;
  b = *c = 2;
  d.e = 3;
  f->g = 4;
  h[i] = j;
  k += l;
  m -= o;
  n *= p;
  q /= r;
  *s++ = 1;
  (*t) = 1;
}

---

(translation_unit
  (function_definition
    type: (primitive_type)
    declarator: (function_declarator
      declarator: (identifier)
      parameters: (parameter_list))
    body: (compound_statement
      (declaration
        (storage_class_specifier)
        type: (primitive_type)
        declarator: (init_declarator
          declarator: (identifier)
          value: (number_literal)))
      (expression_statement (assignment_expression
        left: (identifier)
        right: (assignment_expression
          left: (pointer_expression
            argument: (identifier))
          right: (number_literal))))
      (expression_statement (assignment_expression
        left: (field_expression
          argument: (identifier)
          field: (field_identifier))
        right: (number_literal)))
      (expression_statement (assignment_expression
        left: (field_expression
          argument: (identifier)
          field: (field_identifier))
        right: (number_literal)))
      (expression_statement (assignment_expression
        left: (subscript_expression
          argument: (identifier)
          index: (identifier))
        right: (identifier)))
      (expression_statement (assignment_expression
        left: (identifier)
        right: (identifier)))
      (expression_statement (assignment_expression
        left: (identifier)
        right: (identifier)))
      (expression_statement (assignment_expression
        left: (identifier)
        right: (identifier)))
      (expression_statement (assignment_expression
        left: (identifier)
        right: (identifier)))
      (expression_statement (assignment_expression
        left: (pointer_expression
          argument: (update_expression
            argument: (identifier)))
        right: (number_literal)))
      (expression_statement (assignment_expression
        left: (parenthesized_expression (pointer_expression
          argument: (identifier)))
        right: (number_literal))))))

============================================
Pointer operations
============================================

int main() {
  doSomething(&x, *x);
}

---

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator (identifier) (parameter_list))
    (compound_statement
      (expression_statement (call_expression
        (identifier)
        (argument_list
          (pointer_expression (identifier))
          (pointer_expression (identifier))))))))

============================================
Type-casts
============================================

int main() {
  x = (const SomeType *)thing;
}

---

(translation_unit
  (function_definition
    type: (primitive_type)
    declarator: (function_declarator
      declarator: (identifier)
      parameters: (parameter_list))
    body: (compound_statement
      (expression_statement (assignment_expression
        left: (identifier)
        right: (cast_expression
          type: (type_descriptor
            (type_qualifier)
            type: (type_identifier)
            declarator: (abstract_pointer_declarator))
          value: (identifier)))))))

============================================
Sizeof expressions
============================================

int main() {
  sizeof x.a;
  sizeof(x.a);
  sizeof(const char **);
  sizeof(char * ());
}

---

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator (identifier) (parameter_list))
    (compound_statement
      (expression_statement (sizeof_expression (field_expression (identifier) (field_identifier))))
      (expression_statement (sizeof_expression (parenthesized_expression (field_expression (identifier) (field_identifier)))))
      (expression_statement (sizeof_expression
        (type_descriptor (type_qualifier) (primitive_type) (abstract_pointer_declarator (abstract_pointer_declarator)))))
      (expression_statement (sizeof_expression
        (type_descriptor (primitive_type) (abstract_pointer_declarator (abstract_function_declarator (parameter_list)))))))))

============================================
Compound literals
============================================

int main() {
  x = (SomeType) {
    .f1.f2[f3] = 5,
    .f4 = {}
  };
  y = (struct SomeStruct) {
    7,
    8
  };
  z = (char const []) {'a', 'b'};
}

---

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator (identifier) (parameter_list))
    (compound_statement
      (expression_statement (assignment_expression
        (identifier)
        (compound_literal_expression
          (type_descriptor (type_identifier))
          (initializer_list
            (initializer_pair
              (field_designator (field_identifier))
              (field_designator (field_identifier))
              (subscript_designator (identifier))
              (number_literal))
            (initializer_pair
              (field_designator (field_identifier))
              (initializer_list))))))
      (expression_statement (assignment_expression
        (identifier)
        (compound_literal_expression
          (type_descriptor (struct_specifier (type_identifier)))
          (initializer_list
            (number_literal)
            (number_literal)))))
      (expression_statement
        (assignment_expression
          (identifier)
          (compound_literal_expression
            (type_descriptor (primitive_type) (type_qualifier) (abstract_array_declarator))
            (initializer_list (char_literal) (char_literal))))))))

============================================
Compound literals with trailing commas
============================================

int main() {
  y = (struct SomeStruct) { 7, 8, };
}

---

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator (identifier) (parameter_list))
    (compound_statement
    (expression_statement (assignment_expression
      (identifier)
      (compound_literal_expression
        (type_descriptor (struct_specifier (type_identifier)))
        (initializer_list
          (number_literal)
          (number_literal))))))))

====================================
Comments with escaped newlines
====================================

// one \
   two

---

(translation_unit
  (comment))

==============================================
Comments with escaped chars and newlines
==============================================

// one \a \b \
   two
// one \c \d
---

(translation_unit
  (comment)
  (comment))
