Advertisement
SkullCoder

BF-Interpreter

Jan 19th, 2019
500
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 4.66 KB | None | 0 0
  1. use "M.sml";
  2.  
  3. fun writeHeap xs = let
  4.         fun wH nil p = p
  5.           | wH (x::xr) p = wH xr (con x::p)
  6.     in
  7.          wH xs [new (length xs)]
  8.     end
  9.  
  10. fun bf #"<" = 0
  11.   | bf #">" = 1
  12.   | bf #"+" = 2
  13.   | bf #"-" = 3
  14.   | bf #"[" = 4
  15.   | bf #"]" = 5
  16.   | bf #"!" = 7
  17.   | bf _ = 6
  18. val bfToInt = (map bf) o explode
  19.  
  20. val init = writeHeap (bfToInt "+++++!") (* 5 *)
  21. val init = writeHeap (bfToInt "->-->--->>>!") (* ~1 ~2 ~3 *)
  22. val init = writeHeap (bfToInt "++-+++---!") (* 1 *)
  23. val init = writeHeap (bfToInt "+>++++>+++<+<+!") (* 2 5 3 *)
  24. val init = writeHeap (bfToInt "++>[+++]++<++!") (* 4 2 *)
  25. val init = writeHeap (bfToInt "+[++++]++!") (* divergence *)
  26. val init = writeHeap (bfToInt "+[>+++<-]++>++!") (* 2 5 *)
  27. val init = writeHeap (bfToInt "+++[>+>+<<-]!") (* 0 3 3 *)
  28. val init = writeHeap (bfToInt "+++>++<[->[>+>+<<-]>>[-<<+>>]<<<]!") (* 0 2 6 *)
  29. (*
  30. ++>++<[->
  31.     [>+>+<<-]
  32.     >>[-<<+>>]
  33.     <<<
  34. ]
  35. *)
  36.  
  37. val pc  = 0
  38. val mem = 1
  39. val cmd = 2
  40. val interpret = [
  41. label("goRight"), procS(0,"goRightEnd"),
  42. getS pc, con 1, add, putS pc,                      (* inc pc *)
  43. con 5, getS pc, getH 0, leq, cbranchS "gRelse",
  44. getS pc, getH 0, con 5, leq, cbranchS "gRelse2",
  45. con 0, return,                                     (*bei ]*)
  46. label "gRelse2",                                   (* test auf [ *)
  47. getS pc, getH 0, con 4, leq, cbranchS "gRelse",
  48. callS "goRight",                                   (* noch ein [ *)
  49. label "gRelse", callRS "goRight",
  50. con 0, return, label("goRightEnd"),
  51.  
  52. label("goLeft"), procS(0,"goLeftEnd"),
  53. con 1, getS pc, sub, putS pc,                      (* dec pc *)
  54. getS pc, getH 0, con 4, leq, cbranchS "gLelse",
  55. con 4, getS pc, getH 0, leq, cbranchS "gLelse2",
  56. con 0, return,                                     (*bei [*)
  57. label "gLelse2",                                   (* test auf ] *)
  58. con 5, getS pc, getH 0, leq, cbranchS "gLelse",
  59. callS "goLeft",                                    (* noch ein [ *)
  60. label "gLelse", callRS "goLeft",
  61. con 0, return, label("goLeftEnd"),
  62.  
  63. (* STACK 0 program counter *)                      (* var pc *)
  64. con ~1, con 0, con 0, new 3,                       (* STACK 1 memory queue+list *) (* var mem:=H(3) *)
  65. getS mem, getS mem, putH 0,
  66. getS pc,                                           (* copy pc *)
  67. getH 0, (* STACK 3 *)                              (* var x:= getCMD *)
  68. label("while"), con 6, getS cmd, leq, cbranchS "end", (* while x<=6 *)
  69. label("<"), con 0, getS cmd, leq, cbranchS "n<",   (* if x<=0 *)
  70. getS mem, getH 0, putS mem,                        (* go Left *)
  71. branchS "after",
  72. label("n<"), con 1, getS cmd, leq, cbranchS "n>",  (* elif x<=1 *)
  73. getS mem, getH 2, (* stack 3 *)                    (* getNextAddress *)
  74. con ~1, getS 3, leq, cbranchS "goahead",           (* if a<=~1 *)
  75. con ~1, con 0, con 0, new 3, (* stack 4 *)         (* createNewMemoryCell *)
  76. getS 4, getS mem, putH 2, putS 3,
  77.  getS mem, getS 3, putH 0,                         (* override prev reference *)
  78.                                                    (* next mem is in 3, ss=0-3 *)
  79. label "goahead", putS mem,                         (* ss=0-2 *)
  80. branchS "after",
  81. label("n>"), con 2, getS cmd, leq, cbranchS "n+",  (* elif x<=2 *)
  82. getS mem, getH 1, con 1, add, getS mem, putH 1,    (* increase memory cell *)
  83. branchS "after",
  84. label("n+"), con 3, getS cmd, leq, cbranchS "n-",  (* elif x<=3 *)
  85. con 1, getS mem, getH 1, sub, getS mem, putH 1,    (* decrease memory cell *)
  86. branchS "after",
  87. label("n-"), con 4, getS cmd, leq, cbranchS "n[",  (* elif x<=4 *)
  88. getS mem, getH 1, con 0, leq, cbranchS "saveW",    (* if memory content=0 *)
  89. con 0, getS mem, getH 1, leq, cbranchS "saveW",
  90. callS "goRight", add, branchS "after",             (* move to ] *)
  91. label("saveW"),
  92. branchS "after",
  93. label("n["), con 5, getS cmd, leq, cbranchS "n]",  (* elif x<=5 *)
  94. callS "goLeft", add, branchS "getCMD",             (* move to [ *)
  95. label("n]"),label("after"),
  96. getS pc, con 1, add, putS pc,                      (* increase pc *)
  97. label("getCMD"),getS cmd, sub, add, (* ss=0-2 *)   (* remove cmd from stack *)
  98. getS pc, getH 0, branchS "while",                  (* get next command *)
  99. label("end")
  100. ]
  101.  
  102. val cleanUp = [
  103. con 0, putS pc,
  104. label("goHeapLeft"), getS mem, getH 0, getS (cmd+1), getS mem, leq, cbranchS "notFoundBorder",
  105. branchS "foundLeftBorder",
  106. label("notFoundBorder"),
  107. putS mem,branchS "goHeapLeft",
  108. label("foundLeftBorder"), getS (cmd+1), sub, add,
  109. label("writeGoRight"),
  110. getS mem, getH 1, getS pc, putH 0,
  111. getS pc, con 1, add, putS pc,
  112. getS mem, getH 2, getS (cmd+1), con 0, leq, cbranchS "foundEnd",
  113. putS mem, branchS "writeGoRight",
  114. label("foundEnd")
  115. ]
  116. val prog = init@interpret@cleanUp
  117.  
  118. ;(load o preProcess) (prog@[halt]);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement