Skip to content

Commit d54a4e9

Browse files
committed
Hello World is possible now
1 parent 8194f69 commit d54a4e9

File tree

3 files changed

+141
-17
lines changed

3 files changed

+141
-17
lines changed

mode.rb

+113-17
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def move
5353
end
5454

5555
def push val
56-
@state.stack << val
56+
@state.push val
5757
end
5858

5959
def pop
@@ -65,24 +65,13 @@ def shift
6565
end
6666

6767
def unshift val
68-
@state.stack.unshift val
68+
@state.unshift val
6969
end
7070

7171
def peek
7272
raise NotImplementedError
7373
end
7474

75-
def read_byte
76-
result = nil
77-
if @next_byte
78-
result = @next_byte
79-
@next_byte = nil
80-
else
81-
result = @in_str.getc
82-
end
83-
result
84-
end
85-
8675
end
8776

8877
class Cardinal < Mode
@@ -116,6 +105,9 @@ class Cardinal < Mode
116105
'"' => :string_mode,
117106
"'" => :escape,
118107

108+
'i' => :input,
109+
'o' => :output,
110+
119111
#'(' => ,
120112
#')' => ,
121113

@@ -146,6 +138,26 @@ def move
146138
@state.wrap
147139
end
148140

141+
def pop
142+
loop do
143+
val = @state.pop
144+
if val.is_a?(String)
145+
found = false
146+
val.scan(/-?\d+/) { push $&.to_i; found = true }
147+
next if !found
148+
val = @state.pop
149+
end
150+
151+
break
152+
end
153+
154+
val || 0
155+
end
156+
157+
def process_string
158+
@state.stack += @state.current_string
159+
end
160+
149161
def process opcode, cmd
150162
case opcode
151163
when :terminate
@@ -155,6 +167,51 @@ def process opcode, cmd
155167
@state.set_ordinal
156168
when :wall
157169
@state.dir = @state.dir.reflect cmd.chr
170+
when :move_east
171+
@state.dir = East.new
172+
when :move_west
173+
@state.dir = West.new
174+
when :move_south
175+
@state.dir = South.new
176+
when :move_north
177+
@state.dir = North.new
178+
when :turn_left
179+
@state.dir = @state.dir.left
180+
when :turn_right
181+
@state.dir = @state.dir.right
182+
183+
when :mp_left
184+
@state.mp -= 1
185+
when :mp_right
186+
@state.mp += 1
187+
188+
when :string_mode
189+
@state.string_mode = true
190+
when :escape
191+
move
192+
push @state.cell
193+
194+
when :input
195+
char = @state.in_str.getc
196+
push(char ? char.ord : -1)
197+
when :output
198+
@state.out_str << pop.chr
199+
200+
when :digit
201+
push cmd.chr.to_i
202+
when :add
203+
push(pop + pop)
204+
when :sub
205+
y = pop
206+
push(pop - y)
207+
when :mul
208+
push(pop * pop)
209+
when :div
210+
y = pop
211+
push(pop / y)
212+
when :mod
213+
y = pop
214+
push(pop % y)
158215
end
159216
end
160217
end
@@ -175,17 +232,20 @@ class Ordinal < Mode
175232
':' => :split,
176233
'%' => :mod,
177234

178-
'<' => :rotate_west,
179-
'>' => :rotate_east,
180-
'^' => :rotate_north,
181-
'v' => :rotate_south,
235+
'<' => :ensure_west,
236+
'>' => :ensure_east,
237+
'^' => :ensure_north,
238+
'v' => :ensure_south,
182239

183240
'{' => :strafe_left,
184241
'}' => :strafe_right,
185242

186243
'"' => :string_mode,
187244
"'" => :escape,
188245

246+
'i' => :input,
247+
'o' => :output,
248+
189249
#'(' => ,
190250
#')' => ,
191251

@@ -226,6 +286,17 @@ def move
226286
@state.ip += @state.dir.vec
227287
end
228288

289+
def pop
290+
val = @state.pop
291+
292+
val ? val.to_s : ''
293+
end
294+
295+
def process_string
296+
# Will throw an error when cell isn't a valid code point
297+
push @state.current_string.map(&:chr)*''
298+
end
299+
229300
def process opcode, cmd
230301
case opcode
231302
when :terminate
@@ -235,6 +306,31 @@ def process opcode, cmd
235306
@state.set_cardinal
236307
when :wall
237308
@state.dir = @state.dir.reflect cmd.chr
309+
when :ensure_west
310+
@state.dir = @state.dir.reflect cmd.chr if @state.dir.x > 0
311+
when :ensure_east
312+
@state.dir = @state.dir.reflect cmd.chr if @state.dir.x < 0
313+
when :ensure_north
314+
@state.dir = @state.dir.reflect cmd.chr if @state.dir.y > 0
315+
when :ensure_south
316+
@state.dir = @state.dir.reflect cmd.chr if @state.dir.y < 0
317+
when :strafe_left
318+
@state.ip += (@state.dir.reverse + @state.dir.left) / 2
319+
when :strafe_right
320+
@state.ip += (@state.dir.reverse + @state.dir.right) / 2
321+
when :string_mode
322+
@state.string_mode = true
323+
when :escape
324+
move
325+
push @state.cell.chr # Will throw an error when cell isn't a valid code point
326+
327+
when :digit
328+
push(pop + cmd.chr)
329+
when :input
330+
line = @state.in_str.gets
331+
push(line ? line.chomp : '')
332+
when :output
333+
@state.out_str << pop
238334
end
239335
end
240336
end

point2d.rb

+12
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,18 @@ def -(other)
2323
end
2424
end
2525

26+
def *(other)
27+
if other.is_a?(Numeric)
28+
return Point2D.new(@x*other, @y*other)
29+
end
30+
end
31+
32+
def /(other)
33+
if other.is_a?(Numeric)
34+
return Point2D.new(@x/other, @y/other)
35+
end
36+
end
37+
2638
def coerce(other)
2739
return self, other
2840
end

state.rb

+16
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,22 @@ def set_ordinal
7676
@mode = @ordinal
7777
end
7878

79+
def push val
80+
@stack << val
81+
end
82+
83+
def pop
84+
@stack.pop
85+
end
86+
87+
def shift
88+
@stack.shift
89+
end
90+
91+
def unshift val
92+
@stack.unshift val
93+
end
94+
7995
private
8096

8197
def parse(src)

0 commit comments

Comments
 (0)