Transpile essas funções de seta do ES6!

8

O padrão ECMAScript 6 adicionou muitos novos recursos à linguagem JavaScript, incluindo uma nova notação de função de seta .

Sua tarefa é escrever um transpiler básico de ES6 para ES5. Dada apenas uma seta ES6 funcionar como entrada, envie sua contraparte compatível com ES5.

É ! Que ganhe o programa mais curto em bytes!


O básico

Uma função de seta se parece com isso:

(a, b, c) => { return a + b - c }

E sua expressão equivalente da função ES5 se parece com isso:

function(a, b, c) { return a + b - c }

Em geral, você pode copiar o corpo da função (tudo entre os chavetas) literalmente.


Declaração de retorno implícita

Em vez de um corpo com chaves, uma única expressão pode ser usada; o resultado dessa expressão é retornado.

(a, b, c) => a + b - c

function(a, b, c) { return a + b - c }

Outro exemplo:

(a, b, c) => (a + 1, b - 2 * c / 3)

function(a, b, c) { return (a + 1, b - 2 * c / 3) }

Novamente, você pode simplesmente copiar a expressão literalmente - MAS tenha cuidado para não gerar uma quebra de linha entre ela e a returnpalavra-chave para evitar a inserção automática de ponto e vírgula!


Um argumento

Parênteses são opcionais se um argumento for fornecido.

foo => { return foo + 'bar' }

function(foo) { return foo + 'bar' }

Espaço em branco

Por fim, você deve poder contabilizar qualquer número de caracteres de espaço em branco (espaço, tabulação, nova linha) antes ou depois de parênteses, variáveis, vírgulas, chaves e a seta *.

 ( o   ,  O
     , _    )=>{

    return                                     "Please don't write code like this."
}

A decisão de escolher ou não preservar o espaço em branco na saída depende de você. Mantenha-os, remova-os ou adicione seus próprios - apenas verifique se é um código válido!

* É tecnicamente ilegal uma flecha aparecer imediatamente após uma quebra de linha, mas duvido que esse fato possa ajudá-lo. :)


Uma maneira rápida de validar sua saída:

Entre var foo = <your output>; foo()no console do navegador. Se não reclamar, provavelmente você está no caminho certo.


Mais regras para os assistentes:

  • A entrada é uma função de seta ES6 sintaticamente válida.
  • Assuma que o corpo da função é ES5-compatível (e não faz referência a this, super, arguments, etc.). Isso também significa que a função nunca conterá outra função de seta (mas você não pode assumir que "=>" nunca ocorrerá dentro do corpo).
  • Os nomes das variáveis ​​consistirão apenas em letras latinas básicas $e _.
  • Você não precisa transpilar os recursos do ES6 que não estão listados acima (parâmetros padrão, operador de descanso, destruturação etc.).
  • O espaço após a returndeclaração é opcional, se seguido por (, [ou {.
  • Não é estritamente necessário corresponder exatamente aos meus casos de teste - você pode modificar o código quantas vezes precisar, se isso ajudar a diminuir sua contagem de bytes. Realmente, desde que você produza uma expressão de função ES5 sintaticamente válida e funcionalmente equivalente, você estará de acordo!
darrylyeo
fonte
Podemos assumir que a entrada é uma função de seta sintaticamente válida e nada mais?
ETHproductions
Um exemplo seria a =>\na: onde function(a){ return\na }realmente retornaria, undefinednão importa qual seja o valor a. Precisamos lidar com isso?
ETHproductions
@ETHproductions Você não adora esses pontos e vírgulas auto-mágicas!
21417 Neil
Obteremos funções ES6 aninhadas?
user41805
Podemos assumir que a entrada conterá apenas uma =>?
matemática viciado em

Respostas:

5

JavaScript (ES6), 123 110 100 97 bytes

Guardado 3 bytes graças a @Neil

s=>s.replace(/\(?(.*?)\)?\s*=>\s*([^]*)/,(_,a,b)=>`function(${a})${b[0]=='{'?b:`{return ${b}}`}`)

Assume que a entrada é uma função de seta sintaticamente válida e nada mais. Lida corretamente com o caso a =>\na, embora o manuseio não seja mais curto, tanto quanto posso dizer.

Saída quando o código é executado por si mesmo:

function(s){return s.replace(/\(?(.*?)\)?\s*=>\s*([^]*)/,(_,a,b)=>`function(${a})${b[0]=='{'?b:`{return ${b}}`}`)}

Posso salvar 9 bytes com um formato possivelmente inválido:

s=>s.replace(/\(?(.*?)\)?\s*=>\s*({?)([^]*?)}?$/,(_,a,z,b)=>Function(a,z?b:'return '+b))

Saída para si mesma:

function anonymous(s) {
return s.replace(/\(?([^=)]*)\)?\s*=>\s*({?)([^]*?)}?$/,(_,a,z,b)=>Function(a,z?b:'return '+b))
}

(Especificamente, function anonymousé com isso que estou preocupado.)

ETHproductions
fonte
É uma pena que sua própria função contenha uma outra função de seta, para que, quando executada por ela mesma, não seja totalmente transpilada.
21417 Neil
Eu acho \(?(.*?)\)?\s*=>que você pode economizar 3 bytes.
Neil
2

Retina, 86 80 79 bytes

^ ([^ (] *?) =
($ 1) =
s (`\ s * $

> \ s * (. * [^}]) $
> {devolver $ 1}
) `(. *?) => (. *)
função $ 1 $ 2

Experimente Online!

Guardou um byte graças a Neil

Economizou 6 bytes com a ajuda da ETHproductions

Editar: corrigida a possibilidade de novas linhas no corpo da função.

Solução de 75 bytes, supondo que a entrada não contenha §: Experimente on-line!

viciado em matemática
fonte
1
Você pode usar um pilcrow em vez de \nsalvar um byte.
Neil
1
Isso parece remover quebras de linha no corpo da função, o que pode alterar a funcionalidade.
darrylyeo
Eu acho que \sinclui , então a linha três pode ser \s*$para salvar 4 bytes.
ETHproductions
@ETHproductions Parece \scorresponder apenas quando a sopção de configuração é adicionada. No entanto, ele salvou-me alguns bytes
matemática viciado em
0

PHP, 112 bytes

preg_match("#\(??(.*)\)?=>(\{?)(.*$)#U",$argn,$m);echo"function($m[1])",trim($b=$m[3])[0]=="{"?$b:"{return $b}";

recebe entrada do STDIN; correr com-R

Titus
fonte