Class: Lisp::AList

Inherits:
Object show all
Includes:
Enumerable
Defined in:
lib/rubylisp/alist.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(h = nil) ⇒ AList

Returns a new instance of AList.



94
95
96
# File 'lib/rubylisp/alist.rb', line 94

def initialize(h=nil)
  @value = h || {}
end

Class Method Details

.acons_impl(args, env) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/rubylisp/alist.rb', line 16

def self.acons_impl(args, env)
  raise "acons require at least 2 or 3 arguments" unless args.length == 2 || args.length == 3
  key = args.car.evaluate(env)
  value = args.cadr.evaluate(env)
  alist = args.length == 2 ? nil : args.caddr.evaluate(env)
  alist = Lisp::AList.from_list(alist) if !alist.nil? && alist.list? && !alist.alist?
  raise "the last argument to acons has to be an association list" unless alist.nil? || alist.alist?

  if alist.nil?
    Lisp::AList.new({key => value})
  else
    alist.acons(key, value)
  end
end

.alist_to_list_impl(args, env) ⇒ Object



76
77
78
79
80
81
82
83
# File 'lib/rubylisp/alist.rb', line 76

def self.alist_to_list_impl(args, env)
  raise "alist-to-list requires 1 arguments" unless args.length == 1
  alist = args.car.evaluate(env)
  return alist if alist.list? && !alist.alist?
  raise "the argument to alist-to-list has to be an association list" unless alist.alist?
        
  alist.to_list
end

.assoc_impl(args, env) ⇒ Object



31
32
33
34
35
36
37
38
# File 'lib/rubylisp/alist.rb', line 31

def self.assoc_impl(args, env)
  raise "assoc require 2 arguments" unless args.length == 2
  key = args.car.evaluate(env)
  alist = args.cadr.evaluate(env)
  alist = Lisp::AList.from_list(alist) if alist.list? && !alist.alist?
  raise "the last argument to assoc has to be an association list" unless alist.alist?
  alist.assoc(key)
end

.dissoc_impl(args, env) ⇒ Object



49
50
51
52
53
54
55
56
# File 'lib/rubylisp/alist.rb', line 49

def self.dissoc_impl(args, env)
  raise "assoc require 2 arguments" unless args.length == 2
  key = args.car.evaluate(env)
  alist = args.cadr.evaluate(env)
  alist = Lisp::AList.from_list(alist) if alist.list? && !alist.alist?
  raise "the last argument to dissoc has to be an association list" unless alist.alist?
  alist.dissoc(key)
end

.from_list(list) ⇒ Object



208
209
210
211
212
213
214
# File 'lib/rubylisp/alist.rb', line 208

def self.from_list(list)
  h = {}
  list.each do |pair|
    h[pair.car] = pair.cdr
  end
  self.new(h)
end

.list_to_alist_impl(args, env) ⇒ Object



85
86
87
88
89
90
91
# File 'lib/rubylisp/alist.rb', line 85

def self.list_to_alist_impl(args, env)
  raise "list-to-alist requires 1 arguments" unless args.length == 1
  list = args.car.evaluate(env)
  raise "the argument to list-to-alist has to be a list" unless list.list?
        
  Lisp::AList.from_list(list)
end

.rassoc_impl(args, env) ⇒ Object



40
41
42
43
44
45
46
47
# File 'lib/rubylisp/alist.rb', line 40

def self.rassoc_impl(args, env)
  raise "assoc require 2 arguments" unless args.length == 2
  value = args.car.evaluate(env)
  alist = args.cadr.evaluate(env)
  alist = Lisp::AList.from_list(alist) if alist.list? && !alist.alist?
  raise "the last argument to rassoc has to be an association list" unless alist.alist?
  alist.rassoc(value)
end

.registerObject



6
7
8
9
10
11
12
13
14
# File 'lib/rubylisp/alist.rb', line 6

def self.register
  Primitive.register("acons")         {|args, env| Lisp::AList::acons_impl(args, env) }
  Primitive.register("assoc")         {|args, env| Lisp::AList::assoc_impl(args, env) }
  Primitive.register("rassoc")        {|args, env| Lisp::AList::rassoc_impl(args, env) }
  Primitive.register("dissoc")        {|args, env| Lisp::AList::dissoc_impl(args, env) }
  Primitive.register("zip")           {|args, env| Lisp::AList::zip_impl(args, env) }
  Primitive.register("alist-to-list") {|args, env| Lisp::AList::alist_to_list_impl(args, env) }
  Primitive.register("list-to-alist") {|args, env| Lisp::AList::list_to_alist_impl(args, env) }
end

.zip(keys, values) ⇒ Object



204
205
206
# File 'lib/rubylisp/alist.rb', line 204

def self.zip(keys, values)
  self.new.zip(keys, values)
end

.zip_impl(args, env) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/rubylisp/alist.rb', line 58

