================================================================================
Storage blocks
================================================================================

storage {}

storage {
    balance: u64 = 0,
    name: &str = "",
    var1: Type1 = Type1 { x: 0, y: 0 },
    var2: Type2 = Type2 {
        w: 0x0000000000000000000000000000000000000000000000000000000000000000,
        z: false,
    },
}

storage {
    // With comments
    balances: StorageMap<Identity, u64> = StorageMap {},
}

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

(source_file
  (storage_item
    (storage_content_list))
  (storage_item
    (storage_content_list
      (storage_content
        (field_declaration
          (field_identifier)
          (primitive_type))
        (integer_literal))
      (storage_content
        (field_declaration
          (field_identifier)
          (reference_type
            (primitive_type)))
        (string_literal))
          (storage_content
            (field_declaration
              (field_identifier)
              (type_identifier))
            (struct_expression
              (type_identifier)
              (field_initializer_list
                (field_initializer
                  (field_identifier)
                  (integer_literal))
                (field_initializer
                  (field_identifier)
                  (integer_literal)))))
          (storage_content
            (field_declaration
              (field_identifier)
              (type_identifier))
            (struct_expression
              (type_identifier)
              (field_initializer_list
                (field_initializer
                  (field_identifier)
                  (integer_literal))
                (field_initializer
                  (field_identifier)
                  (boolean_literal)))))))
  (storage_item
    (storage_content_list
      (line_comment)
      (storage_content
        (field_declaration
          (field_identifier)
          (generic_type
            (type_identifier)
            (type_arguments
              (type_identifier)
              (primitive_type))))
        (struct_expression
          (type_identifier)
          (field_initializer_list))))))

================================================================================
Configurable blocks
================================================================================

configurable {}

configurable {
    C0: bool = true,
    C1: u64 = 42,
    C2: b256 = 0x1111111111111111111111111111111111111111111111111111111111111111,
    C3: MyStruct = MyStruct { x: 42, y: true },
    C4: MyEnum = MyEnum::A(42),
    C5: MyEnum = MyEnum::B(true),
    C6: &str = "fuel",
    C7: [u64; 4] = [1, 2, 3, 4],
    C8: u64 = 0, // Unused - should not show up in the JSON file
}

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

(source_file
  (configurable_item
    (storage_content_list))
      (configurable_item
    (storage_content_list
      (storage_content
        (field_declaration
          (field_identifier)
          (primitive_type))
        (boolean_literal))
      (storage_content
        (field_declaration
          (field_identifier)
          (primitive_type))
        (integer_literal))
      (storage_content
        (field_declaration
          (field_identifier)
          (type_identifier))
        (integer_literal))
      (storage_content
        (field_declaration
          (field_identifier)
          (type_identifier))
        (struct_expression
          (type_identifier)
          (field_initializer_list
            (field_initializer
              (field_identifier)
              (integer_literal))
            (field_initializer
              (field_identifier)
              (boolean_literal)))))
      (storage_content
        (field_declaration
          (field_identifier)
          (type_identifier))
        (call_expression
          (scoped_identifier
            (identifier)
            (identifier))
          (arguments
            (integer_literal))))
      (storage_content
        (field_declaration
          (field_identifier)
          (type_identifier))
        (call_expression
          (scoped_identifier
            (identifier)
            (identifier))
          (arguments
            (boolean_literal))))
      (storage_content
        (field_declaration
          (field_identifier)
          (reference_type
            (primitive_type)))
        (string_literal))
      (storage_content
        (field_declaration
          (field_identifier)
          (array_type
            (primitive_type)
            (integer_literal)))
        (array_expression
          (integer_literal)
          (integer_literal)
          (integer_literal)
          (integer_literal)))
      (storage_content
        (field_declaration
          (field_identifier)
          (primitive_type))
        (integer_literal))
      (line_comment))))

================================================================================
ABI items
================================================================================

abi Empty {}

abi Counter {
    #[storage(read, write)]
    fn increment();

    #[storage(read, write)]
    fn decrement();

    #[storage(read)]
    fn count() -> u64;
}

abi OtherContract {
    #[payable]
    fn external_call();
}

