hammock-ruby 0.0.1.alpha

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +132 -0
  3. data/bin/hammock +55 -0
  4. data/lib/clojure/core.clj +6872 -0
  5. data/lib/hammock.rb +0 -0
  6. data/lib/hammock/aref.rb +57 -0
  7. data/lib/hammock/array_chunk.rb +49 -0
  8. data/lib/hammock/atom.rb +50 -0
  9. data/lib/hammock/block.rb +8 -0
  10. data/lib/hammock/chunk_buffer.rb +25 -0
  11. data/lib/hammock/chunked_cons.rb +108 -0
  12. data/lib/hammock/chunked_seq.rb +97 -0
  13. data/lib/hammock/compiler.rb +197 -0
  14. data/lib/hammock/environment.rb +40 -0
  15. data/lib/hammock/errors.rb +14 -0
  16. data/lib/hammock/function.rb +187 -0
  17. data/lib/hammock/ichunked_seq.rb +23 -0
  18. data/lib/hammock/ideref.rb +5 -0
  19. data/lib/hammock/ifn.rb +10 -0
  20. data/lib/hammock/ilookup.rb +6 -0
  21. data/lib/hammock/interfaces.rb +80 -0
  22. data/lib/hammock/ipersistent_collection.rb +15 -0
  23. data/lib/hammock/ireference.rb +15 -0
  24. data/lib/hammock/iseq.rb +12 -0
  25. data/lib/hammock/lazy_sequence.rb +82 -0
  26. data/lib/hammock/lazy_transformer.rb +169 -0
  27. data/lib/hammock/list.rb +232 -0
  28. data/lib/hammock/loop_locals.rb +34 -0
  29. data/lib/hammock/map.rb +205 -0
  30. data/lib/hammock/meta.rb +12 -0
  31. data/lib/hammock/multi_method.rb +52 -0
  32. data/lib/hammock/namespace.rb +185 -0
  33. data/lib/hammock/reader.rb +570 -0
  34. data/lib/hammock/recur_locals.rb +16 -0
  35. data/lib/hammock/reduced.rb +15 -0
  36. data/lib/hammock/repl.rb +29 -0
  37. data/lib/hammock/rt.rb +580 -0
  38. data/lib/hammock/sequence.rb +59 -0
  39. data/lib/hammock/set.rb +144 -0
  40. data/lib/hammock/stream.rb +40 -0
  41. data/lib/hammock/symbol.rb +65 -0
  42. data/lib/hammock/var.rb +186 -0
  43. data/lib/hammock/vector.rb +309 -0
  44. data/lib/hammock/version.rb +3 -0
  45. data/lib/hammock/volatile.rb +19 -0
  46. data/spec/examples/data.hmk +4 -0
  47. data/spec/hammock/reader_spec.rb +242 -0
  48. data/spec/hammock/rt_spec.rb +10 -0
  49. data/spec/hammock/sequence_spec.rb +24 -0
  50. metadata +139 -0
