Entry 6366
Brainfuck
Submitted by anonymous
on Aug. 25, 2010 at 1:30 p.m.
Language: Prolog. Code size: 7.5 KB.
:- dynamic ptr/1. :- dynamic cell/2. :- dynamic memo/2. % le predicat qui lit stdin. bfread :- writeln('Tapez votre code entre quote ('') suivi d''un point'), read(A), atom_codes(A, L), bf(L). % le prédicat bf qui prend une chaine en argument bf(L) :- maplist(char_code, L1, L), writef('%s\n', [L]), retractall(ptr(_)), retractall(cell(_,_)), % pour la memorisation des codes de boucle retractall(memo(_,_)), % on cree le pointeur index dans le tableau, initialise a 0. assert(ptr(0)), % on cree le tableau de 30 000 valeurs initialisees à 0 forall(between(0, 30000, I), assert(cell(I, 0))), bf(L1, _, _). % le parsing des commandes hors boucle bf(['>'|B]) --> {incrptr}, bf(B). bf(['<'|B]) --> {decrptr}, bf(B). bf(['+'|B]) --> {incrcell}, bf(B). bf(['-'|B]) --> {decrcell}, bf(B). bf(['.'|B]) --> {putchar}, bf(B). bf([','|B]) --> {getchar}, bf(B). % on rencontre un début de boucle, bf(['['|B]) --> {% on doit sauter au ']' suivant carnull, % on n'a pas besoin de mémoriser le saut skip(B, 0, U-U, _T, B1)}, bf(B1). % on rencontre un début de boucle, bf(['['|B]) --> {% ici on commence la boucle, il faut memoriser les caracteres lus \+ carnull, % on est au premier niveau d'imbrication de boucle % on n'a pas de code de boucle a memoriser asserta(memo(0, X-X))}, % utilisation des differences-listes % pas de code mémorise, donc liste vide symbolisee par U-U en "ecriture dl". bfmemo(B, U-U). % tout caractere inconnu est considere comme commentaire donc oublie bf([_|B]) --> bf(B). % quand c'est fini, c'est fini bf([]) --> []. % le parsing des commandes de boucle % Il faut les mémoriser bfmemo(['>'|B], T) --> {incrptr, append_dl(T, ['>' | U]-U, T1)}, bfmemo(B, T1). bfmemo(['<'|B], T) --> {decrptr, append_dl(T, ['<' | U]-U, T1)}, bfmemo(B, T1). bfmemo(['+'|B], T) --> {incrcell, append_dl(T, ['+' | U]-U, T1)}, bfmemo(B, T1). bfmemo(['-'|B], T) --> {decrcell, append_dl(T, ['-' | U]-U, T1)}, bfmemo(B, T1). bfmemo(['.'|B], T) --> {putchar, append_dl(T, ['.' | U]-U, T1)}, bfmemo(B, T1). bfmemo([','|B], T) --> {getchar, append_dl(T, [',' | U]-U, T1)}, bfmemo(B, T1). bfmemo(['['|B], T) --> {% le caractere pointe est null, on saute % et on memorise la partie sautee carnull, skip(B, 0, ['['|W]-W, SF, B1), append_dl(T, SF, T1) }, bfmemo(B1, T1). bfmemo(['['|B], T) --> { % le caractere pointé est non null \+carnull, append_dl(T, ['['|U]-U, T1), memo(N, _), N1 is N+1, % on debute une nouvelle boucle % on memorise le debut de la precedente boucle asserta(memo(N1, T1)) }, bfmemo(B, V-V). bfmemo([']'|B], T) --> { % Si l'octet pointe est null, on continue carnull, % on recupere les donnees memorisees memo(N, L), % ici on n'est pas au niveau 0 N \= 0, !, % on efface le niveau retract(memo(N,L)), append_dl(T, [']'|U]-U, T1), append_dl(L, T1, T2) }, % on continue en bfmemo bfmemo(B, T2). bfmemo([']'|B], _T) --> { % Si l'octet pointe est null, on continue carnull, % on recupere les donnees memorisees memo(N, L), % ici on est au niveau 0 N = 0, !, % on efface tout retract(memo(N,L)) }, % on continue en bf bf(B). bfmemo([']'|B], T) --> { % ici on repart au debut de la boucle \+ carnull, % on recree la liste des donnees à partir du debut de la boucle append_dl(T, [']'|V]-V, T1-[]), append(T1, B, T2) }, bfmemo(T2, U-U). % tout caractère inconnu est ignore bfmemo([_C|B], T) --> bfmemo(B, T). % la concatenation des differences-listes, en temps constant ! append_dl(X1-X2, X2-X3, X1-X3). % skip(Liste, Niveau SC, SR, LR) % Permet le saut au ']' suivant % Liste : la liste a travailler % Niveau : niveau d'imbrication des [] % SC : dl-partie a sauter en construction % SR : dl-partie a sauter resultat % LR : Liste resultat restant a etudier % on termine la recherche skip([']'|B], 0, SC, ST, B) :- append_dl(SC, [']'|U]- U, ST). % on baisse d'un niveau d'imbrication skip([']'|B], N, SC, ST, BF) :- N1 is N-1, append_dl(SC, [']'|U]- U, SC1), skip(B, N1, SC1, ST, BF). % on augmente le niveau d'imbrication skip(['['|B], N, SC, ST, BF) :- N1 is N+1, append_dl(SC, ['['|U]- U, SC1), skip(B, N1, SC1, ST, BF). skip([A|B], N, SC, ST, BF) :- append_dl(SC, [A|U]- U, SC1), skip(B, N, SC1, ST, BF). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Les primitives du langage % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% incrptr :- retract(ptr(N)), N1 is N+1, assert(ptr(N1)). decrptr :- retract(ptr(N)), N1 is N-1, assert(ptr(N1)). incrcell :- ptr(N), retract(cell(N, V)), V1 is (V+1) mod 256, assert(cell(N, V1)). decrcell :- ptr(N), retract(cell(N, V)), V1 is V-1, assert(cell(N, V1)). putchar :- ptr(N), cell(N, V), char_code(A, V), write(A). getchar :- ptr(N), retract(cell(N, _)), read(A), ( number(A) -> number_codes(A, [V]); char_code(A,V)), assert(cell(N, V)). % la valeur courante est-elle nulle carnull :- ptr(N), cell(N, 0). % quelques prog d'exemples bf_test :- /* writeln('Hello World !'), L = "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++ .<<+++++++++++++++.>.+++.------.--------.>+.>.", */ /* writeln('Addition'), L = ",>++++++[<-------->-],[<+>-]<.", */ /* writeln('Multiplication'), L = ",>,>++++++++[<------<------>>-]<<[>[>+>+<<-]>>[<<+>>-]<<<-] >>>++++++[<++++++++>-]<.>.", */ /* writeln('Affiche le caractère entre'), L = ",[.,]", */ /* writeln('Mise en majuscule de la saisie'), L = ",----------[----------------------.,----------]", */ /* writeln('recherche du minimum de deux nombres'), L = ",>,[->>+<<]+<[->>>[>>>>>+<<<<<->+<<]<[>]>>>>>[-<<->>>>>>>]<[>]<<<<<<]>[>>>>->]<<<<<<[-]>[-]>>[-]>.", */ writeln('Calcul des nombres de Fibonacci'), L =">++++++++++>+>+[[+++++[>++++++++<-]>.<++++++[>--------<-]+<<<]>.>>[ [-]<[>+<-]>>[<<+>+>-]<[>+<-[>+<-[>+<-[>+<-[>+<-[>+<- [>+<-[>+<-[>+<-[>[-]>+>+<<<-[>+<-]]]]]]]]]]]+>>>]<<<]", /* writeln('Test BlueStorm sur les carres '), L = "+++++++++++++++++++++++++[>+++++<-]>[<+++++>-]+<+[>[>+>+<<-]++>>[<<+>>-]>>>[-]++>[-]+>>>+[[-]++++++>>>]<<<[[<++++++++<++>>-]+<.<[>----<-]<]<<[>>>>>[>>>[-]+++++++++<[>-<-]+++++++++>[-[<->-]+[<<<]]<[>+<-]>]<<-]<<-]", */ bf(L).
This snippet took 0.03 seconds to highlight.
Back to the Entry List or Home.