Este projeto foi criado como trabalho da matéria de compiladores. Chefe é uma linguagem de programação esotérica, onde os programas se parecem com receitas de culinária. Criada originalmente por David Morgan-Mar (disponível em http://www.dangermouse.net/esoteric/chef.html). A sintaxe e a especificação da linguagem foram traduzidas para o português.
- Receitas de programas devem almejar não apenas a compilação, mas também serem fáceis de preparar e deliciosas.
- Receitas usam o sistema internacional de unidades, mas podem usar medidas tradicionais da culinária como colheres, xícaras e copos.
Todas as receitas possuem ingredientes! Ingredientes armazenam valores individuais. Ingredientes líquidos serão interpretados como caracteres Unicode, enquanto ingredientes secos ou não especificados serão interpretados como números.
Chefe tem acesso a um estoque ilimitado de tigelas e assadeiras. Estas podem conter ingredientes. Ingredientes numa tigela ou numa assadeira são ordenados como uma pilha de panquecas. Novos ingredientes são inseridos no topo, e se ingredientes são removidos, serão também removidos do topo. Note que se o valor de um ingrediente muda, o valor na tigela ou assadeira continua igual.
Múltiplas tigelas ou assadeiras são referencias com um identificador ordinal (a 2ª tigela
, por exemplo). Se nenhum identificador é utilizado, então a receita só possui um deste utensílio. Identificadores ordinais devem ser seguidos de uma terminação, ª
ou º
, para indicar o gênero.
Os itens a seguir aparecem numa receita de Chefe. Alguns são opcionais. Itens devem aparecer na ordem mostrada abaixo, com uma linha em branco (duas quebras de linha) entre itens.
O título da receita descreve, em poucas palavras, o que o programa faz. Por exemplo: "Suflê de Olá Mundo" ou "Números Fibonacci com Caramelo". O título é sempre a primeira linha de uma receita, seguida de um ponto final.
titulo-da-receita.
Comentários são constituídos de um parágrafo após o título da receita. Comentários são opcionais.
Lista os ingredientes que serão usados pelo programa. A sintaxe é descrita abaixo.
Ingredientes. [valor-inicial] [medida [tipo-da-medida]] nome-do-ingrediente [valor-inicial] [medida [tipo-da-medida]] nome-do-ingrediente
Cada ingrediente é listado em uma linha. O valor inicial é um número, e é opcional. Tentar utilizar um ingrediente sem um valor definido é um erro de tempo de execução. A medida
pode ser qualquer uma das seguintes medidas:
g [de] | kg [de] | pitada[s] [de]
: Indicam ingredientes sólidos.ml [de] | l [de] | fio[s] [de]
: Indicam ingredientes líquidos.colher[es] [de [sopa | chá]] [de] | xícara[s] [de] | copo[s] [de]
: Indicam tanto ingredientes sólidos como líquidos.
O nome do ingrediente pode ser qualquer frase, e pode incluir espaços em branco. A lista de ingredientes é opcional. Se um ingrediente é repetido, o novo valor é usado e os valores antigos são descartados.
Tempo de preparo: tempo (hora[s] | minuto[s]).
O tempo de preparo é opcional. O tempo
é um número.
Pré-aqueça o forno a temperatura °C.
Algumas receitas requerem aquecimento. A temperatura do forno é opcional.
Modo de preparo. métodos de preparação
O modo de preparo contém as instruções para a receita. Estas são escritas em sentenças. Quebras de linha são ignoradas no modo de preparo de uma receita. Instruções válidas são:
-
Retire [o|a][s]
ingrediente
do refrigerador.
: Lê um valor doSTDIN
para o ingrediente, sobrescrevendo qualquer valor anterior. -
Coloque [o|a][s]
ingrediente
na [iª] tigela.
: Coloca um ingrediente na iª tigela. -
Sove [o|a][s]
ingrediente
na [iª] tigela.
: Remove o valor do topo da iª tigela e o coloca no ingrediente. -
Adicione [o|a][s]
ingrediente
[na [iª] tigela].
: Adicona o valor de ingrediente ao valor do ingrediente no topo da iª tigela, e guarda o resultado na iª tigela. -
Remova [o|a][s]
ingrediente
[da [iª] tigela].
: Subtrai o valor de ingrediente do valor do ingrediente no topo da iª tigela, e guarda o resultado na iª tigela. -
Combine [o|a][s]
ingrediente
[na [iª] tigela].
: Multiplica o valor de ingrediente pelo valor do ingrediente no topo da iª tigela, e guarda o resultado na iª tigela. -
Divida [o|a][s]
ingrediente
[na [iª] tigela].
: Divida o valor de ingrediente pelo valor do ingrediente no topo da iª tigela, e guarda o resultado na iª tigela. -
Adicione os ingredientes sólidos [na [iª] tigela].
: Adiciona o valor de todos os ingredientes sólidos e guarda o resultado na iª tigela. -
Liquidifique [o|a][s]
ingredientes.
: Torna o ingrediente em líquido, ou seja, um caractere Unicode para saída de dados. -
Liquidifique o conteúdo da [iª] tigela.
: Torna todos os ingredientes da iª tigela em líquido, ou seja, em caracteres Unicode para saída de dados. -
Misture [a [iª] tigela] por
número
minutos.
: Empurra o primeiro ingredientes na iª tigela, tal que o ingrediente no topo vai número de lugares pra baixo e todos os outros ingredientes no caminho são mandados um lugar pra cima. Se não há este número de ingredientes na tigela, o ingrediente no topo vai para a posição mais abaixo, e todos os outros sobem um lugar. -
Misture [o|a][s]
ingrediente
na [iª] tigela.
: Empurra o primeiro ingredientes na iª tigela, tal que o ingrediente no topo desde o valor de ingrediente lugares pra baixo e todos os outros ingredientes no caminho são mandados um lugar pra cima. Se não há este número de ingredientes na tigela, o ingrediente no topo vai para a posição mais abaixo, e todos os outros sobem um lugar. -
Misture bem [a [iª] tigela].
: Randomiza a ordem dos ingredientes na iª tigela. -
Limpe a [iª] tigela.
: Remove todos os ingredientes da iª tigela. -
Despeje o conteúdo da [iª] tigela na [jª] assadeira.
: Copia todos os ingredientes da iª tigela para a jª assadeira, mantendo a ordem os colocando em cima de qualquer coisa que já esteja na assadeira. -
Verbo
[o|a][s]
ingrediente.
: Marca o começo de um loop. Deve aparecer como um par com a declaração abaixo. O loop é executado desta forma: o valor do ingrediente é checado. Se é diferente de zero, o corpo do loop é executado até chegar na declaração até. O valor do ingrediente é checado novamente. Se é diferente de zero, o loop executa de novo. Se em qualquer checagem o valor do ingrediente for zero, o loop para e a execução continua na declaração depois do até. Loops podem ser aninhados. -
Verbo
[[o|a][s] ingrediente] até [que]
frase.
ouVerbo
até [que] [[o|a][s] ingrediente]
frase.
: Marca o fim de um loop. Deve aparecer como um par com a declaração acima. O verbo nesta declaração é arbitrário e ignorado. Se o ingrediente aparece nesta declaração, seu valor é decrementado por 1 quando esta declaração for executada. O ingrediente não precisa ser o mesmo ingrediente do começo do loop. -
Deixe descansar.
: Causa o fim prematuro e imediato do loop mais interno em que esta declaração aparece e continua na declaração após o até. -
Sirva com
receita-auxiliar.
: Invoca um sous-chef para imediatamente preparar a receita-auxiliar. O chefe que o chamou aguarda até que o sous-chef acabe para continuar a sua receita. Veja a seção de receitas auxiliares abaixo. -
Refrigere [por
número
horas].
: Causa o fim prematuro e imediato da receita em que essa declaração aparece. Se for uma receita auxiliar, a receita acaba e a primeira tigela do sous-chef é passada de volta para o chefe que o chamou, normalmente. Se o número de horas for especificado, a receita vai imprimir as número primeiras assadeiras (veja a seção Rendimento abaixo) antes de encerrar.
A última frase de uma receita é a quantidade de porções que ela rende, ou, a quantidade de pessoas que ela serve.
Rendimento: número-de-porções (porções | pessoas).
Este comando escreve para o STDOUT
o conteúdo das primeiras número-de-porções
assadeiras. Começa pela 1ª assadeira
, removendo os valores do topo um por um e os imprimindo, até que a assadeira fique vazia. Então, progride para a próxima assadeira, até que todas sejam impressas.
O rendimento é opcional numa receita, mas é necessário se o programa tiver qualquer saída!
Algumas receitas pequenas podem ser necessárias para produzir ingredientes especializados para a receita principal (como molhos, ou caldas). Eles são listados na receita principal. Receitas auxiliares são feitas por sous-chefs, então eles têm o próprio conjunto de tigelas e assadeiras que o Chefe principal nunca vê, mas pode copiar todas as tigelas e assadeiras em uso pelo chef que o chamou. Mudanças nessas tigelas e assadeiras não interferem nas tigelas e assadeiras do chef que o chamou. Quando a receita auxiliar termina, os ingredientes na 1ª tigela
são passados para a 1ª tigela
do chefe que o chamou.
Uma receita auxiliar pode ter todos os itens de uma receita principal.
-
Bolo de Olá Mundo com cobertura de chocolate (Esta funciona como receita de verdade! Originalmente publicada por Mike Worth nesse site).