================================================================================
Excerpt from stdlib's base.gleam
================================================================================

import gleam/bit_string
import gleam/string

/// Encodes a BitString into a base 64 encoded string.
///
pub fn encode64(input: BitString, padding: Bool) -> String {
  let encoded = do_encode64(input)
  case padding {
    True -> encoded
    False -> string.replace(encoded, "=", "")
  }
}

if erlang {
  external fn do_encode64(BitString) -> String =
    "base64" "encode"
}

if javascript {
  external fn do_encode64(BitString) -> String =
    "../gleam_stdlib.mjs" "encode64"
}

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

(source_file
  (import
    module: (module))
  (import
    module: (module))
  (statement_comment)
  (statement_comment)
  (function
    (visibility_modifier)
    name: (identifier)
    parameters: (function_parameters
      (function_parameter
        name: (identifier)
        type: (type
          name: (type_identifier)))
      (function_parameter
        name: (identifier)
        type: (type
          name: (type_identifier))))
    return_type: (type
      name: (type_identifier))
    body: (function_body
      (let
        pattern: (identifier)
        value: (function_call
          function: (identifier)
          arguments: (arguments
            (argument
              value: (identifier)))))
      (case
        subjects: (case_subjects
          (identifier))
        clauses: (case_clauses
          (case_clause
            patterns: (case_clause_patterns
              (case_clause_pattern
                (record_pattern
                  name: (type_identifier))))
            value: (identifier))
          (case_clause
            patterns: (case_clause_patterns
              (case_clause_pattern
                (record_pattern
                  name: (type_identifier))))
            value: (function_call
              function: (field_access
                record: (identifier)
                field: (label))
              arguments: (arguments
                (argument
                  value: (identifier))
                (argument
                  value: (string
                    (quoted_content)))
                (argument
                  value: (string)))))))))
  (target_group
    target: (target)
    (external_function
      name: (identifier)
      parameters: (function_parameters
        (function_parameter
          type: (type
            name: (type_identifier))))
      return_type: (type
        name: (type_identifier))
      body: (external_function_body
        (string
          (quoted_content))
        (string
          (quoted_content)))))
  (target_group
    target: (target)
    (external_function
      name: (identifier)
      parameters: (function_parameters
        (function_parameter
          type: (type
            name: (type_identifier))))
      return_type: (type
        name: (type_identifier))
      body: (external_function_body
        (string
          (quoted_content))
        (string
          (quoted_content))))))

================================================================================
Excerpt from stdlib's bool.gleam
================================================================================

//// A type with two possible values, `True` and `False`. Used to indicate whether
//// things are... true or false!
////
//// Often is it clearer and offers more type safety to define a custom type
//// than to use `Bool`. For example, rather than having a `is_teacher: Bool`
//// field consider having a `role: SchoolRole` field where `SchoolRole` is a custom
//// type that can be either `Student` or `Teacher`.

import gleam/order.{Order}

/// Returns the opposite bool value.
///
/// This is the same as the `!` or `not` operators in some other languages.
///
/// ## Examples
///
///    > negate(True)
///    False
///
///    > negate(False)
///    True
///
pub fn negate(bool: Bool) -> Bool {
  case bool {
    True -> False
    False -> True
  }
}

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

(source_file
  (module_comment)
  (module_comment)
  (module_comment)
  (module_comment)
  (module_comment)
  (module_comment)
  (module_comment)
  (import
    module: (module)
    imports: (unqualified_imports
      (unqualified_import
        name: (type_identifier))))
  (statement_comment)
  (statement_comment)
  (statement_comment)
  (statement_comment)
  (statement_comment)
  (statement_comment)
  (statement_comment)
  (statement_comment)
  (statement_comment)
  (statement_comment)
  (statement_comment)
  (statement_comment)
  (function
    (visibility_modifier)
    name: (identifier)
    parameters: (function_parameters
      (function_parameter
        name: (identifier)
        type: (type
          name: (type_identifier))))
    return_type: (type
      name: (type_identifier))
    body: (function_body
      (case
        subjects: (case_subjects
          (identifier))
        clauses: (case_clauses
          (case_clause
            patterns: (case_clause_patterns
              (case_clause_pattern
                (record_pattern
                  name: (type_identifier))))
            value: (record
              name: (type_identifier)))
          (case_clause
            patterns: (case_clause_patterns
              (case_clause_pattern
                (record_pattern
                  name: (type_identifier))))
            value: (record
              name: (type_identifier))))))))

================================================================================
Trailing commas
================================================================================

import animal.{Cat,}

const foo: #(Int,) = #(1,)
const bar = [1,]
const cat:Cat(String,) = Cat(name: "Nubi",)

type Thing {
  First(name: String,)
}

external fn foo(String,) -> String = "foo" "bar"

fn foo(a,) {
  myfun(a,)
  let Cat(name: name,) = Cat(..a, name: "George",)
  let #(a) = #(a,)
  let [x,] = [1,]
}

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

(source_file
  (import
    (module)
    (unqualified_imports
      (unqualified_import
        (type_identifier))))
  (constant
    (identifier)
    (tuple_type
      (type
        (type_identifier)))
    (tuple
      (integer)))
  (constant
    (identifier)
    (list
      (integer)))
  (constant
    (identifier)
    (type
      (type_identifier)
      (type_arguments
        (type_argument
          (type
            (type_identifier)))))
    (record
      (type_identifier)
      (arguments
        (argument
          (label)
          (string
            (quoted_content))))))
  (type_definition
    (type_name
      (type_identifier))
    (data_constructors
      (data_constructor
        (type_identifier)
        (data_constructor_arguments
          (data_constructor_argument
            (label)
            (type
              (type_identifier)))))))
  (external_function
    (identifier)
    (function_parameters
      (function_parameter
        (type
          (type_identifier))))
    (type
      (type_identifier))
    (external_function_body
      (string
        (quoted_content))
      (string
        (quoted_content))))
  (function
    (identifier)
    (function_parameters
      (function_parameter
        (identifier)))
    (function_body
      (function_call
        (identifier)
        (arguments
          (argument
            (identifier))))
      (let
        (record_pattern
          (type_identifier)
          (record_pattern_arguments
            (record_pattern_argument
              (label)
              (identifier))))
        (record_update
          (type_identifier)
          (identifier)
          (record_update_arguments
            (record_update_argument
              (label)
              (string
                (quoted_content))))))
      (let
        (tuple_pattern
          (identifier))
        (tuple
          (identifier)))
      (let
        (list_pattern
          (identifier))
        (list
          (integer))))))
