Você precisa escrever um intérprete para um idioma legal chamado Chicken !
Você deve ler um programa Chicken a partir de um arquivo, entrada padrão, argumentos de programa ou função, ou o que for mais conveniente para o seu idioma, bem como a entrada para o programa.
Você deve imprimir ou retornar o resultado da interpretação do programa de acordo com a especificação do idioma Chicken.
Mais descrição sobre o idioma .
Visão Geral do Programa Chicken
O frango opera em uma única pilha, que compõe todo o seu modelo de memória. À medida que as instruções são executadas, o programa pressiona e pop valores da pilha, mas também existem instruções que permitem ao programa modificar outras partes da pilha à vontade.
Existem três segmentos na pilha:
- Os registros, nos índices 0 e 1. O índice 0 é uma referência à própria pilha e o índice 1 é uma referência à entrada do usuário. Usado principalmente para a instrução 6 (veja abaixo).
- O código carregado: para cada linha de código, há célula neste segmento que contém o número de "galinhas" na linha. Isso é preenchido com um 0 (opcode para encerrar o programa) no final.
- A pilha real do programa, na qual os valores são enviados / atualizados à medida que o programa é executado. Observe que os segmentos não são isolados, o que significa que é possível criar código auto-modificável ou executar código a partir desse segmento do espaço de pilha.
The Chicken ISA
O conjunto de instruções do Chicken é baseado no número de vezes que a palavra "chicken" aparece em cada linha do programa. Uma linha vazia finaliza o programa e imprime o valor mais alto na pilha.
O conjunto de instruções Chicken, pelo número de "chicken" s por linha:
- Empurre a string literal "chicken" para a pilha
- Adicione os dois principais valores da pilha como números naturais e pressione o resultado.
- Subtraia os dois principais valores como números naturais e empurre o resultado.
- Multiplique os dois principais valores como números naturais e pressione o resultado.
- Compare dois valores principais para igualdade, pressione 1 se forem iguais e 0 caso contrário.
- Veja a próxima instrução para determinar de qual fonte carregar: 0 carga da pilha, 1 carga da entrada do usuário. Pontos principais da pilha para endereçar / indexar para carregar da fonte especificada; carregue esse valor e empurre-o para a pilha. Como esta é uma instrução de largura dupla, o ponteiro da instrução ignora a instrução usada para determinar a fonte.
- Pontos principais da pilha para endereçar / indexar para armazenar. O valor abaixo disso será exibido e armazenado na pilha no índice especificado.
- O topo da pilha é um deslocamento relativo para o qual pular. Se o valor abaixo desse valor for verdadeiro, o programa passará pelo deslocamento.
- Interpreta o topo da pilha como ascii e pressiona o caractere correspondente.
- (10 + N) Coloca o número literal n-10 na pilha.
Exemplo
Suponha que o programa seja:
chicken chicken chicken chicken chicken chicken chicken chicken chicken chicken chicken
chicken chicken chicken chicken chicken chicken
(an empty line)
(Um programa para gatos. Observe que a linha vazia é necessária devido à linha anterior ter 6 "galinhas".)
Entrada fornecida ao programa Chicken
Chicken
Resultado
Chicken
A implementação de referência Chicken.js .
Detecção de erro
O intérprete deve deixar um erro e terminar quando qualquer palavra que não seja "frango" estiver presente na fonte.
Boa sorte!
fonte
Respostas:
Ruby, 335 bytes
Pega o nome do arquivo de entrada como argumento da linha de comando e recebe a entrada do usuário (para a instrução nº 6) de STDIN.
Devido ao fato de Ruby "truthy" (tudo, exceto
false
enil
) ser diferente do Javascript "truthy" (Ruby truthy plus0
, strings vazias etc.), pode haver alguns casos extremos em que os programas que funcionam bem em um interpretador JS falham nesse caso. por causa da instrução 8, como se estivesse""
na pilha. Corrigi o maior caso, porém, que é falso0
.Funciona com o programa de teste e o programa Hello World no site do Chicken.
Explicação
O intérprete começa imediatamente executando uma correspondência de expressão regular em
/^(chicken|\s)*$/m
todo o arquivo ($<.read
), o que garante que o arquivo contenha nada além dechicken
espaço em branco. No Ruby, esse operador retorna o índice para a correspondência ounil
se não foi encontrado.Dois truques de economia de bytes são usados aqui: em vez de corresponder diretamente
chicken
, o operador de substituição de string#{}
é usado para atribuir essa string a uma variável para mais tarde (salva 1 byte) e ao armazenar o conteúdo do arquivo em uma variável para processamento , ele anexa duas novas linhas para permitir que alines
função posteriormente adicione naturalmente um extra0
ao final do conjunto de instruções. (São necessários dois por causa da nova linha à direita ignorada, necessária para o programa Chicken).O erro usado é o
NoMethodError: undefined method '+@' for nil:NilClass
que é feito envolvendo a correspondência de expressões regulares em parênteses e colocando uma+
na frente. Se o arquivo corresponder ao padrão, você obtém+0
, que avalia0
e prossegue normalmente.Em seguida, a pilha é montada. A lista inicial deve ser criada antes que a referência própria à pilha possa ser atribuída, para que um espaço reservado seja usado e depois substituído. O ponteiro de instrução está definido como em
1
vez de,2
porque não existem operadores pós-incremento no Ruby.Por fim, ele usa o truque lambda de @BassdropCumberwubwubwub para determinar o que colocar na pilha a seguir. Se uma operação não coloca nada na pilha, o intérprete simplesmente gera um valor extra para que a pilha permaneça a mesma. (Isso economiza bytes ao adicionar uma operação de envio a cada lambda.)
Código não destruído:
fonte
Javascript ES6, 398 bytes
De longe, o golfe mais longo que já fiz, tenho certeza de que isso pode ser melhorado, mas meu cérebro não reconhece outra coisa senão
chicken
neste momento.Vou editar a explicação quando meu cérebro começar a funcionar novamente. Aqui está uma versão um pouco não destruída por enquanto.
Emite um valor de falsey (0) para tudo o que não é
chicken
Experimente aqui
fonte
if(!/^(chicken\s?)+$/.test(a))throw'There are any words except "chicken".';
logo no início do seu intérprete.stderr
ou sair do programa com um código diferente de zero. Algo que mostra que algo não está certo. Em Javascript, você pode lançar uma exceção, retornar um objeto Error, mostrar um alerta, gravar no console usandoconsole.erro()
ou algo semelhante.