logfuck

From Esolang
Jump to navigation Jump to search
logfuck
Paradigm(s) imperative
Designed by User:Palaiologos
Appeared in 2025
Computational class Turing-complete
Reference implementation Unimplemented
Influenced by Brainfuck
File extension(s) .lf

Synopsis

Brainfuck where things are O(log n) rather than O(n). An interesting way of solving the problem of Brainfuck's relative verbosity not by introducing RLE or similar operations (which make Brainfuck still struggle with linear-time copy and addition) but by changing the underlying data structures and their exposed format.

Spec

The language operates on an infinitely downwards-growing binary tree. The state of the program is the tree, the currently seen node and the 16-bit unsigned numbers associated with each node. The following instructions are supported:

- ^ - Go to the parent node.

- < - Descend to the left child, creating with zero if necessary.

- > - Descend to the right child, creating with zero if necessary.

- v - Pop out the lowest bit of the current node's value.

- . - Take lowest 8-bits of the node's value and print it as an US-ASCII character.

- , - Input a byte and consider it the current node's value. On EOF writes 0xFFFE.

- [A;B] - If the lowest bit of the current node is zero, execute A. Otherwise execute B.

- (A) - Execute A until the current node's value is non-zero.

- 0 - Shift in a zero in the current node's value.

- 1 - Shift in an one in the current node's value.

Interpreters

Initial attempt in Perl by Kamila Szewczyk. Non-spec behaviour is printing the current node's value at exit.

#!/usr/bin/perl
use strict;
use warnings;
sub n{my$v=shift//0;{v=>$v,l=>undef,r=>undef,p=>undef}}
sub l{my$n=shift;$n->{l}//=n(0);$n->{l}{p}=$n;$n->{l}}
sub r{my$n=shift;$n->{r}//=n(0);$n->{r}{p}=$n;$n->{r}}
sub pd{my($c,$s)=@_;my($p,$d,$m)=($s,1,-1);while(++$p<@$c&&$d){$d+=($c->[$p]eq'[')-($c->[$p]eq']');$m=$p if$c->[$p]eq';'&&$d==1&&$m<0}die"Parse error"if$d||$m<0;(join'',@$c[$s..$m-1]),(join'',@$c[$m+1..$p-2]),$p-1}
sub pl{my($c,$s)=@_;my($p,$d)=($s,1);$d+=($c->[++$p]eq'(')-($c->[$p]eq')')while$p<@$c&&$d;die"Parse error"if$d;(join'',@$c[$s..$p-2]),$p-1}
sub ex{my($s,$pr)=@_;local$_;my@c=split//,$pr;for(my$p=0;$p<@c;$p++){$_=$c[$p];/^(\^|<|>|0|1|\[|\(|\.|,)$/||next;/^(\^)/&&do{$s->{c}=$s->{c}->{p}if$s->{c}->{p};next};/^</&&do{$s->{c}=l($s->{c});next};/^>/&&do{$s->{c}=r($s->{c});next};/^0/&&do{$s->{c}->{v}=($s->{c}->{v}<<1)&0xFFFF;next};/^1/&&do{$s->{c}->{v}=((($s->{c}->{v}<<1)|1)&0xFFFF);next};/^\[/&&do{my($a,$b,$e)=pd(\@c,++$p);ex($s,($s->{c}->{v}&1)?$b:$a);$p=$e;next};/^\(/&&do{my($co,$e)=pl(\@c,++$p);ex($s,$co)while$s->{c}->{v};$p=$e;next};/^\./&&do{print chr($s->{c}->{v}&0xFF);next};/^,/&&do{my$i=getc STDIN;$s->{c}->{v}=defined$i?ord($i)&0xFFFF:0xFFFE;next}}}
my$r=n(0);my$s={c=>$r,r=>$r};ex($s,$ARGV[0]||die"Usage: $0 '<program>'\n");print$s->{c}->{v},"\n"