-
Notifications
You must be signed in to change notification settings - Fork 0
/
brain_rb.hs
145 lines (121 loc) · 3.3 KB
/
brain_rb.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
{-# LANGUAGE QuasiQuotes #-}
module Brain_rb where
import Control.Applicative
import Str
before_main = [str|
class BuildLambda
def initialize
@funcs = []
end
def increment
@funcs.push(:increment)
self
end
def decrement
@funcs.push(:decrement)
self
end
def next_var
@funcs.push(:next_var)
self
end
def prev_var
@funcs.push(:prev_var)
self
end
def print_value
@funcs.push(:print_value)
self
end
def get_value
@funcs.push(:get_value)
self
end
def loop_self(builder)
@funcs.push([:loop_self, builder])
self
end
def evaluate lst
for func in @funcs
if func == :increment
lst = lst.increment
elsif func == :decrement
lst = lst.decrement
elsif func == :next_var then
lst = lst.next_var
elsif func == :prev_var then
lst = lst.prev_var
elsif func == :print_value then
lst = lst.print_value
elsif func == :get_value then
lst = lst.get_value
elsif func.class == Array and func[0] == :loop_self then
lst = lst.loop_self(func[1])
end
end
lst
end
def loop_var lst
return lst if lst.value == 0
loop_var(evaluate(lst))
end
end
class TuringHead
BYTE = 256
attr_accessor :prev, :next, :value
def initialize(prev = nil)
@value = 0
end
def increment
@value = (@value + 1) % BYTE
self
end
def decrement
@value = (@value + BYTE - 1) % BYTE
self
end
def next_var
unless @next
@next = TuringHead.new
@next.prev = self
end
@next
end
def prev_var
unless @prev
@prev = TuringHead.new
@prev.next = self
end
@prev
end
def print_value
print @value.chr
self
end
def get_value
@value = getc.ord
self
end
def loop_self(builder)
builder.loop_var self
end
end
|]
convert_brainfuck :: String -> String
convert_brainfuck "" = ""
convert_brainfuck ('+':rest) = ".increment" ++ convert_brainfuck rest
convert_brainfuck ('-':rest) = ".decrement" ++ convert_brainfuck rest
convert_brainfuck ('>':rest) = ".next_var" ++ convert_brainfuck rest
convert_brainfuck ('<':rest) = ".prev_var" ++ convert_brainfuck rest
convert_brainfuck ('.':rest) = ".print_value" ++ convert_brainfuck rest
convert_brainfuck (',':rest) = ".get_value" ++ convert_brainfuck rest
convert_brainfuck ('[':rest) = ".loop_self(BuildLambda.new" ++ convert_brainfuck rest
convert_brainfuck (']':rest) = ")" ++ convert_brainfuck rest
convert_brainfuck (_:rest) = convert_brainfuck rest
create_run :: String -> String
create_run input = "TuringHead.new" ++ (convert_brainfuck input)
create_program :: String -> String
create_program input = before_main ++ (create_run input)
brainfuck :: String
brainfuck = ">+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.[-]>++++++++[<++++>-]<.>+++++++++++[<+++++>-]<.>++++++++[<+++>-]<.+++.------.--------.[-]>++++++++[<++++>-]<+.[-]++++++++++."
-- main = putStrLn $ create_program brainfuck