Created
February 11, 2017 16:21
-
-
Save seki/062c65f9e5657aef785b792f2b15ba52 to your computer and use it in GitHub Desktop.
cons on Rinda
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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