@@ -0,0 +1,40 @@
1
+ module Hammock
2
+ class Environment
3
+ attr_reader :frame
4
+
5
+ def initialize(frame)
6
+ unless Hammock::Map === frame
7
+ frame = Hammock::Map.create frame
8
+ end
9
+ @frame = frame
10
+ end
11
+
12
+ def bind(name, val)
13
+ self.class.new(@frame.assoc name, val)
14
+ end
15
+
16
+ def merge(env)
17
+ self.class.new(@frame.merge(env.frame))
18
+ end
19
+
20
+ def find(name)
21
+ if item = @frame[name]
22
+ item
23
+ end
24
+ end
25
+ alias [] find
26
+
27
+ def key?(name)
28
+ @frame.key?(name)
29
+ end
30
+
31
+ def inspect
32
+ parts = []
33
+ f = frame.each do |k,v|
34
+ parts << " #{k}\t#{v.inspect}"
35
+ end
36
+ "#<#{self.class}\n#{parts.join("\n")}"
37
+ end
38
+ alias to_s inspect
39
+ end
40
+ end
@@ -0,0 +1,14 @@
1
+ module Hammock
2
+ class Error < StandardError
3
+ end
4
+
5
+ class CompileError < Error
6
+ def initialize(form, msg=nil)
7
+ parts = [msg || "Error compiling form"]
8
+ if Meta === form && form.meta && form.meta[:line]
9
+ parts << "Originated from #{form.meta[:file]}:#{form.meta[:line]}, col #{form.meta[:column]}"
10
+ end
11
+ super(parts.join("\n"))
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,187 @@
1
+ require 'hammock/meta'
2
+ require 'hammock/ifn'
3
+
4
+ module Hammock
5
+ class Function
6
+ include Meta
7
+ include IFn
8
+
9
+ attr_reader :arities
10
+ attr_writer :meta
11
+
12
+ def self.alloc_from(fn, meta)
13
+ new(fn.internal_name, fn.ns, fn.env, fn.arities).tap do |fn|
14
+ fn.meta = meta
15
+ end
16
+ end
17
+
18
+ def self.create(name, ns, env, arities)
19
+ new(name, ns, env, arities)
20
+ end
21
+
22
+ def initialize(internal_name, ns, env, arities)
23
+ @internal_name = internal_name || generate_name
24
+ @ns = ns
25
+ @env = env
26
+ @arities = arities
27
+ @meta = nil
28
+ end
29
+
30
+ def variadic?
31
+ arities.any?(&:variadic?)
32
+ end
33
+
34
+ def arity_counts
35
+ arities.map(&:arity)
36
+ end
37
+
38
+ def find_arity!(*args)
39
+ needed = args.to_a.length
40
+ arities.detect {|a| a.handles_arity?(needed)} or \
41
+ raise ArgumentError, wrong_arity_message(needed)
42
+ end
43
+
44
+ def wrong_arity_message(needed)
45
+ c = arity_counts.map(&:to_s)
46
+ c << "more" if variadic?
47
+ if c.length == 1
48
+ counts = c.first
49
+ else
50
+ counts = c[0..-2].join(", ") + " or #{c.last}"
51
+ end
52
+ "Wrong number of args passed to #{name}. Expected #{counts}; Got #{needed}"
53
+ end
54
+
55
+ def name
56
+ "#{ns.name}/#@internal_name"
57
+ end
58
+
59
+ def meta=(meta)
60
+ @meta = meta
61
+ end
62
+
63
+ def trace
64
+ return unless meta
65
+ "#{meta[:file]}:#{meta[:line]} in #@internal_name"
66
+ end
67
+
68
+ def to_proc
69
+ fn = self
70
+ lambda { |*args| fn.call(*args) }
71
+ end
72
+
73
+ def to_block
74
+ Block.new(self)
75
+ end
76
+
77
+ def call(*args)
78
+ arity = find_arity!(*args)
79
+
80
+ env = @env.bind("__namespace__", @ns)
81
+ env = env.bind(@internal_name, self)
82
+
83
+ locals = args
84
+
85
+ loop do
86
+ env = arity.bind_env(env, locals.to_a)
87
+ ret = nil
88
+ body = arity.body.dup
89
+ until body.empty?
90
+ ret = Compiler.evaluate(env, body.first)
91
+ body.shift
92
+ end
93
+ if RecurLocals === ret
94
+ if ret.to_a.last.nil?
95
+ locals = ret.to_a[0..-2]
96
+ else
97
+ locals = ret
98
+ end
99
+ else
100
+ break ret
101
+ end
102
+ end
103
+ end
104
+
105
+ def inspect
106
+ "#<Hammock::Function #@internal_name>"
107
+ end
108
+
109
+ protected
110
+
111
+ attr_reader :ns, :env, :internal_name
112
+
113
+ private
114
+
115
+ def generate_name
116
+ "fn__#{RT.next_id}"
117
+ end
118
+
119
+ class Arity
120
+ AMPERSAND = Symbol.intern("&")
121
+
122
+ attr_reader :bindings, :body, :arity, :args
123
+
124
+ def initialize(bindings, *body)
125
+ @bindings, @body = bindings, body
126
+ @locals, @args, @variadic, @variadic_name = unpack_args(bindings)
127
+ @arity = @args.length
128
+ end
129
+
130
+ def bind_env(env, args)
131
+ max = variadic? ? @args.length - 1 : @args.length
132
+
133
+ 0.upto(max) do |i|
134
+ env = env.bind @args[i], args[i]
135
+ end
136
+
137
+ if variadic?
138
+ lastarg = nil
139
+ if args.length > max
140
+ tail = args[max..-1]
141
+ lastarg = Sequence.from_array(tail) if tail && !tail.empty?
142
+ end
143
+ env = env.bind @variadic_name, lastarg
144
+ end
145
+
146
+ env
147
+ end
148
+
149
+ def handles_arity?(count)
150
+ if variadic?
151
+ count >= @arity - 1
152
+ else
153
+ count == @arity
154
+ end
155
+ end
156
+
157
+ def variadic?
158
+ @variadic
159
+ end
160
+
161
+ def unpack_args(form)
162
+ locals = {}
163
+ args = []
164
+ lastisargs = false
165
+ argsname = nil
166
+
167
+ form.each do |x|
168
+ if x == AMPERSAND
169
+ lastisargs = true
170
+ next
171
+ end
172
+ if lastisargs and argsname
173
+ raise "variable length argument must be the last in the function #{form.inspect}"
174
+ end
175
+ argsname = x.name if lastisargs
176
+ if !(Symbol === x) || x.ns
177
+ raise "fn* arguments must be non namespaced symbols, got #{x}: in #{form.inspect}"
178
+ end
179
+ locals[x] = RT.list(x)
180
+ args << x.name
181
+ end
182
+
183
+ return locals, args, lastisargs, argsname
184
+ end
185
+ end
186
+ end
187
+ end
@@ -0,0 +1,23 @@
1
+ module Hammock
2
+ module IChunkedSeq
3
+ Undefined = Object.new
4
+
5
+ def nth(n, notfound=Undefined)
6
+ list = seq
7
+
8
+ n.times do
9
+ list = list.rest
10
+ end
11
+
12
+ if list.empty?
13
+ if notfound == Undefined
14
+ raise IndexError
15
+ else
16
+ notfound
17
+ end
18
+ else
19
+ list.first
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,5 @@
1
+ module Hammock
2
+ module IDeref
3
+ # def deref; end
4
+ end
5
+ end
@@ -0,0 +1,10 @@
1
+ module Hammock
2
+ module IFn
3
+ # def call(*args)
4
+ # end
5
+
6
+ def apply_to(sequence)
7
+ call(*sequence.to_a)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,6 @@
1
+ module Hammock
2
+ module ILookup
3
+ # def fetch(key, default=Undefined)
4
+ # end
5
+ end
6
+ end
@@ -0,0 +1,80 @@
1
+ module IPersistentCollection
2
+ # returns int
3
+ def count; end
4
+
5
+ # returns a collection
6
+ def cons(obj); end
7
+
8
+ # returns empty collection
9
+ def empty(); end
10
+
11
+ # returns true or false
12
+ # def equiv(obj); end
13
+ end
14
+
15
+ module IPersistentVector
16
+ # returns int
17
+ def length; end
18
+
19
+ # returns IPersistentVector
20
+ def assocN(i, obj); end
21
+
22
+ # returns IPersistentVector
23
+ def cons(obj); end
24
+ end
25
+
26
+ module ILookup
27
+ def val_at(key, not_found=nil); end
28
+ end
29
+
30
+ module Associative
31
+ # returns MapEntry
32
+ def entry_at(key); end
33
+
34
+ # returns Associative
35
+ def assoc(key, val); end
36
+ end
37
+
38
+ module IPersistentMap
39
+ # returns IPersistentMap
40
+ def assoc(key, val); end
41
+
42
+ # returns IPersistentMap
43
+ def assocEx(key, val); end
44
+
45
+ # returns IPersistentMap
46
+ def without(key); end
47
+ end
48
+
49
+ module IMeta
50
+ def meta; end
51
+ end
52
+
53
+ module IObj
54
+ # returns IObj
55
+ def with_meta(meta); end
56
+ end
57
+
58
+ module ISeq
59
+ def first; end
60
+ def next; end
61
+ def more; end
62
+ def cons(obj); end
63
+ end
64
+
65
+ module IFn
66
+ def invoke(*args); end
67
+ end
68
+
69
+ module IReduce
70
+ def reduce(fn, start=nil); end
71
+ end
72
+
73
+ # module IEditableCollection
74
+ # def as_transient; end
75
+ # end
76
+
77
+ # module ITransientCollection
78
+ # def conj(obj); end
79
+ # def persistent; end
80
+ # end
@@ -0,0 +1,15 @@
1
+ module Hammock
2
+ module IPersistentCollection
3
+ # returns int
4
+ def count; end
5
+
6
+ # returns a collection
7
+ def cons(obj); end
8
+
9
+ # returns empty collection
10
+ def empty(); end
11
+
12
+ # returns true or false
13
+ # def equiv(obj); end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'hammock/meta'
2
+
3
+ module Hammock
4
+ module IReference
5
+ include Meta
6
+ def reset_meta(meta)
7
+ @meta = meta
8
+ end
9
+
10
+ def alter_meta(fn, args)
11
+ args = [@meta] + args.to_a
12
+ @meta = fn.invoke(*args)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,12 @@
1
+ module Hammock
2
+ module ISeq
3
+ def first; end
4
+ def next; end
5
+ def rest; end
6
+
7
+ # override
8
+ def cons(obj)
9
+ Sequence.new(obj, self)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,82 @@
1
+ require 'atomic'
2
+ require 'hammock/meta'
3
+ require 'hammock/list'
4
+
5
+ module Hammock
6
+ class LazySequence
7
+ include List
8
+ include Meta
9
+
10
+ attr_reader :s
11
+
12
+ def self.alloc_from(ls, meta=nil)
13
+ new(meta, ls.fn, ls.s)
14
+ end
15
+
16
+ def initialize(meta=nil, fn=nil, s=nil)
17
+ @meta = meta
18
+ @fn = Atomic.new(fn)
19
+ @s = s
20
+ @target = nil
21
+ end
22
+
23
+ def seq
24
+ list = sval
25
+ while list.is_a?(LazySequence)
26
+ list = list.sval
27
+ end
28
+ @s = RT.seq(list)
29
+ end
30
+
31
+ def empty?
32
+ seq.nil?
33
+ end
34
+
35
+ def head
36
+ seq
37
+ return nil if @s.nil?
38
+ @s.head
39
+ end
40
+
41
+ def tail
42
+ seq
43
+ return nil if @s.nil?
44
+ @s.tail
45
+ end
46
+
47
+ def rest
48
+ seq
49
+ return EmptyList.new if @s.nil?
50
+ @s.rest
51
+ end
52
+
53
+ def each
54
+ return self unless block_given?
55
+ list = self
56
+ while !list.empty?
57
+ yield(list.head)
58
+ list = list.rest
59
+ end
60
+ end
61
+
62
+ def inspect
63
+ seq.inspect
64
+ end
65
+
66
+ def fn
67
+ @fn.value
68
+ end
69
+
70
+ protected
71
+
72
+ def sval
73
+ unless fn.nil?
74
+ @fn.update do |v|
75
+ @target = v.call
76
+ nil
77
+ end
78
+ end
79
+ @target.nil? ? @s : @target
80
+ end
81
+ end
82
+ end