137 lines
4 KiB
Rust
137 lines
4 KiB
Rust
#![warn(clippy::pedantic)]
|
|
|
|
use std::io::{stdin, Read};
|
|
|
|
fn main() {
|
|
let mut input = String::new();
|
|
stdin().read_to_string(&mut input).unwrap();
|
|
|
|
println!(
|
|
"{}({})()",
|
|
function_constructor(),
|
|
string_with_fromcodepoint(input.trim())
|
|
);
|
|
}
|
|
|
|
fn string_with_fromcodepoint(s: &str) -> String {
|
|
let mut out = String::new();
|
|
out.push_str(&function_constructor());
|
|
out.push('(');
|
|
out.push_str(&string("return String.fromCodePoint("));
|
|
for c in s.chars() {
|
|
out.push('+');
|
|
out.push_str(&string(&(c as u32).to_string()));
|
|
out.push('+');
|
|
out.push_str(&char(','));
|
|
}
|
|
out.push('+');
|
|
out.push_str(&char(')'));
|
|
out.push_str(")()");
|
|
out
|
|
}
|
|
|
|
fn regexp_constructor() -> String {
|
|
format!("{}({})()", function_constructor(), string("return RegExp"))
|
|
}
|
|
|
|
fn function_constructor() -> String {
|
|
format!("[][{}][{}]", string("flat"), string("constructor"))
|
|
}
|
|
|
|
fn string(s: &str) -> String {
|
|
s.chars().map(char).collect::<Vec<_>>().join("+")
|
|
}
|
|
|
|
fn char(c: char) -> String {
|
|
if c == ',' {
|
|
format!("([[]][{}]([[]])+[])", string("concat"))
|
|
} else if c.is_ascii() && c.is_numeric() {
|
|
format!("(({})+[])", number(c as usize - b'0' as usize))
|
|
} else if let Some(index) = "undefined".find(c) {
|
|
format!("([][[]]+[])[{}]", number(index))
|
|
} else if let Some(index) = "true".find(c) {
|
|
format!("(!![]+[])[{}]", number(index))
|
|
} else if let Some(index) = "false".find(c) {
|
|
format!("(![]+[])[{}]", number(index))
|
|
} else if let Some(index) = "function flat() {".find(c) {
|
|
format!("([][{}]+[])[{}]", string("flat"), number(index))
|
|
} else if let Some(index) = "[object Array Iterator]".find(c) {
|
|
format!("([][{}]()+[])[{}]", string("entries"), number(index))
|
|
} else if let Some(index) = "Number".find(c) {
|
|
format!(
|
|
"((+[])[{}]+[])[{}]",
|
|
string("constructor"),
|
|
number(index + 9)
|
|
)
|
|
} else if let Some(index) = "String".find(c) {
|
|
format!(
|
|
"(([]+[])[{}]+[])[{}]",
|
|
string("constructor"),
|
|
number(index + 9)
|
|
)
|
|
} else if let Some(index) = "Function".find(c) {
|
|
format!("({}+[])[{}]", function_constructor(), number(index + 9))
|
|
} else if c == '}' {
|
|
format!(
|
|
"([][{}]+[])[{}](-({}))",
|
|
string("flat"),
|
|
string("at"),
|
|
number(1)
|
|
)
|
|
} else if c == '.' {
|
|
format!("(+({})+[])[{}]", string("11e100"), number(1))
|
|
} else if c.is_ascii_lowercase() {
|
|
format!(
|
|
"({})[{}+(([]+[])[{}][{}])]({})",
|
|
number(c as usize - b'a' as usize + 10),
|
|
string("to"),
|
|
string("constructor"),
|
|
string("name"),
|
|
number(36)
|
|
)
|
|
} else if let Some(index) = "RangeError:".find(c) {
|
|
format!(
|
|
"({}({})()+[])[{}]",
|
|
function_constructor(),
|
|
string("try{String().normalize(false)}catch(f){return f}"),
|
|
number(index)
|
|
)
|
|
} else if let Some(index) = "/(?:)/".find(c) {
|
|
format!("({}()+[])[{}]", regexp_constructor(), number(index))
|
|
} else if c == '\\' {
|
|
format!(
|
|
"({}({})+[])[{}]",
|
|
regexp_constructor(),
|
|
string("/"),
|
|
number(1)
|
|
)
|
|
} else if c == '\'' {
|
|
format!(
|
|
"({}({})()+[])[{}]",
|
|
function_constructor(),
|
|
string("try{Function([[]].concat([[]]).toString())}catch(f){return f}"),
|
|
number(30)
|
|
)
|
|
} else {
|
|
let mut buf = [0; 2];
|
|
let buf = c.encode_utf16(&mut buf);
|
|
let s = buf
|
|
.iter()
|
|
.map(|v| format!("\\u{:04x}", v))
|
|
.collect::<String>();
|
|
format!(
|
|
"{}({})()",
|
|
function_constructor(),
|
|
string(&format!("return '{}'", s))
|
|
)
|
|
}
|
|
}
|
|
|
|
fn number(n: usize) -> String {
|
|
if n == 0 {
|
|
"+[]".to_owned()
|
|
} else {
|
|
"+!![]".repeat(n)
|
|
}
|
|
}
|