Execute SNUSP/Ruby: Difference between revisions

m
→‎Bloated SNUSP: fixed threadring
m (→‎Bloated SNUSP: fixed threadring)
Line 297:
 
== Bloated SNUSP ==
User input is still line-oriented -- must press Enter before Ruby sees input.
The threading is not correctly implemented -- the "BangBang" example is not working.
 
<lang ruby>require 'rc_modularsnusp.rb'
 
# here, need input to be non-blocking, so other "threads" can keep working.
# we'll have to simulate blocking when reading a character from stdin. see read() below
require 'fcntl'
$stdin.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK)
 
SNUSPThread = Struct.new(:pc, :pdir, :execution_stack, :dptr)
Line 311 ⟶ 316:
})
def initialize(text, args={})
super
@dptr = [0,0]
Line 321 ⟶ 326:
def add_thread
@thread_counter += 1
@threads[@thread_counter] = SNUSPThread.new(@pc.dup, @pdir, @execution_stack, @dptr.dup)
end
Line 369 ⟶ 374:
@pc, @pdir = @execution_stack.pop
p @execution_stack if $DEBUG
end
 
def read
# we want input to be blocking. However, actual blocking on stdin will halt
# all other running "threads". So, what we do here is to set stdin to be
# non-blocking (at top of this file), and if we fail to read a character,
# we backup the program counter so we attempt to read again at the next tick.
char = if @input.nil?
begin
$stdin.sysread(1)
rescue SystemCallError
nil
end
else
@input.slice!(0)
end
if char.nil?
p "no data to read" if $DEBUG
# backup, so we can poll again in the next tick.
reverse_direction = {:up => :down, :down => :up, :right => :left, :left => :right}
@pdir = reverse_direction[@pdir]
move
@pdir = reverse_direction[@pdir]
else
@data[@dptr] = char
p "read '#{@data[@dptr]}'" if $DEBUG
end
end
Line 434 ⟶ 466:
puts "done"
 
$stdin.read # clear stdin before next interactive program
end
 
</lang>
# programs from http://www.baumanfamily.com/john/esoteric.html
puts "Bloated: randout"
randout = <<'PROGRAM'
//?\!===.====/!=\/\/\/\/=!\\
|\-/++\ | ++++++++ \/
| + + | ++++++++
| + + | ++++++++
| + + < \/\/\/\/
$==&\=+/ \+=%>?!/====#
|
|
|
\==>==,==#
PROGRAM
snusp = BloatedSNUSP.new(randout)
snusp.run
puts "done"
 
end</lang>
 
Output:
<pre>$ ruby rc_bloatedsnusp.rb
Bloated: random
3476158785073done
426844146737605042562646108481049454738617585534012246132619612443400509062done
Bloated: BangBang</pre>
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!j!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
The program hangs there, awaiting user input, without printing any exclamation marks. Hmmm.
done
Bloated: randout
35382407644156390115:505854:46783082311335:4940492329597706::155
2done
</pre>
Anonymous user