Skip to content

Instantly share code, notes, and snippets.

@seki
Created February 11, 2017 16:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save seki/062c65f9e5657aef785b792f2b15ba52 to your computer and use it in GitHub Desktop.
Save seki/062c65f9e5657aef785b792f2b15ba52 to your computer and use it in GitHub Desktop.
cons on Rinda
require 'rinda/tuplespace'
require 'drb'
class Risp
Ptr = Struct.new(:ptr)
class Ptr
def initialize(ptr)
self.ptr = ptr
end
def succ
self.class.new(self.ptr + 1)
end
def ==(other)
self.ptr == other.ptr
end
end
def initialize(ts)
@ts = ts
end
def init
@ts.write([:seq, Ptr.new(0)])
end
def alloc
_, ptr = @ts.take([:seq, nil])
ptr = ptr.succ
@ts.write([:seq, ptr])
ptr
end
def cons(a, b=nil)
ptr = alloc
b = @nil if b.nil?
@ts.write([ptr, :cell, a, b])
ptr
end
def car(ptr)
return nil if ptr.nil?
raise unless Ptr == ptr.class
@ts.read([ptr, :cell, nil, nil])[2]
end
def cdr(ptr)
return nil if ptr.nil?
raise unless Ptr == ptr.class
@ts.read([ptr, :cell, nil, nil])[3]
end
def list(*args)
return @nil if args.empty?
cons(args.shift, list(*args))
end
def _set_(ptr)
raise unless Ptr == ptr.class
begin
tuple = @ts.take([ptr, :cell, nil, nil])
tuple[2], tuple[3] = yield(tuple[2], tuple[3])
ensure
@ts.write(tuple)
end
ptr
end
def setcar(ptr, value=nil)
return setcar(ptr) {value} unless block_given?
_set_(ptr) do |car, cdr|
[yield(car, cdr), cdr]
end
end
def setcdr(ptr, value=nil)
return setcdr(ptr) {value} unless block_given?
_set_(ptr) do |car, cdr|
[car, yield(car, cdr)]
end
end
end
env = Risp.new(Rinda::TupleSpace.new)
env.init
DRb.start_service('drbunix:/tmp/risp.drb', env)
puts DRb.uri
DRb.thread.join
=begin
Terminal 1
> ruby risp.rb
Terminal 2
> irb -r drb
%> env = DRbObject.new_with_uri('drbunix:/tmp/risp.drb')
%> list = env.list('hello', 'world.')
%> env.car(list)
%> env.car(env.cdr(list))
=end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment