Execute SNUSP/Ruby: Difference between revisions

m
Fixed syntax highlighting.
(add Ruby)
 
m (Fixed syntax highlighting.)
 
(7 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 ===
<syntaxhighlight lang="ruby">$stdout.sync = true
<lang ruby>class CoreSNUSP
$stdin.sync = true
 
class CoreSNUSP
Bounce = {
:ruld => {:right => :up, :left => :down, :up => :right, :down => :left },
Line 19 ⟶ 22:
"." => :write,
"," => :read,
'"' => :dump,
})
 
def initialize(text, args={})
@data = Hash.new(0)
@dptr = 0
Line 28 ⟶ 32:
@width = @program[0].nil? ? 0 : @program[0].size
@pdir = :right
@input = args[:input]
end
 
Line 77 ⟶ 82:
@dptr += 1
end
 
def left
@dptr -= 1
end
 
def incr
if @dptr < 0
Line 87 ⟶ 94:
p ["data:",@dptr, @data[@dptr]] if $DEBUG
end
 
def decr
if @dptr < 0
Line 94 ⟶ 102:
p ["data:",@dptr, @data[@dptr]] if $DEBUG
end
 
def ruld
p @pdir if $DEBUG
Line 99 ⟶ 108:
p @pdir if $DEBUG
end
 
def lurd
p @pdir if $DEBUG
Line 104 ⟶ 114:
p @pdir if $DEBUG
end
 
def skipz
p ["data:",@dptr, @data[@dptr]] if $DEBUG
move if @data[@dptr] == 0
end
 
def skip
move
end
 
def write
printp "output: #{@data[@dptr]} = '#{@data[@dptr].chr}'" if $DEBUG
$stdout.print @data[@dptr].chr
end
 
def read
@data[@dptr] = $stdin if @input.getcnil?
# blocking read from stdin
$stdin.getc
else
@input.slice!(0)
end
p "read '#{@data[@dptr]}'" if $DEBUG
end
 
def dump
p [@dptr, @data]
end
 
def unknown; end
end
Line 149 ⟶ 174:
 
helloWorld = <<'PROGRAM'
/++++!/===========?\>++.>+.+++++++..+++\
\+++\ | /+>+++++++>/ /++++++++++<<.++>./
$+++/ | \+++++++++>\ \+++++.>.+++.-----\
\==-<<<<+>+++/ /=.>.+>.--------.-/
PROGRAM
snusp = CoreSNUSP.new(helloWorld)
Line 158 ⟶ 183:
puts "done"
 
end</langsyntaxhighlight>
 
Output:
<pre>$ ruby rc_coresnusp.rb
Line 167 ⟶ 193:
done</pre>
 
== =Modular SNUSP ===
<langsyntaxhighlight lang="ruby">require 'rc_coresnusp.rb'
 
class ModularSNUSP < CoreSNUSP
Line 176 ⟶ 202:
})
def initialize(text, args={})
super
@execution_stack = []
Line 237 ⟶ 263:
+ +
+ + print newline
+ + /-\
+ \.+++CR.---NL.!\?/<<#
|
| /<=!/!#++++\
Line 252 ⟶ 278:
#\?<<+>>-/
PROGRAM
snusp = ModularSNUSP.new(ackerman, :input => '33') # calculate A(3,3)
snusp.run
puts
puts "done"
 
end</langsyntaxhighlight>
Output:
<pre>$ echo '33' | ruby rc_modularsnusp.rb
Empty Program 2
done
Line 266 ⟶ 293:
Modular: Ackerman
 
61
61done</pre>
done</pre>
 
===Bloated SNUSP===
User input is still line-oriented -- must press Enter before Ruby sees input.
 
<syntaxhighlight lang="ruby">require 'rc_modularsnusp.rb'
== Bloated SNUSP ==
The threading is not correctly implemented -- the "BangBang" example is not working.
 
# here, need input to be non-blocking, so other "threads" can keep working.
<lang ruby>require 'rc_modularsnusp.rb'
# 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 283 ⟶ 316:
})
def initialize(text, args={})
super
@dptr = [0,0]
Line 293 ⟶ 326:
def add_thread
@thread_counter += 1
@threads[@thread_counter] = SNUSPThread.new(@pc.dup, @pdir, @execution_stack, @dptr.dup)
end
Line 341 ⟶ 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 406 ⟶ 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,476

edits