fork download
  1. =begin
  2.  
  3. 267 デフォルトの名無しさん 2020/08/10(月) 05:44:26.44 ID:SKFyjjt9
  4.   お題:
  5.   Brainfuck実行環境を作成し,以下のhello.bfを読み込み実行してください
  6.  
  7.   入力: https://g...content-available-to-author-only...b.com/pablojorge/brainfuck/blob/master/programs/hello.bf
  8.   出力: "Hello World!"
  9.  
  10. ---------------------------------------------------------------------
  11.  
  12. ideone の仕様により入力は埋め込み。
  13. 2pass 化して連続処理を最適化。
  14.  
  15. =end
  16.  
  17. # require 'net/http'
  18. # Uri = 'https://g...content-available-to-author-only...b.com/pablojorge/brainfuck/blob/master/programs/hello.bf'
  19. # Uri_Raw = Uri.sub(%r{//github.com/(.*)/blob/}){"//raw.githubusercontent.com/#{$1}/"}
  20. # $src = Net::HTTP.get( URI.parse( Uri_Raw ) )
  21. $src = DATA.read
  22.  
  23. $src2 = [] # Pass2 code ( operand:n , opcode:3 )
  24.  
  25. OP_Ptr = 0
  26. OP_Add = 1
  27. OP_Put = 2
  28. OP_Get = 3
  29. OP_W_s = 4
  30. OP_W_e = 5
  31.  
  32. def pass1_sub( ipc, ch, op )
  33. p1 = 8
  34. while $src[ipc+1] == ch
  35. p1 += 8
  36. ipc += 1
  37. end
  38. $src2 << ( op + p1 )
  39. ipc
  40. end
  41.  
  42. def pass1_num( ipc, op, op1, op2 )
  43. p1 = 0
  44. while ipc < $src.length
  45. case $src[ipc]
  46. when op1; p1 += 8
  47. when op2; p1 -= 8
  48. else
  49. ipc -= 1
  50. break
  51. end
  52. ipc += 1
  53. end
  54. $src2 << ( op + p1 ) if p1 != 0
  55. ipc
  56. end
  57.  
  58. def pass1( ipc, wloop = 0 )
  59. while ipc < $src.length
  60. ch = $src[ipc]
  61. case ch
  62. when '>', '<'; ipc = pass1_num( ipc, OP_Ptr, '>', '<' )
  63. when '+', '-'; ipc = pass1_num( ipc, OP_Add, '+', '-' )
  64. when '.'; ipc = pass1_sub( ipc, ch, OP_Put )
  65. when ','; ipc = pass1_sub( ipc, ch, OP_Get )
  66. when '['
  67. $src2 << OP_W_s
  68. wloop2 = $src2.length
  69. ipc = pass1( ipc+1, wloop2 )
  70. $src2[wloop2-1] += $src2.length << 3
  71. when ']'
  72. $src2 << ( OP_W_e + (wloop << 3) )
  73. return ipc
  74. end
  75. ipc += 1
  76. end
  77. if wloop != 0
  78. warn "Error [ ... ]"
  79. exit 1
  80. end
  81. ipc
  82. end
  83.  
  84. $src.gsub!( /[^<>+\-\.,\[\]]/, '' )
  85. pass1( 0 )
  86. # pass2
  87. buff = [0] * 0x8000
  88. ptr = 0
  89. ipc = 0
  90. while (o = $src2[ipc])
  91. p1 = o >> 3
  92. case o & 7
  93. when OP_Ptr; ptr += p1
  94. when OP_Add; buff[ptr] += p1
  95. when OP_Put; print buff[ptr].chr * p1
  96. when OP_Get; p1.times{ buff[ptr] = STDIN.getc.ord }
  97. when OP_W_s; ipc = p1 - 1 if buff[ptr] == 0
  98. when OP_W_e; ipc = p1 - 1 if buff[ptr] != 0
  99. end
  100. ipc += 1
  101. end
  102.  
  103. __END__
  104. +++++ +++++ initialize counter (cell #0) to 10
  105. [ use loop to set the next four cells to 70/100/30/10
  106. > +++++ ++ add 7 to cell #1
  107. > +++++ +++++ add 10 to cell #2
  108. > +++ add 3 to cell #3
  109. > + add 1 to cell #4
  110. <<<< - decrement counter (cell #0)
  111. ]
  112. > ++ . print 'H'
  113. > + . print 'e'
  114. +++++ ++ . print 'l'
  115. . print 'l'
  116. +++ . print 'o'
  117. > ++ . print ' '
  118. << +++++ +++++ +++++ . print 'W'
  119. > . print 'o'
  120. +++ . print 'r'
  121. ----- - . print 'l'
  122. ----- --- . print 'd'
  123. > + . print '!'
  124. > . print '\n'
  125.  
Success #stdin #stdout 0.01s 6696KB
stdin
Standard input is empty
stdout
Hello World!