// Try to cover all syntactic constructs.
@compiler > 0
@compiler =< 10.1.2.3.4

include "String.aes"

namespace NamespaceX =
  datatype datatypeX('a) = D | S(int) | M('a, list('a), int)
  private function fff() = 123

  stateful function
    f (1, x) = (_) => x

payable contract interface AllSyntaxType =
  /** Multi-
    * line
    * comment
    */
  stateful entrypoint foo : (string * hash) => unit
  entrypoint bar : int => (int * 'a)


main contract AllSyntax =
  datatype mickiewicz = Adam | Mickiewicz
  record goethe('a, 'b) = {
    johann : int,
    wolfgang : 'a,
    von : 'a * 'b * int,
    goethe : unit
    }
  type dante = NamespaceX.datatypeX(int)
  type shakespeare('a) = goethe('a, 'a)

  type state = shakespeare(int)

  entrypoint init() = {
    johann = 1000,
    wolfgang = -10,
    von = (2 + 2, 0, List.sum([x | k <- [1,2,3]
                                 , let l = k + 1
                                 , if(l < 10)
                                 , let f(x) = x + 100
                                 , Adam <- [Adam, Mickiewicz]
                                 , let x = f(l)
                                 ])),
    goethe = () }

  stateful function f() =
     let kp = "nietzsche"
     let p = "Пушкин"
     let k(x : bytes(8)) : int = Bytes.to_int(#fedcba9876543210)

     let f : () => address = () => ak_2gx9MEFxKvY9vMG5YnqnXWv1hCsX7rgnfvBLJS4aQurustR1rt
     if(Bits.test(Bits.all, 10))
       abort("ohno")
     if(true && false)
       require(true, "ohyes")
     elif(false || 2 == 2)
       ()
     else
       ()
     if(true)
       let Some(x) = String.to_int(Address.to_str(f()))
       x
     else switch(1::[1,2,3])
       [] => 1
       a::b => 123
       1::2::3::_ => 123123
       [2,3,4] => 1
       _ => 13
       1::[2] => 2138
     put(state{johann = 1})

     let m = {["foo"] = 19, /*hey wanna talk about inlined comments?*/ ["bar"] = 42}
     let n = {}
     m{ ["x" = 0] @ z = z + state.johann }

     let sh : shakespeare(shakespeare(int)) = {wolfgang = state, johann = 43, von = (state, state, 42), goethe = ()}
     sh{wolfgang.wolfgang = sh.johann} // comment

  record rec = {x: int, y: bool}
  datatype user_type = All | Nothing
  datatype event = EventX(indexed int, string)

  function all_literals() =
    let t1 : int = -1
    let t1 : int = 245_000_000_000
    let t1 : int = 0x12ab45de
    let t2 : address = ak_2gx9MEFxKvY9vMG5YnqnXWv1hCsX7rgnfvBLJS4aQurustR1rt
    let t3 : bool = true || false
    let t4 : bits = Bits.all
    let t5 : bytes(8) = #00010203040506ff
    let t6 : string = "This is a string"
    let t6 : string = "This \b\n"
    let t7 : list(int) = [1, 2, 3]
    let t8 : int * string = (1, "fgoo")
    let t9 : rec = {x = 12, y = false}
    let t10 : map(int, int) = {[12] = 12, [42] = 1}
    let t11 : option(int) = Some(1)
    let t12 : event = EventX(42, "Hello")
    let t13 : hash = #000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f
    let t14 : signature = #000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f
    let t15 : Chain.ttl = FixedTTL(1234)
    let t15 : Chain.ttl = RelativeTTL(12)
    let t16 : oracle(int, int) = ok_2YNyxd6TRJPNrTcEDCe9ra59SVUdp9FR9qWC5msKZWYD9bP9z5
    let t17 : oracle_query(int, int) = oq_2oRvyowJuJnEkxy58Ckkw77XfWJrmRgmGaLzhdqb67SKEL1gPY
    let t18 : AllSyntaxType = ct_Ez6MyeTMm17YnTnDdHTSrzMEBKmy7Uz2sXu347bTDPgVH2ifJ
    let t19 : user_type = All
    let t20 : list(char) = ['x', 'y', 'ど', '✓']
    let t21 : unit = ()
    t21

  function all_operators() =
    let x = 0 :: [1] ++ [2, 3]
    let y = -5 + 6 - 7 * 8 / 9 mod 10 ^ 4
    let z = 12 band 34 bor 56 bxor bnot 78 << 1 >> 2
    let a = !(0 =< 1) && (1 >= 2) || (1 != 2) || (3 == 4) && (5 < 6) && (8 > 7)
    (x, y, z)
