New Faster BrainF*ck

Community Forums/Showcase/New Faster BrainF*ck

GW(Posted 2009) [#1]
A few years ago I released here a Brainfuck interpreter in b3d.
this weekend I decided to revisit it an make it faster. 100X faster!
'// Todo: input 
'// Brainfuck JIT-A By GW 2009 //
'------------------------------
SuperStrict  
Framework brl.retro
Import brl.reflection  
Import brl.system 
  
Const CE% = 16
Global CODE$
Local T$
Global OPS$ 
Global Func(A:Byte Ptr,B:Byte Ptr)

RestoreData DAT
Repeat	
	ReadData T$
	If T$="" Then Exit
	CODE$=CODE$+T$
Forever

Global Mem:Byte Ptr = MemAlloc(65535)
MemClear(mem,65535)
	
Global BC%=0	
Global LC%=0
Global BA% 
Global FP:Byte Ptr
Global Labels:TList = CreateList()
Global Pa% = Int(Byte Ptr(altprint))

Func = MemAlloc(Len(code)*16)
BA = Int(Varptr(mem))
fp = func
For Local I% = 0 To (Len(code)*CE)-1
	fp[i] = $90
Next

Global LA%[1024]

outop($5A)
outop($5E)
outop($5B)
outop($52)
outop($60)

For Local I% = 0 To CODE.length-1
	Select CODE[i]
		Case Asc("+")
			outop($FE);outop($06)
		Case Asc("-")
			outop($FE);outop($0E)
		Case Asc(">")
			outop($46)
		Case Asc("<")
			outop($4E)
		Case Asc("[") 
			labels.addlast("label_" + LC)
			LC:+1
			outop($80);outop($3E);outop($00)
			outop($0F);outop($84); outop(lc);outop($01);outop($02);outop($03) 
			LA[LC-1] = BC
			LC:+1
		Case Asc("]") 
			If labels.isempty() Then RuntimeError("mismached labels!")
			Local t$ = String(labels.removelast())
			Local z% = Int(t.Replace("label_",""))
			z:+1
			LA[z] = BC
			outop($E9); outop(z);outop($F1);outop($F2);outop($F3)
		Case Asc(".")  
			outop($FF);outop($36)
			outop($FF)
			outop($D3)
			outop($81);outop($C4);outop($04);outop($00);outop($00);outop($00)
			outop($B8);outop($00);outop($00);outop($00);outop($00);
		Case Asc(",")
			'TODO
		Default
	EndSelect	
Next
outop($61)
outop($c3)

For Local I% = 1 To (Len(code)*CE)-4
	If fp[i] = $01 And fp[i+1] = $02 And fp[i+2] = $03 Then
		Local z% = fp[i-1]
		Local TMP% = (la[z]-la[z-1])+5 
		fp[i-1] = Byte(Byte Ptr( Varptr(TMP))[0] )   
		fp[i] = Byte(Byte Ptr( Varptr(TMP))[1] )  
		fp[i+1] = Byte(Byte Ptr( Varptr(TMP))[2] )
		fp[i+2] = Byte(Byte Ptr( Varptr(TMP))[3] )
	EndIf
	If fp[i] = $F1 And fp[i+1] = $F2 And fp[i+2] = $F3 Then
		Local z% = fp[i-1] 
		Local TMP% = -(la[z]-la[z-1]+(5+3+6))
		fp[i-1] = Byte(Byte Ptr( Varptr(TMP))[0] )  
		fp[i] = Byte(Byte Ptr( Varptr(TMP))[1] )  
		fp[i+1] = Byte(Byte Ptr( Varptr(TMP))[2] )
		fp[i+2] = Byte(Byte Ptr( Varptr(TMP))[3] )
	EndIf
Next

Function Out(S$) 
	Print s
End Function
	
Function outop(s:Byte)
	fp[bc] = s
	bc:+1
	If bc > Len(code)*CE Then RuntimeError("out of space!")
End Function    

Function AltPrint(b:Int)
	Print Chr(Byte(b))
End Function

'DebugStop
'-------------------------------------------------------------------------------------
Func(mem,altprint)

#DAT	'Hello world
DefData "++++++++++[>+++++++>++++++++++>+++<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+."
DefData ""



Sokurah(Posted 2009) [#2]
Hey, if I wanted to read source like this I'd be programming C++. ;)


GW(Posted 2009) [#3]
You mean to say that you don't know how it works? :D


Sokurah(Posted 2009) [#4]
I ran it, saw what it did, decided hell would freeze over before trying to understand it. :D


GW(Posted 2009) [#5]
decided hell would freeze over before trying to understand it.

:D
Too bad. I think most here don't get it either.
Its a pretty neat hack imo.
The fastest implementation of the slowest of languages right on the Cpu. ;)


Warpy(Posted 2009) [#6]
Now do befunge!


GW(Posted 2009) [#7]
heh. no way.. Jit assembling BF is hard enough on the brain. ;D


Scienthsine(Posted 2009) [#8]
I wrote a BF*ck interpreter in B+ a few years back. I kinda liked the language. Had one for my TI89 calc, spent hours during my senior highschool year mapping out BF*ck programs.


D4NM4N(Posted 2009) [#9]
Yikesalmighty!


slenkar(Posted 2009) [#10]
how about I f**k your brain with my fist





j/k


Guy Fawkes(Posted 2009) [#11]
already made a javascript brainf**k interpreter XD im straight


GW(Posted 2009) [#12]
Not as fast as this one.
Seriously, i think not a single person commenting on this has looked to see how it works.. :(


Warpy(Posted 2009) [#13]
I assumed it was b3d because you said the last one was in b3d.

That's not machine code, is it? Now I get what you meant about JIT assembling.

Oh, and if you replace Print with Standardiostream.Writestring you don't get a newline, makes for nicer output.


GW(Posted 2009) [#14]
Ya, is assembling to run right on the cpu. jumps and all.
Thanks for noticing. :D


Guy Fawkes(Posted 2009) [#15]
um, yes. its much faster. plus, it encodes websites into brainf**k


steve_ancell(Posted 2009) [#16]

slenkar (Posted 5 days ago) #10
how about I f**k your brain with my fist





j/k



Dude, you sound stressed... You really need help !

I don't think you need to use a fist, BrainF**K does it flawlessly !


slenkar(Posted 2009) [#17]
lol I also posted a similar thing here:

http://www.blitzbasic.com/Community/posts.php?topic=87508


for a laugh,

at least these comments have some relation to the thread though


Blitzplotter(Posted 2009) [#18]
Okay. I confess. I tried sussing the code on the train on my phone. But seeing as i have just sufferred a recent bfuck on a 3 day intensive software testing course. She just can t take any more captain.


Nate the Great(Posted 2010) [#19]
just bumping this out of interest... um I spent a good 3 hours trying to figure out how this works... I give up...

edit: hey I made my first brain fk program!!!!

+[.+]

displays all characters...


Dreamora(Posted 2010) [#20]
to make it even faster, you could replace the ASC calls in the select statements with the real ascii values :)


Noobody(Posted 2010) [#21]
um I spent a good 3 hours trying to figure out how this works... I give up...

It seems that he's converting brainfuck commands into real machine code (basically compiled ASM) and then calls the so-compiled brainfuck code as a function.

Very impressive. How many times did your machine crash until you got everything right? I don't even know what happens when you feed a CPU wrong commands.


Taron(Posted 2010) [#22]
I am very hesitant to chime in here. I've looked at it and I'm having trouble figuring out the use, honestly. I see how it translates the data into what has to be ascii codes in some bizarre kind of maneuvers. Feels like a kind of cat playing with a dead mouse, somehow. Is there a deeper sense to it, prooving a point of sorts or is it purely just goofing around in a geek contest of some kind? (completely not meant offensively, really, just don't know how to label this any differently?!)


GW(Posted 2010) [#23]
Thanks for the kind comments and for taking the time to see how it actually worked.
Warpy and Noobody are right. Its converting the BF sourcecode into x86 opcodes and setting the compiled code into a function pointer. Its all pretty easy except the labels were a b*tch.
I did encounter a problem where if the BF program is very large, the generated code can jump outside the function for big jumps, never sure why that was happening...

How many times did your machine crash

None actualy. 90% of the dev time was spent walking through the code in Olly to make sure its correct. (bmax would crash sometimes though :p )