abi IdentityExample {
    #[storage(read)]
    fn access_control_with_identity();
    fn cast_to_identity();
    fn different_executions(my_identity: Identity);
    fn identity_to_contract_id(my_identity: Identity);
}

abi MyAbi : MyTrait1 + MyTrait2 {
    fn bar();
} {
    fn baz() {
        Self::foo1();
        Self::foo2();
    }
}

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

(source_file
  (abi_item
    (type_identifier)
    (declaration_list))
  (abi_item
    (type_identifier)
    (declaration_list
      (attribute_item
        (attribute
          (identifier)
          (token_tree
            (identifier)
            (identifier))))
      (function_signature_item
        (identifier)
        (parameters))
      (attribute_item
        (attribute
          (identifier)
          (token_tree
            (identifier)
            (identifier))))
      (function_signature_item
        (identifier)
        (parameters))
      (attribute_item
        (attribute
          (identifier)
          (token_tree
            (identifier))))
      (function_signature_item
        (identifier)
        (parameters)
        (primitive_type))))
  (abi_item
    (type_identifier)
    (declaration_list
      (attribute_item
        (attribute
          (identifier)))
      (function_signature_item
        (identifier)
        (parameters))))
  (abi_item
    (type_identifier)
    (declaration_list
      (attribute_item
        (attribute
          (identifier)
          (token_tree
            (identifier))))
      (function_signature_item
        (identifier)
        (parameters))
      (function_signature_item
        (identifier)
        (parameters))
      (function_signature_item
        (identifier)
        (parameters
          (parameter
            (identifier)
            (type_identifier))))
      (function_signature_item
        (identifier)
        (parameters
          (parameter
            (identifier)
            (type_identifier))))))
  (abi_item
    (type_identifier)
    (trait_bounds
      (type_identifier)
      (type_identifier))
    (declaration_list
      (function_signature_item
        (identifier)
        (parameters))))
  (expression_statement
    (block
      (function_item
        (identifier)
        (parameters)
        (block
          (expression_statement
            (call_expression
              (scoped_identifier
                (identifier)
                (identifier))
              (arguments)))
          (expression_statement
            (call_expression
              (scoped_identifier
                (identifier)
                (identifier))
              (arguments))))))))

================================================================================
ABI expressions
================================================================================

abi(TestAbi, 0x3dba0a4455b598b7655a7fb430883d96c9527ef275b49739e7b0ad12f8280eae).deposit(amount);

caller.send_funds {
    gas: 10000,
    asset_id: ZERO_B256,
}(amount_to_send, recipient_address);

let number = balance_test_contract.get_42 {
    gas: u64::max(),
}();

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

(source_file
  (expression_statement
    (call_expression
      (field_expression
        (abi_instance_expression
          (arguments
            (identifier)
            (integer_literal)))
        (field_identifier))
      (arguments
        (identifier))))
  (expression_statement
    (abi_call_expression
      (field_expression
        (identifier)
        (field_identifier))
      (field_initializer_list
        (field_initializer
          (field_identifier)
          (integer_literal))
        (field_initializer
          (field_identifier)
          (identifier)))
      (arguments
        (identifier)
        (identifier))))
  (let_declaration
    (identifier)
    (abi_call_expression
      (field_expression
        (identifier)
        (field_identifier))
      (field_initializer_list
        (field_initializer
          (field_identifier)
          (call_expression
            (scoped_identifier
              (identifier)
              (identifier))
            (arguments))))
      (arguments))))

================================================================================
ASM blocks
================================================================================

asm(r1: 0, r2: 0, r3, r4) {
    move r1 r2;
    move r2 r1;
    move r3 r1;
    move r4 r2;
};

impl Ord for u32 {
    fn gt(self, other: Self) -> bool {
        asm(r1: self, r2: other, r3) {
            gt r3 r1 r2;
            r3: bool
        }
    }
    fn lt(self, other: Self) -> bool {
        asm(r1: self, r2: other, r3) {
            lt r3 r1 r2;
            r3: bool
        }
    }
}

asm(r1: a, r2: ZERO_B256) {
    log r1 r2 zero zero;
    zero
};

asm(r1: (big_value.bytes)[0], r2) {
    r2: bool
};

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

(source_file
  (expression_statement
    (asm_expression
      (asm_parameters
        (asm_parameter
          (identifier)
          (integer_literal))
        (asm_parameter
          (identifier)
          (integer_literal))
        (asm_parameter
          (identifier))
        (asm_parameter
          (identifier)))
      (asm_block
        (asm_content
          (identifier)
          (identifier)
          (identifier)
          (identifier)
          (identifier)
          (identifier)
          (identifier)
          (identifier)
          (identifier)
          (identifier)
          (identifier)
          (identifier)))))
  (impl_item
    (type_identifier)
    (primitive_type)
    (declaration_list
      (function_item
        (identifier)
        (parameters
          (self_parameter
            (self))
          (parameter
            (identifier)
            (type_identifier)))
        (primitive_type)
        (block
          (asm_item
            (asm_parameters
              (asm_parameter
                (identifier)
                (self))
              (asm_parameter
                (identifier)
                (type_identifier))
              (asm_parameter
                (identifier)))
            (asm_block
              (asm_content
                (identifier)
                (identifier)
                (identifier)
                (identifier)
                (identifier)
                (primitive_type))))))                
      (function_item
        (identifier)
        (parameters
          (self_parameter
            (self))
          (parameter
            (identifier)
            (type_identifier)))
        (primitive_type)
        (block
          (asm_item
            (asm_parameters
              (asm_parameter
                (identifier)
                (self))
              (asm_parameter
                (identifier)
                (type_identifier))
              (asm_parameter
                (identifier)))
            (asm_block
              (asm_content
                (identifier)
                (identifier)
                (identifier)
                (identifier)
                (identifier)
                (primitive_type))))))))
  (expression_statement
    (asm_expression
      (asm_parameters
        (asm_parameter
          (identifier)
          (type_identifier))
        (asm_parameter
          (identifier)
          (type_identifier)))
      (asm_block
        (asm_content
          (identifier)
          (identifier)
          (identifier)
          (identifier)
          (identifier)
          (identifier)))))
  (expression_statement
    (asm_expression
      (asm_parameters
        (asm_parameter
          (identifier)
          (index_expression
            (parenthesized_expression
              (field_expression
                (identifier)
                (field_identifier)))
            (integer_literal)))
        (asm_parameter
          (identifier)))
      (asm_block
        (asm_content
          (identifier)
          (primitive_type))))))

================================================================================
ASM expressions
================================================================================

let balance = asm(token_bal, token: BASE_ASSET_ID, id: balance_test_contract_id) {
    bal  token_bal token id;
    token_bal: u64
};

assert(foo_ptr == asm(r1: foo) { r1: raw_ptr });

fn get_gas() -> GasCounts {
    GasCounts {
        global_gas: asm() {
            ggas
        }
    }
}

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

(source_file
  (let_declaration
    (identifier)
    (asm_expression
      (asm_parameters
        (asm_parameter
          (identifier))
        (asm_parameter
          (identifier)
          (type_identifier))
        (asm_parameter
          (identifier)
          (type_identifier)))
      (asm_block
        (asm_content
          (identifier)
          (identifier)
          (identifier)
          (identifier)
          (identifier)
          (primitive_type)))))
  (expression_statement
    (call_expression
      (identifier)
      (arguments
        (binary_expression
          (identifier)
          (asm_expression
            (asm_parameters
              (asm_parameter
                (identifier)
                (type_identifier)))
            (asm_block
              (asm_content
                (identifier)
                (type_identifier))))))))
  (function_item
    (identifier)
    (parameters)
    (type_identifier)
    (block
      (struct_expression
        (type_identifier)
        (field_initializer_list
          (field_initializer
            (field_identifier)
            (asm_expression
              (asm_parameters)
              (asm_block
                (asm_content
                  (identifier))))))))))

================================================================================
Program Type
================================================================================

contract;

script;

predicate;

library my_lib;

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

(source_file
  (program_type)
  (program_type)
  (program_type)
  (program_type
    (identifier)))

