Eu projetei uma linguagem na qual a aritmética de ponteiros é a principal ferramenta de programação.
Aqui estão alguns exemplos.
(print 0 to 8)
=9[>1=9-*-1.>-1-1]
(print 1 to 10 with spaces in between, character literal extension used)
=1[.>1=10-*-1[>1=' '!>-2+1;-2];1]='\n'!
(compute the factorial of 10)
=10>1=*-1-1[>-1**1>1-1]>-1.
(print "hi")
=104!=105!
(print "hi" with extension for arrays)
={104,105,0}[!>1]
(print "Hello, world!" with extension for C-style string literals)
="Hello, world!"[!>1]
Especificação de idioma
A definição da linguagem é muito simples. Você entenderá com muita facilidade se tiver experiência com C, mas não assumirei isso.
Todo programa no PointerLang possui o ponteiro , em resumo P,. Você pode pensar nisso como uma variável global única oculta, que você pode controlar usando comandos . Pinicialmente aponta para o início da matriz . Cada elemento da matriz tem o tipo intque é um número inteiro assinado de 32 bits.
Para programadores C
int32_t *P = malloc(1000);
No PointerLang, existem comandos e argumentos . Um argumento é aquele intque deve vir após um comando. Todos os comandos são executados da esquerda para a direita, a menos que seja especificado o contrário. A seguir está a lista de comandos. Asignifica argumento. Um comando sem Ameios não leva a um argumento. Um comando com Adeve receber um argumento. Dentro dos parênteses está a expressão C equivalente.
=A: atribua A em P (*P = A)+A: adicione A em P (*P += A)-A: subtraia A em P (*P -= A)*A: multiplicar por A em P (*P *= A)/A: divida por A em P (*P /= A)>A: moverPporA(P += A).: imprime o número inteiro em P (printf("%d", *P))!: imprime o número inteiro em P como ASCII (printf("%c", (char)*P))[: se o valor em P for 0, vá para o comando após o próximo](while (*P) {)]: vá para o anterior[que é o par correspondente (});A: seAfor positivo, vá para o comando após o próximoAth]; seAfor negativo, vá para oAth[vindo antes; se A for 0, não faça nada.
Um literal inteiro é um argumento.
Os dois a seguir são argumentos especiais que aceitam um argumento.
-A: avaliado como um argumento com o mesmo valor absolutoAe o sinal oposto deA; menos unário*A: MovimentoPporA, avaliar o valor emP, movimentoPpor-A(P[A])
Todos os comentários no PointerLang estão entre parênteses (comment).
Programa de exemplo
Este programa que conta de 1 a 10 é um bom exemplo para concluir sua compreensão.
(print 1 to 10 with spaces in between)
=1[.>1=10-*-1[>1=32!>-2+1;-2];1]=10!
Tenha cuidado ao interpretar -*-1. -é o comando e *-1é o argumento. Um literal inteiro indica efetivamente o final de um par de argumentos de comando.
Pode ser traduzido para C com correspondência 1 para 1, conforme
int main(void) {
int32_t *P = malloc(1000);
*P = 1; // =1
l:
while (*P) { // [
printf("%d", *P); // .
P += 1; // > 1
*P = 10; // =10
*P -= P[-1]; // -*-1
while (*P) { // [
P += 1; // >1
*P = 32; // =32
printf("%c", (char)*P); // !
P += -2; // >-2
*P += 1; // +1
goto l; // ;-2
} // ]
break; // ;1
} // ]
*P = 10; // =10
printf("%c", (char)*P); // !
return 0;
}
Extensões podem ser aplicadas a essa linguagem, como literais de caracteres, matrizes, literais de cadeias etc., mas você não precisa implementá-las, para simplificar.
O desafio
Você precisa implementar os principais recursos detalhados na seção Especificação de Idioma e nas NOTAS abaixo. Experimente a sua linguagem de programação favorita, escrevendo o programa mais curto possível.
NOTA1: O tamanho da matriz é indefinido. Mas deve ser grande o suficiente para resolver a maioria dos problemas.
NOTA2: Estouro de número inteiro é indefinido.
NOTA3: A especificação define apenas o resultado ou o efeito de determinadas construções de linguagem. Por exemplo, você não precisa seguir exatamente as etapas na definição do argumento *.
NOTA4: Quaisquer caracteres que não sejam comandos, argumentos ou comentários, espaços em branco são ignorados. =104!=105!é o mesmo que = 1 0 4! = 1 05 !por exemplo.
NOTA5: Comentários não são aninhados. ((comment))é um erro de sintaxe.
NOTA6: Fiz uma alteração de última hora para corrigir um buraco no meu idioma. O ~comando agora não é utilizado e ;sempre recebe um argumento.
NOTA7: Todo literal inteiro é decimal.
=9[>1=9-*-1.>-1-1]imprime de 0 a 9? Depois de pontuar 8 porque P [0] = 1, subtrai 1 imediatamente antes do final do loop, o que faz com que P [0] = 0 e, quando ele inicia o loop novamente, deve sair porque P [0] = 0, para que exemplo deve imprimir apenas de 0 a 8. Ou estou realmente confuso?