PageRenderTime 26ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/src/bf2go.go

http://github.com/creamdog/bf2go
Go | 161 lines | 139 code | 21 blank | 1 comment | 12 complexity | 6153fc3103f35ceb49af0e0949ca1949 MD5 | raw file
  1. package bf2go
  2. import(
  3. "os"
  4. "log"
  5. "strconv"
  6. )
  7. type brainfuck struct {
  8. SourceFile *os.File
  9. DestFile *os.File
  10. Token []byte
  11. Line int
  12. Char int
  13. Debug bool
  14. }
  15. func Translate(source string, dest string, debug bool) {
  16. in,_ := os.Open(source)
  17. out,_ := os.OpenFile(dest,os.O_CREATE|os.O_RDWR|os.O_TRUNC,0666)
  18. bf := &brainfuck{in,out,make([]byte,1),1,1,debug}
  19. bf.SourceFile.Seek(0,0)
  20. bf.DestFile.Seek(0,0)
  21. bf.initalizeOutputFile()
  22. bf.ParseToken()
  23. }
  24. func (bf *brainfuck) initalizeOutputFile() {
  25. bf.DestFile.WriteString("package main\n")
  26. bf.DestFile.WriteString("import (\n")
  27. bf.DestFile.WriteString("\t\"os\"\n")
  28. bf.DestFile.WriteString("\t\"bufio\"\n")
  29. if bf.Debug {
  30. bf.DestFile.WriteString("\t\"log\"\n")
  31. }
  32. bf.DestFile.WriteString(")\n")
  33. bf.DestFile.WriteString("\n\n");
  34. bf.DestFile.WriteString("func coredump(stack []byte){\n")
  35. bf.DestFile.WriteString("\tfile,_ := os.OpenFile(\"bfcoredump\",os.O_CREATE|os.O_RDWR|os.O_TRUNC,0666)\n")
  36. bf.DestFile.WriteString("\tfile.Write(stack)\n")
  37. bf.DestFile.WriteString("\tfile.Close()\n")
  38. bf.DestFile.WriteString("}\n")
  39. bf.DestFile.WriteString("\n\n");
  40. bf.DestFile.WriteString("func main(){\n")
  41. bf.DestFile.WriteString("\tstack := make([]byte,30000)\n")
  42. bf.DestFile.WriteString("\tdefer func() {\n\tcoredump(stack)\n\t}()\n")
  43. bf.DestFile.WriteString("\tfor i:=0;i<len(stack);i++ {\nstack[i]=0\n}\n")
  44. bf.DestFile.WriteString("\tstackPosition := 0\n")
  45. bf.DestFile.WriteString("\twriter := bufio.NewWriter(os.Stdout)\n")
  46. bf.DestFile.WriteString("\treader := bufio.NewReader(os.Stdin)\n")
  47. bf.DestFile.WriteString("\tif writer == nil{\nwriter=nil}\n")
  48. bf.DestFile.WriteString("\tif reader == nil{\nreader=nil}\n")
  49. bf.DestFile.WriteString("\tbuf := make([]byte,1)\n")
  50. bf.DestFile.WriteString("\tif buf == nil{\nbuf=nil}\n")
  51. }
  52. func (bf *brainfuck) finnishOutputFile() {
  53. bf.DestFile.WriteString("\twriter.Flush()\n")
  54. bf.DestFile.WriteString("}\n")
  55. }
  56. func (bf *brainfuck) ParseToken() {
  57. if _,err := bf.SourceFile.Read(bf.Token); err != nil {
  58. bf.finnishOutputFile();
  59. log.Printf("%s",err)
  60. return
  61. }
  62. token := bf.Token[0];
  63. if token == '\n' {
  64. bf.Line++
  65. bf.Char=1
  66. } else if token != '\r' {
  67. bf.Char++
  68. }
  69. switch(token) {
  70. case '<':
  71. bf.DestFile.WriteString("\n\tstackPosition--\n\tif stackPosition < 0 {\n\tstackPosition=0\n\t}\n")
  72. break;
  73. case '>':
  74. bf.DestFile.WriteString("\n\tstackPosition++\n")
  75. bf.DestFile.WriteString("\tif stackPosition >= len(stack) {\n")
  76. if bf.Debug {
  77. bf.DestFile.WriteString("\tlog.Printf(\"increasing stack length to %d\",len(stack)+2)\n")
  78. }
  79. bf.DestFile.WriteString("\ttmp := make([]byte,len(stack)+2)\n")
  80. bf.DestFile.WriteString("\tfor i:= 0;i<len(stack);i++ {\n\ttmp[i]=stack[i]\n\t}\n")
  81. bf.DestFile.WriteString("\tstack=tmp\n")
  82. bf.DestFile.WriteString("\t}\n")
  83. break;
  84. case '+':
  85. bf.DestFile.WriteString("\tstack[stackPosition]++\n")
  86. break;
  87. case '-':
  88. bf.DestFile.WriteString("\tstack[stackPosition]--\n")
  89. break;
  90. case '.':
  91. if bf.Debug {
  92. bf.DestFile.WriteString("\tlog.Printf(\"print@%d\",stackPosition)\n")
  93. }
  94. bf.DestFile.WriteString("\twriter.WriteByte(stack[stackPosition])\n")
  95. break;
  96. case ',':
  97. //bf.DestFile.WriteString("if num,_ := os.Stdin.Read(buf); num > 0 {\nstack[stackPosition]=buf[0]\n}\n")
  98. bf.DestFile.WriteString("\tstack[stackPosition],_=reader.ReadByte()\n")
  99. break;
  100. case '|':
  101. bf.DestFile.WriteString("\tswitch(stack[stackPosition]) {\n")
  102. bf.DestFile.WriteString("\tcase 1:\n")
  103. bf.DestFile.WriteString("\tend := 0\n")
  104. bf.DestFile.WriteString("\tstart := stackPosition+1\n")
  105. bf.DestFile.WriteString("\tfor i:=start;i<len(stack);i++ {\n")
  106. bf.DestFile.WriteString("\tif stack[i] != 0 {\n\tend++\n\t} else {\n\tbreak;\n\t}\n")
  107. bf.DestFile.WriteString("\t}\n")
  108. bf.DestFile.WriteString("\tfile,error := os.OpenFile((string)(stack[start:end]),os.O_CREATE|os.O_RDWR|os.O_TRUNC,0666)\n")
  109. bf.DestFile.WriteString("\tif error == nil { writer = bufio.NewWriter(file) } else { writer.Write(([]byte)(error.String())) }\n")
  110. bf.DestFile.WriteString("\tbreak;\n")
  111. bf.DestFile.WriteString("\tdefault:\n")
  112. bf.DestFile.WriteString("\twriter = bufio.NewWriter(os.Stdout)\n")
  113. bf.DestFile.WriteString("\tbreak;\n")
  114. bf.DestFile.WriteString("\t}\n")
  115. break;
  116. case '[':
  117. if bf.Debug {
  118. bf.DestFile.WriteString("\tlog.Printf(\"loop start@"+strconv.Itoa(bf.Line)+":"+strconv.Itoa(bf.Char)+"\")\n")
  119. }
  120. bf.DestFile.WriteString("\tfor{\n")
  121. break;
  122. case ']':
  123. if bf.Debug {
  124. bf.DestFile.WriteString("\tlog.Printf(\"loop end@"+strconv.Itoa(bf.Line)+":"+strconv.Itoa(bf.Char)+", stack=%d,stackPosition=%d\",stack[stackPosition],stackPosition)\n")
  125. }
  126. bf.DestFile.WriteString("\tif stack[stackPosition] == 0 {\n\t\tbreak;\n\t}\n")
  127. bf.DestFile.WriteString("\t}\n")
  128. break;
  129. case '}':
  130. bf.DestFile.WriteString("\tgo func(stackPosition int){\n")
  131. break;
  132. case '{':
  133. bf.DestFile.WriteString("\t}(stackPosition+0)\n")
  134. break;
  135. default:
  136. log.Printf("ignore '%c'",token)
  137. break;
  138. }
  139. bf.ParseToken()
  140. }