Execute SNUSP/Ruby: Difference between revisions

m
Fixed syntax highlighting.
m (→‎Modular SNUSP: pass user input as a string)
m (Fixed syntax highlighting.)
 
(5 intermediate revisions by 3 users not shown)
Line 1:
{{implementation|SNUSP}}{{collection|RCSNUSP}}[[Category:Ruby]]
These [[Ruby]] implementations of SNUSP profiles are partially derived from [[RCSNUSP/Tcl]].
With gratitude to [[RCSNUSP/Tcl]]
== =Core SNUSP ===
<langsyntaxhighlight lang="ruby">$stdout.sync = true
$stdin.sync = true
 
Line 183:
puts "done"
 
end</langsyntaxhighlight>
 
Output:
Line 193:
done</pre>
 
== =Modular SNUSP ===
<langsyntaxhighlight lang="ruby">require 'rc_coresnusp.rb'
 
class ModularSNUSP < CoreSNUSP
Line 283:
puts "done"
 
end</langsyntaxhighlight>
Output:
<pre>$ echo '33' | ruby rc_modularsnusp.rb
Empty Program 2
done
Line 293:
Modular: Ackerman
 
61
61donedone</pre>
 
== =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.
 
<langsyntaxhighlight 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 310 ⟶ 316:
})
def initialize(text, args={})
super
@dptr = [0,0]
Line 320 ⟶ 326:
def add_thread
@thread_counter += 1
@threads[@thread_counter] = SNUSPThread.new(@pc.dup, @pdir, @execution_stack, @dptr.dup)
end
Line 368 ⟶ 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 433 ⟶ 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</syntaxhighlight>
 
Output:
<div style="width:full;overflow:scroll"><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></div>
9,477

edits