Brainfuck Compiler und Interpreter
Übersicht

![]() |
BtbNBetreff: Brainfuck Compiler und Interpreter |
![]() Antworten mit Zitat ![]() |
---|---|---|
Das Modul:
Code: [AUSKLAPPEN] SuperStrict
Rem bbdoc: Brainfuck EndRem Module BtbN.Brainfuck ModuleInfo "Version: 1.75" ModuleInfo "Author: BtbN" ModuleInfo "License: Public Domain" ModuleInfo "History: 1.75 Release" ModuleInfo "History: Optimizing C++-Source" ModuleInfo "History: 1.50 Release" ModuleInfo "History: Compiler added" Import Pub.StdC Import Pub.FreeProcess Import BRL.Stream Import BRL.FileSystem Import BRL.StandardIO Private Function Sys:Int(cmd$) Return system_(cmd) End Function Public Rem bbdoc: The Brainfuck Interpreter Type EndRem Type TBrainfuck Field code:String Field arr:Int[256] Rem bbdoc: Insert a Brainfuck-Code for interpreting EndRem Method SetCode(inp:String) self.code = inp EndMethod Rem bbdoc: Read the Brainfuck-Code from a Stream EndRem Method SetCodeStream(strm:TStream) self.SetCode(LoadString(strm)) EndMethod Rem bbdoc: Read the Brainfuck-Code from a File EndRem Method SetCodeFile(url:Object) Local tmp:TStream = ReadStream(url) self.SetCodeStream(tmp) CloseStream(tmp) EndMethod Rem bbdoc: Compiles the Brainfuck-Code into the given @file. about: If @keepsource is set, the tmp.cpp source-File will not be deleted. EndRem Method Compile(file:String,keepsource:Byte=False) Local cpph:String = "#include <iostream>~n" cpph :+ "~n" cpph :+ "int main(int argc,char *argv[])~n" cpph :+ "{~n" cpph :+ " int *p = new int[256];~n" cpph :+ " char cell = 0;~n" cpph :+ " char tmp;~n" cpph :+ "~n" Local cppf:String = "}~n" Local out:TStream = WriteStream(AppDir+"/tmp.cpp") Local plcount:Int,plfound:Byte,micount:Int,mifound:Byte Local slcount:Int,slfound:Byte,srcount:Int,srfound:Byte Local whilecount:Int,bevadder:String,i:Int WriteString(out,cpph) Local pos:Long = 0 While(pos<self.code.Length) If (Chr(self.code[pos]) = "." Or .. Chr(self.code[pos]) = "," Or .. Chr(self.code[pos]) = "[" Or .. Chr(self.code[pos]) = "]" Or .. Chr(self.code[pos]) = "<" Or .. Chr(self.code[pos]) = ">" Or .. Chr(self.code[pos]) = "-") And .. plfound = 1 .. Then WriteLine(out,bevadder+" p[cell] += "+plcount+";") plcount = 0 plfound = 0 EndIf If (Chr(self.code[pos]) = "." Or .. Chr(self.code[pos]) = "," Or .. Chr(self.code[pos]) = "[" Or .. Chr(self.code[pos]) = "]" Or .. Chr(self.code[pos]) = "<" Or .. Chr(self.code[pos]) = ">" Or .. Chr(self.code[pos]) = "+") And .. mifound = 1 .. Then WriteLine(out,bevadder+" p[cell] -= "+micount+";") micount = 0 mifound = 0 EndIf If (Chr(self.code[pos]) = "." Or .. Chr(self.code[pos]) = "," Or .. Chr(self.code[pos]) = "[" Or .. Chr(self.code[pos]) = "]" Or .. Chr(self.code[pos]) = ">" Or .. Chr(self.code[pos]) = "-" Or .. Chr(self.code[pos]) = "+") And .. slfound = 1 .. Then WriteLine(out,bevadder+" cell -= "+slcount+";") slcount = 0 slfound = 0 EndIf If (Chr(self.code[pos]) = "." Or .. Chr(self.code[pos]) = "," Or .. Chr(self.code[pos]) = "[" Or .. Chr(self.code[pos]) = "]" Or .. Chr(self.code[pos]) = "<" Or .. Chr(self.code[pos]) = "-" Or .. Chr(self.code[pos]) = "+") And .. srfound = 1 .. Then WriteLine(out,bevadder+" cell += "+srcount+";") srcount = 0 srfound = 0 EndIf Select Chr(self.code[pos]) Case ">" srcount :+ 1 srfound = 1 Case "<" slcount :+ 1 slfound = 1 Case "." WriteLine(out,bevadder+" std::printf(~q%c~q,p[cell]);") Case "," WriteLine(out,bevadder+" std::cin >> tmp;") WriteLine(out,bevadder+" p[cell] = (int)tmp;") Case "-" micount :+ 1 mifound = 1 Case "+" plcount :+ 1 plfound = 1 Case "[" WriteLine(out,bevadder+" while(p[cell]) {") whilecount :+ 1 bevadder = "" For i = 0 Until whilecount bevadder :+ " " Next Case "]" whilecount :- 1 bevadder = "" For i = 0 Until whilecount bevadder :+ " " Next WriteLine(out,bevadder+" }") EndSelect pos :+ 1 Wend WriteString(out,cppf) CloseStream(out) Sys("g++ "+AppDir+"/tmp.cpp -o "+file) If Not keepsource Then DeleteFile(AppDir+"/tmp.cpp") EndMethod Rem bbdoc: Starts interpreting the Brainfuck-Code.<br>The output will be written in @out and outoutted to sthe StdIO, if @ToStdIO is True. EndRem Method RunEx(out:String Var,ToStdIO:Byte=False) Local pos:Long,cast:Byte Local loop_pos:Long[256],lnum:Byte=0 Local tmps:String pos = 0 While(pos<self.code.Length) Select Chr(self.code[pos]) Case ">" cast :+ 1 If cast = 256 Then cast = 0 Case "<" cast :- 1 If cast = -1 Then cast = 255 Case "." tmps :+ Chr(Byte(self.arr[cast])) Case "," self.arr[cast] = getchar_() Case "-" self.arr[cast] :- 1 Case "+" self.arr[cast] :+ 1 Case "[" loop_pos[lnum] = pos lnum :+ 1 Case "]" If self.arr[cast] <> 0 Then pos = loop_pos[lnum-1] Else lnum :- 1 EndIf EndSelect pos :+ 1 Wend If ToStdIO Then WriteString(StandardIOStream,tmps) FlushStream(StandardIOStream) EndIf out = tmps For pos = 0 To 255 arr[pos] = 0 Next EndMethod Rem bbdoc: Easyer way to start Interpreting the the Brainfuck-Code EndRem Method Run(ToStdIO:Byte=True) Local tmp:String self.RunEx(tmp,ToStdIO) EndMethod EndType Und hier ein Hello World: Code: [AUSKLAPPEN] SuperStrict
Framework BtbN.Brainfuck Global b:TBrainfuck = New TBrainfuck b.SetCode("++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.") b.Compile("test",1) b.run() Sollte eine Binary "test" erzugen, die beim ausführen "Hello World!" ausgibt und einmal selbst "Hello World!" ausgeben. Allerdings nur über die StdIO(Konsole). Auf Windows muss zum kompilieren das MinGW installiert sein(für g++). Edit: Update auf Version 1.75, der C++-Source wird jetzt optimiert, sodass die ellenlangen cell++;..... Reihen darin ausbleiben. Desweiteren kann man unterbinden, dass das C++-Source-File gelöscht wird. So kann man es z.B. selber kompilieren, fals man kein g++ hat. |
||
- Zuletzt bearbeitet von BtbN am So, März 12, 2006 12:24, insgesamt 2-mal bearbeitet
![]() |
Justus |
![]() Antworten mit Zitat ![]() |
---|---|---|
http://de.wikipedia.org/wiki/Brainfuck | ||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group