def self.zip_impl(args, env)
  raise "assoc require 2 or 3arguments" unless args.length == 2 || args.length == 3
  key_list = args.car.evaluate(env)
  raise "the keys supplied to zip has to be a list" unless key_list.list?
  value_list = args.cadr.evaluate(env)
  raise "the values supplied to zip has to be a list" unless value_list.list?
  raise "zip requires the same number of keys and values" unless key_list.length == value_list.length

  if args.length == 3
    alist = args.caddr.evaluate(env)
    alist = Lisp::AList.from_list(alist) if alist.list? && !alist.alist?
    raise "the third argument to zip has to be an association list" unless alist.alist?
    alist.zip(key_list.to_a, value_list.to_a)
  else
    Lisp::AList.zip(key_list.to_a, value_list.to_a)
  end
end

Instance Method Details

#acons(k, v) ⇒ Object



178
179
180
181
# File 'lib/rubylisp/alist.rb', line 178

def acons(k, v)
  @value[k] = v
  self
end

#alist?Boolean

Returns:



159
160
161
# File 'lib/rubylisp/alist.rb', line 159

def alist?
  true
end

#assoc(k) ⇒ Object



183
184
185
186
# File 'lib/rubylisp/alist.rb', line 183

def assoc(k)
  v = @value[k]
  Lisp::ConsCell.cons(k, v)
end

#carObject



171
172
173
# File 'lib/rubylisp/alist.rb', line 171

def car
  @value.first
end

#cdrObject



175
176
# File 'lib/rubylisp/alist.rb', line 175

def cdr
end

#character?Boolean

Returns:



115
116
117
# File 'lib/rubylisp/alist.rb', line 115

def character?
  false
end

#dissoc(k) ⇒ Object



194
195
196
197
# File 'lib/rubylisp/alist.rb', line 194

def dissoc(k)
  @value.delete(k)
  self
end

#empty?Boolean

Returns:



107
108
109
# File 'lib/rubylisp/alist.rb', line 107

def empty?
  @value.empty?
end

#eq?(sexpr) ⇒ Boolean

Returns:



102
103
104
105
# File 'lib/rubylisp/alist.rb', line 102

def eq?(sexpr)
  return false unless sexpr.alist?
  @value == sexpr.value
end

#frame?Boolean

Returns:



163
164
165
# File 'lib/rubylisp/alist.rb', line 163

def frame?
  false
end

#function?Boolean

Returns:



143
144
145
# File 'lib/rubylisp/alist.rb', line 143

def function?
  false
end

#lengthObject



167
168
169
# File 'lib/rubylisp/alist.rb', line 167

def length
  return @value.length
end

#lisp_object?Boolean

Returns:



98
99
100
# File 'lib/rubylisp/alist.rb', line 98

def lisp_object?
  true
end

#list?Boolean

Returns:



155
156
157
# File 'lib/rubylisp/alist.rb', line 155

def list?
  true
end

#macro?Boolean

Returns:



147
148
149
# File 'lib/rubylisp/alist.rb', line 147

def macro?
  false
end

#negative?Boolean

Returns:



131
132
133
# File 'lib/rubylisp/alist.rb', line 131

def negative?
  false
end

#number?Boolean

Returns:



119
120
121
# File 'lib/rubylisp/alist.rb', line 119

def number?
  false
end

#pair?Boolean

Returns:



151
152
153
# File 'lib/rubylisp/alist.rb', line 151

def pair?
  true
end

#positive?Boolean

Returns:



123
124
125
# File 'lib/rubylisp/alist.rb', line 123

def positive?
  false
end

#primitive?Boolean

Returns:



139
140
141
# File 'lib/rubylisp/alist.rb', line 139

def primitive?
  false
end


224
225
226
# File 'lib/rubylisp/alist.rb', line 224

def print_string
  self.to_s
end

#rassoc(value) ⇒ Object



188
189
190
191
192
# File 'lib/rubylisp/alist.rb', line 188

def rassoc(value)
  @value.each do |k, v|
    return Lisp::ConsCell.cons(k, v) if value == v || value.eq?(v)
  end
end

#string?Boolean

Returns:



111
112
113
# File 'lib/rubylisp/alist.rb', line 111

def string?
  false
end

#symbol?Boolean

Returns:



135
136
137
# File 'lib/rubylisp/alist.rb', line 135

def symbol?
  false
end

#to_listObject



216
217
218
# File 'lib/rubylisp/alist.rb', line 216

def to_list
  Lisp::ConsCell.array_to_list(@value.map {|k, v| Lisp::ConsCell.cons(k, v)})
end

#to_sObject



220
221
222
# File 'lib/rubylisp/alist.rb', line 220

def to_s
  to_list.to_s
end

#zero?Boolean

Returns:



127
128
129
# File 'lib/rubylisp/alist.rb', line 127

def zero?
  false
end

#zip(keys, values) ⇒ Object



199
200
201
202
# File 'lib/rubylisp/alist.rb', line 199

def zip(keys, values)
  keys.zip(values).each {|k, v| @value[k] = v}
  self
end