macro_rules! println {
    ($($arg:tt)*) => ({
        $crate::io::_print(format_args_nl!($($arg)*));
    })
}

mod panic {
    pub macro panic_2015 {
        () => (
            panic("explicit panic")
        ),
        ($msg:literal $(,)?) => (
            panic($msg)
        ),
        // Use `panic_str` instead of `panic_display::<&str>` for non_fmt_panic lint.
        ($msg:expr $(,)?) => (
            panic_str($msg)
        ),
        // Special-case the single-argument case for const_panic.
        ("{}", $arg:expr $(,)?) => (
            panic_display(&$arg)
        ),
        ($fmt:expr, $($arg:tt)+) => (
            panic_fmt(const_format_args!($fmt, $($arg)+))
        ),
    }
}

macro_rules! toho {
    () => ($crate::panic!("not yet implemented"));
    ($($arg:tt)+) => ($crate::panic!("not yet implemented: {}", format_args!($($arg)+)));
}

macro_rules! reuse_twice {
    ($literal:literal) => {{stringify!($literal); format_args!($literal)}};
}

fn main() {
    let a = '\n';
    let a = '\t';
    let a = '\e'; // invalid escape
    let a = 'e';
    let a = ' ';
    let a = '\u{48}';
    let a = '\u{4823}';
    let a = '\x65';
    let a = '\x00';

    let a = b'\xFF';

    println!("Hello {{Hello}}");
    // from https://doc.rust-lang.org/std/fmt/index.html
    println!("Hello");                 // => "Hello"
    println!("Hello, {}!", "world");   // => "Hello, world!"
    println!("The number is {}", 1);   // => "The number is 1"
    println!("{:?}", (3, 4));          // => "(3, 4)"
    println!("{value}", value=4);      // => "4"
    println!("{} {}", 1, 2);           // => "1 2"
    println!("{:04}", 42);             // => "0042" with leading zerosV
    println!("{1} {} {0} {}", 1, 2);   // => "2 1 1 2"
    println!("{argument}", argument = "test");   // => "test"
    println!("{name} {}", 1, name = 2);          // => "2 1"
    println!("{a} {c} {b}", a="a", b='b', c=3);  // => "a 3 b"
    println!("{{{}}}", 2);                       // => "{2}"
    println!("Hello {:5}!", "x");
    println!("Hello {:1$}!", "x", 5);
    println!("Hello {1:0$}!", 5, "x");
    println!("Hello {:width$}!", "x", width = 5);
    println!("Hello {:<5}!", "x");
    println!("Hello {:-<5}!", "x");
    println!("Hello {:^5}!", "x");
    println!("Hello {:>5}!", "x");
    println!("Hello {:+}!", 5);
    println!("{:#x}!", 27);
    println!("Hello {:05}!", 5);
    println!("Hello {:05}!", -5);
    println!("{:#010x}!", 27);
    println!("Hello {0} is {1:.5}", "x", 0.01);
    println!("Hello {1} is {2:.0$}", 5, "x", 0.01);
    println!("Hello {0} is {2:.1$}", "x", 5, 0.01);
    println!("Hello {} is {:.*}",    "x", 5, 0.01);
    println!("Hello {} is {2:.*}",   "x", 5, 0.01);
    println!("Hello {} is {number:.prec$}", "x", prec = 5, number = 0.01);
    println!("{}, `{name:.*}` has 3 fractional digits", "Hello", 3, name=1234.56);
    println!("{}, `{name:.*}` has 3 characters", "Hello", 3, name="1234.56");
    println!("{}, `{name:>8.*}` has 3 right-aligned characters", "Hello", 3, name="1234.56");

    let _ = "{}"
    let _ = "{{}}";

    println!("Hello {{}}");
    println!("{{ Hello");
    println!("Hello }}");
    println!("{{Hello}}");
    println!("{{ Hello }}");
    println!("{{Hello }}");
    println!("{{ Hello}}");

    println!(r"Hello, {}!", "world");

    // escape sequences
    println!("Hello\nWorld");
    println!("\u{48}\x65\x6C\x6C\x6F World");

    let _ = "\x28\x28\x00\x63\xFF\u{FF}\n"; // invalid non-UTF8 escape sequences
    let _ = b"\x28\x28\x00\x63\xFF\u{FF}\n"; // valid bytes, invalid unicodes
    let _ = c"\u{FF}\xFF"; // valid bytes, valid unicodes
    let backslash = r"\\";

    println!("{\x41}", A = 92);
    println!("{ничоси}", ничоси = 92);

    println!("{:x?} {} ", thingy, n2);
    panic!("{}", 0);
    panic!("more {}", 1);
    assert!(true, "{}", 1);
    assert!(true, "{} asdasd", 1);
    toho!("{}fmt", 0);
    let i: u64 = 3;
    let o: u64;
    asm!(
        "mov {0}, {1}",
        "add {0}, 5",
        out(reg) o,
        in(reg) i,
    );

    const CONSTANT: () = ():
    let mut m = ();
    format_args!(concat!("{}"), "{}");
    format_args!("{} {} {} {} {} {} {backslash} {CONSTANT} {m}", backslash, format_args!("{}", 0), foo, "bar", toho!(), backslash);
    reuse_twice!("{backslash}");
}