Skip to content

Instantly share code, notes, and snippets.

@tompng
Last active June 2, 2018 15:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tompng/0a9a407b57d34b75c0b46c6a8b7e56c5 to your computer and use it in GitHub Desktop.
Save tompng/0a9a407b57d34b75c0b46c6a8b7e56c5 to your computer and use it in GitHub Desktop.
s5: brainf*ck compiler, banner, quine
def bfrun bfcode
bforder = '[><+-,.]'
bftrans=%(while(x[i]!=0);i+=1;i-=1;x[i]+=1;x[i]-=1;x[i]=$<.getc&.ord||0;$><<x[i].chr;end).split(?;);
x=Hash.new{0}
i=0
eval bfcode.chars.map{|a|bftrans[bforder.index(a)]}.compact*';'
end
bfrun %(++++[->++++[->+++++++>+++<<]<]>>++++.--.<+++[->---<]>.[<+<+>>-]<<------.>++.>>++.--.+.+++++++.)
[116, 114, 105, 99, 107, 50, 48, 49, 56]
# at_exit{a=[];C.map{|a,b|a[a.to_i,b.size]=b.chars};eval(a*'')}
#
# a=?;*9999
# q=->(i,s){a[i.to_i,s.size]=s}
# at_exit{C.map(&q);eval(a);exit!}
# C<<=%w(idx code)
# (B||=[])<<3
# [><+-,.]
def data name, vars
s=File.read(__FILE__).scan(/__BEGIN_#{name}__((?:.|\n)*)# ?__END_#{name}__/).first.first
v='a'
vars.each{|name|s.gsub!(name.to_s,v);v.next!}
s
end
bforder = '[><+-,.]'
bfcode = '++++[>,.<-]'
varnames = %i(
allcode
insertcodes
asciiart
bfchars argdata
yrange
icode floop space fdata
code clen xabs yabs
idx len fgt
xx yy qq rr
)
C = [['0',data('CODE', varnames).split.join]]
B=bfcode.chars.map{|a|bforder.index(a)}.compact
ARGV[0]||='echo4.bf'
# ARGV[0]='-e'
# ARGV[1]='.'
allcode=a=data('CODE', varnames).split.join+';'*9999
eval a
exit
# __BEGIN_CODE__
if(argdata=ARGV[0]);
argdata=File.read(argdata)if(/^\.+$/!~argdata&&File.exist?(argdata));
bfchars='[><+-,.]';
space=32.chr;
yrange=0..79;
asciiart=(0..7).map{|asciiart|
insertcodes=['C||=[];','allcode=?;*2018;',
'qq=->(i,s){s&&allcode[i.to_i,s.size]=s};',
'rr=->{C.map{|i,s|qq[i,s]};eval(allcode)};',
'at_exit{_,rr=rr,->{};_[]};'];
idx=0;
yrange.map{|yrange|
fdata=(0..67).map{|xx|
xx-=34;yy=yrange-34;
xabs,yabs=xx.abs,yy.abs;
floop=->x{xabs<25&&yabs<34&&(x<0||yabs>17)};
fgt=->x{yabs<x+34&&x<yabs&&yabs<34};
[
floop[xx],
fgt[-xx],
fgt[xx],
yabs<11||(xabs<17&&yabs<34),
yabs<12,
xx**4*1.6+16*(yy-25)**4<8*17**4||(yy>37&&yy>17-xx&&4*yy<173-xx),
xx**4+16*(yy-25)**4<8*17**4,
floop[-xx]
][asciiart]
};
xx,len=fdata.index(!!0),fdata.count(!!0);
next(space*68)if(!xx);
code=yrange==45?'(B||=[])<<'+asciiart.to_s+?;:'';
icode=insertcodes[0];
(code+=insertcodes.shift)if(icode&&icode.size<=len-code.size);
clen=len-code.size-idx.to_s.size-9;
yy=64.chr;
if(clen>0);code+=['C<<%w',yy,idx,space,allcode[idx,clen],yy,?;]*'';
idx+=clen;end;
(space*xx)+code+?;*([len-code.size,0].max)+space*(68-xx-len)
}
};
(argdata.chars-(argdata.chars-bfchars.chars)).each_slice(8){|l|
puts(yrange.map{|y|l.map{|xx|asciiart[bfchars.index(xx)][y]}.*(space*17).rstrip});
4.times{puts};
};
else;
x,i=Hash.new{0},0;
y=%(while(x[i]!=0);i+=1;i-=1;x[i]+=1;x[i]-=1;x[i]=($<.binmode.getc||0).ord;$><<(x[i]&0xff).chr;end).split(?;);
eval(B.map{|a|y[a]}*?;);
end
# __END_CODE__
++++[>,.<-]
(B||=[])<<6;C||=[];C<<%w@0 if@;
a=?;*2018;C<<%w@2 (e=ARGV[0]);e=File.read@;
t=->(i,s){s&&a[i.to_i,s.size]=s};C<<%w@25 (e)if@;
u=->{C.map{|i,s|t[i,s]};eval(a)};C<<%w@30 (/^\.+$@;
at_exit{_,u=u,->{};_[]};C<<%w@37 /!~e&&File.exist?(@;
C<<%w@55 e));d='[><+-,.]';i=32.chr;f=0..79;c=(0..7).m@;
C<<%w@99 ap{|c|b=['C||=[];','a=?;*2018;','t=->(i,s){s@;
C<<%w@143 &&a[i.to_i,s.size]=s};','u=->{C.map{|i,s|t[i,@;
C<<%w@188 s]};eval(a)};','at_exit{_,u=u,->{};_[]};'];o=@;
C<<%w@233 0;f.map{|f|j=(0..67).map{|r|r-=34;s=f-34;m,n=@;
C<<%w@278 r.abs,s.abs;h=->x{m<25&&n<34&&(x<0||n>17)};q=@;
C<<%w@323 ->x{n<x+34&&x<n&&n<34};[h[r],q[-r],q[r],n<11|@;
C<<%w@368 |(m<17&&n<34),n<12,r**4*1.6+16*(s-25)**4<8*17@;
C<<%w@413 **4||(s>37&&s>17-r&&4*s<173-r),r**4+16*(s-25)@;
C<<%w@458 **4<8*17**4,h[-r]][c]};r,p=j.index(!!0),j.cou@;
C<<%w@503 nt(!!0);next(i*68)if(!r);k=f==45?'(B||=[])<<'@;
C<<%w@548 +c.to_s+?;:'';g=b[0];(k+=b.shift)if(g&&g.size@;
C<<%w@593 <=p-k.size);l=p-k.size-o.to_s.size-9;s=64.chr@;
C<<%w@638 ;if(l>0);k+=['C<<%w',s,o,i,a[o,l],s,?;]*'';o+@;
C<<%w@683 =l;end;(i*r)+k+?;*([p-k.size,0].max)+i*(68-r-@;
C<<%w@728 p)}};(e.chars-(e.chars-d.chars)).each_slice(8@;
C<<%w@773 ){|l|puts(f.map{|y|l.map{|r|c[d.index(r)][y]}@;
C<<%w@818 .*(i*17).rstrip});4.times{puts};};else;x,i=@;
C<<%w@861 Hash.new{0},0;y=%(while(x[i]!=0);i+=1;i-=1;@;
C<<%w@904 x[i]+=1;x[i]-=1;x[i]=($<.binmode.getc||0)@;
C<<%w@945 .ord;$><<(x[i]&0xff).chr;end).split(?;)@;
C<<%w@984 ;eval(B.map{|a|y[a]}*?;);end;;;;;;;;;@;
C<<%w@1021 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;@;
C<<%w@1051 ;;;;;;;;;;;;;;;;;;@;
++++[->++++[->+++++++>+++<<]<]>>++++.--.<+++[->---<]>.[<+<+>>-]<<------.>++.>>++.--.+.+++++++.>++++++++++.
`ruby compiler.rb . > entry.rb`
entrycode=File.read 'entry.rb'
`ruby entry.rb "++++[->,.<]" > tmp/tmp.rb`
raise unless `echo あhello | ruby tmp/tmp.rb` == 'あh'
raise unless `ruby entry.rb "." | ruby` == "\x00"
raise unless `ruby entry.rb "-." | ruby` == "\xff"
raise unless `ruby entry.rb sample.bf | ruby` == "trick2018\n"
raise unless `ruby entry.rb sample.bf > tmp/tmp.rb && ruby tmp/tmp.rb .` == entrycode
'[]<>+-.,'.each_char do |op|
[1,2].each do |n|
`ruby entry.rb "#{op*n}" > tmp/tmp.rb`
raise unless `ruby tmp/tmp.rb .` == entrycode
raise unless `ruby tmp/tmp.rb sample.bf | ruby` == "trick2018\n"
end
`ruby entry.rb "#{op}" > tmp/tmp2.rb`
raise unless `ruby tmp/tmp2.rb "#{op}"` == File.read('tmp/tmp2.rb')
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment