harraps

brainfuck interpreter moonscript TIC

Jan 28th, 2017
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.91 KB | None | 0 0
  1. --[moonscript]
  2. --brainfuck interpreter by oSchyns
  3. --version 0.3.0
  4.  
  5. BF="++++ ++++"..
  6. "[>+++++ +++++<-]"..
  7. ">++++.----- ----- -.--- ---."--..
  8. --uncomment to test error output
  9. --"<< force a tape outbound"
  10.  
  11. IN=""
  12.  
  13. --tape to perform computation
  14. class Tape
  15.  
  16. new:(l,m)=>
  17. @l=l --cell limit
  18. @m=m --loop the finite tape
  19. @t={} --tape
  20. @h=0 --read head
  21. --correct values
  22. @l-=1 if @l~=nil
  23. @m-=1 if @m~=nil
  24.  
  25. --rhead out of the bounds of the tape
  26. unbound:=>
  27. if @m~=nil then return @h>@m
  28. @h<0
  29.  
  30. --init nil cell to zero
  31. init:=> @t[@h]=0 if @t[@h]==nil
  32.  
  33. --move read head to the left
  34. mvL:=>
  35. @h-=1
  36. if @m~=nil then if @h<0
  37. @h=@m
  38.  
  39. --move read head to the right
  40. mvR:=>
  41. @h+=1
  42. if @m~=nil then if @h>@m
  43. @h=0
  44.  
  45. --decreament cell
  46. decr:=>
  47. @init!
  48. @t[@h]-=1
  49. if @l~=nil then if @t[@h]<0
  50. @t[@h]=@l
  51.  
  52. --increament cell
  53. incr:=>
  54. @init!
  55. @t[@h]+=1
  56. if @l~=nil then if @t[@h]>@l
  57. @t[@h]=0
  58.  
  59. --ins: insert value in cell
  60. --out: get value from cell
  61.  
  62. ins:(i)=> @t[@h]=i if i~=nil
  63. out: => @t[@h] or 0
  64.  
  65. --stack to hold indexes of brackets
  66. class Stack
  67. new: => @s={}
  68. top: => @s[#@s]
  69. pop: => @s[#@s]=nil
  70. push:(i)=> @s[#@s+1]=i
  71.  
  72.  
  73. --automaton to execute the program
  74. class Automaton
  75.  
  76. new:(p,i,l,m)=>
  77. @t=Tape l,m --tape
  78. @s=Stack! --stack
  79. @r=1 --read head
  80. @p="" --program
  81. @i=i --input
  82. @o="" --output
  83. @e=nil --error
  84. --strip useless chars of program
  85. for c in p\gmatch "[<>%+%-%[%]%.%,]+"
  86. @p..=c
  87. b=@check!
  88. if b~=nil
  89. @e="brackets mismatch at "..b
  90.  
  91. --check for brackets mismatch
  92. check:=>
  93. s=Stack!
  94. for i=1,#@p
  95. if @program(i)=='[' then s\push i
  96. elseif @program(i)==']'
  97. return i if #s.s<=0
  98. s\pop!
  99. return s\top! if #s.s> 0
  100. return nil
  101.  
  102. --get char from input
  103. input:=>
  104. if @i==nil or @i=="" then return nil
  105. c1=@i\byte! --1st char of i
  106. @i=@i\sub 2 --remove 1st char
  107. return c1
  108.  
  109. --output: add char to output
  110. --program: get instruction at 'n'
  111. --continue: continue execution
  112.  
  113. output: (n)=> @o..=string.char n
  114. program:(n)=> @p\sub n,n
  115. continue: => @r<=#@p and @e==nil
  116.  
  117. --find matching bracket
  118. match:(b)=>
  119. m=1
  120. while m>0 and b<=#@p
  121. b+=1
  122. if @program(b)=='[' then m+=1
  123. elseif @program(b)==']' then m-=1
  124. return b
  125.  
  126. --opening bracket
  127. open:=>
  128. --jump to matching bracket
  129. if (@t\out!)==0 then @r=@match @r
  130. else @s\push @r
  131.  
  132. --closing bracket
  133. clos:=>
  134. if (@t\out!)==0 then @s\pop!
  135. elseif @s\top! ~=nil then @r=@s\top!
  136.  
  137. --automaton's' execution step
  138. step:=>
  139. switch @program @r
  140. when '<' then @t\mvL!
  141. when '>' then @t\mvR!
  142. when '-' then @t\decr!
  143. when '+' then @t\incr!
  144. when ',' then @t\ins @input!
  145. when '.' then @output @t\out!
  146. when '[' then @open!
  147. when ']' then @clos!
  148. @r+=1
  149. if @t\unbound!
  150. @e="tape outbound !"
  151.  
  152.  
  153. --display to see the execution
  154. class Display
  155.  
  156. new:(a,s=1,f=nil)=>
  157. @a=a --automaton
  158. @s=s/60 --number of update per second
  159. @c=0 --counter
  160. @f=3 --display format of cells
  161. if f=="hexadecimal" then @f=2
  162. elseif f=="character" then @f=1
  163.  
  164. --execute automaton all at once
  165. execute:=>
  166. while @a\continue!
  167. @a\step!
  168. @output!
  169.  
  170. --update automaton at given frame rate
  171. update:=>
  172. if @a\continue!
  173. if @c<1 then @c+=@s
  174. else
  175. @c=0
  176. @a\step!
  177. @draw!
  178.  
  179. --draw automaton state and output
  180. draw:=>
  181. cls!
  182. @tape 8, 2
  183. @program 8,12
  184. @output 4
  185.  
  186.  
  187. --draw the tape
  188. tape:(w=6,h=0,c=1,a=3)=>
  189. rect 0,h,240,w,c
  190. l=math.ceil (40/@f)*0.5
  191. p=(w-6)*0.5
  192. q=6*@f
  193. d=15
  194. if @f==2 then d=6
  195. elseif @f==1 then d=3
  196. rect l*q-d,h,6*@f,w,a
  197. for [email protected],@a.t.h+l
  198. unless i<0
  199. c=15
  200. if @f==3 then v="%3d"\format v
  201. elseif @f==2 then v="%2x"\format v
  202. elseif @f==1 then v=string.char v
  203. print v,(i+b)*q-d,h+p,c
  204.  
  205. --draw the program
  206. program:(w=6,h=6,c=1,a=3)=>
  207. rect 0,h,240,w,c
  208. rect 117,h, 6,w,a
  209. p=(w-6)*0.5
  210. for [email protected],@a.r+20
  211. unless i<1
  212. c=15
  213. v=@a\program i
  214. print v,(i+b)*6-2,h+p,c
  215.  
  216. --print result of execution
  217. output:(s=0)=>
  218. i=s
  219. --print each line
  220. for l in o\gmatch "[%S \t]*\n"
  221. print l,0,i*6
  222. i+=1
  223. break if i==21 --no more room
  224. --print error
  225. unless @a.e==nil
  226. print @a.e,0,130,6
  227.  
  228. --create automaton 'TM' using
  229. --program : BF
  230. --input : IN
  231. TM=Automaton BF,IN,128,nil
  232.  
  233. --create display 'DP' using
  234. --automaton : TM
  235. --frame rate : 30
  236. --cell display : decimal
  237. DP=Display TM,30,"decimal"
  238.  
  239. --execute the automaton and display it
  240. export TIC=->
  241. DP\update!
  242.  
  243. --http://moonscript.org/reference/
  244. --http://moonscript.org/compiler/
  245. --https://esolangs.org/wiki/Brainfuck
  246. --http://zacstewart.com/2013/09/15/learning-cpp-a-brainfuck-interpreter.html
Advertisement
Add Comment
Please, Sign In to add comment