testFullUntyped :: SpecWith ()
testFullUntyped = test s "FullUntyped" input output
  where
    s :: Syntactic '[TmBool, TmNat, TmArith, TmApp, TmLam, TmLet, TmRecord, TmFloat, TmString, TmVar]
    s = crep
    input = [
      "x",
      "y'",
      "if x then false else x",
      "\\x.x",
      "(\\x.x)   \\x.x",
      "\\x.(x)",
      "\\x.(x x)",
      "\\x.x \\x.x",
      "2.0",
      "timesfloat 2.0 3.0",
      "timesfloat (timesfloat 2.0 3.0) (timesfloat 4.0 5.0)",
      "\"hello\"",
      "0",
      "succ (pred 0)",
      "iszero (pred (succ (succ 0)))",
      "let x=true in x",
      "{x=\\x.x, y=(\\x.x)(\\x.x)}",
      "{x=\\x.x, y=(\\x.x)(\\x.x)}.x",
      "{x=1.0}.t"]
    output = [
      "x",
      "y'",
      "(if x then false else x)",
      "\\x.x",
      "(\\x.x \\x.x)",
      "\\x.x",
      "\\x.(x x)",
      "(\\x.x \\x.x)",
      "2.0",
      "timesfloat (2.0) (3.0)",
      "timesfloat (timesfloat (2.0) (3.0)) (timesfloat (4.0) (5.0))",
      "\"hello\"",
      "0",
      "succ (pred (0))",
      "iszero (pred (succ (succ (0))))",
      "let x = true in x",
      "{x=\\x.x, y=(\\x.x \\x.x)}",
      "{x=\\x.x, y=(\\x.x \\x.x)}.x",
      "{x=1.0}.t"]
testFullUntyped :: SpecWith ()
testFullUntyped = test s "FullUntyped" input output
  where
    s :: Syntactic '[TmBool, TmNat, TmArith, TmApp, TmLam, TmLet, TmRecord, TmFloat, TmString, TmVar]
    s = crep
    input = [
      "x",
      "y'",
      "if x then false else x",
      "\\x.x",
      "(\\x.x)   \\x.x",
      "\\x.(x)",
      "\\x.(x x)",
      "\\x.x \\x.x",
      "2.0",
      "timesfloat 2.0 3.0",
      "timesfloat (timesfloat 2.0 3.0) (timesfloat 4.0 5.0)",
      "\"hello\"",
      "0",
      "succ (pred 0)",
      "iszero (pred (succ (succ 0)))",
      "let x=true in x",
      "{x=\\x.x, y=(\\x.x)(\\x.x)}",
      "{x=\\x.x, y=(\\x.x)(\\x.x)}.x",
      "{x=1.0}.t"]
    output = [
      "x",
      "y'",
      "(if x then false else x)",
      "\\x.x",
      "(\\x.x \\x.x)",
      "\\x.x",
      "\\x.(x x)",
      "(\\x.x \\x.x)",
      "2.0",
      "timesfloat (2.0) (3.0)",
      "timesfloat (timesfloat (2.0) (3.0)) (timesfloat (4.0) (5.0))",
      "\"hello\"",
      "0",
      "succ (pred (0))",
      "iszero (pred (succ (succ (0))))",
      "let x = true in x",
      "{x=\\x.x, y=(\\x.x \\x.x)}",
      "{x=\\x.x, y=(\\x.x \\x.x)}.x",
      "{x=1.0}.t"]
testFullUntyped = test s "FullUntyped" input output
  where
    s :: Syntactic '[TmBool, TmNat, TmArith, TmApp, TmLam, TmLet, TmRecord, TmFloat, TmString, TmVar]
    s = crep
    input = [
      "x",
      "y'",
      "if x then false else x",
      "\\x.x",
      "(\\x.x)   \\x.x",
      "\\x.(x)",
      "\\x.(x x)",
      "\\x.x \\x.x",
      "2.0",
      "timesfloat 2.0 3.0",
      "timesfloat (timesfloat 2.0 3.0) (timesfloat 4.0 5.0)",
      "\"hello\"",
      "0",
      "succ (pred 0)",
      "iszero (pred (succ (succ 0)))",
      "let x=true in x",
      "{x=\\x.x, y=(\\x.x)(\\x.x)}",
      "{x=\\x.x, y=(\\x.x)(\\x.x)}.x",
      "{x=1.0}.t"]
    output = [
      "x",
      "y'",
      "(if x then false else x)",
      "\\x.x",
      "(\\x.x \\x.x)",
      "\\x.x",
      "\\x.(x x)",
      "(\\x.x \\x.x)",
      "2.0",
      "timesfloat (2.0) (3.0)",
      "timesfloat (timesfloat (2.0) (3.0)) (timesfloat (4.0) (5.0))",
      "\"hello\"",
      "0",
      "succ (pred (0))",
      "iszero (pred (succ (succ (0))))",
      "let x = true in x",
      "{x=\\x.x, y=(\\x.x \\x.x)}",
      "{x=\\x.x, y=(\\x.x \\x.x)}.x",
      "{x=1.0}.t"]