hammock-ruby 0.0.1.alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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