Module: Lisp

Included in:
DottedPair
Defined in:
lib/carat/lisp.rb,
lib/carat/lisp-format.rb

Overview

This module contains various Lisp facilities that are of general usefulness. Lisp’s rich string formatting language is implemented in the Format module. More modules may be added later.

TODO: the floating point functions are rather horendous

Defined Under Namespace

Modules: Format Classes: DottedPair

Constant Summary collapse

VERSION =
1.1

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.format(format, *args) ⇒ Object



1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
# File 'lib/carat/lisp-format.rb', line 1788

def Lisp.format(format, *args)
  begin 
    state = Format::State.new(args, Format::Output.new)
    formatter = Format::Formatter.new(format, state)
    formatter.run
  rescue => e
    puts 'Format error: ' + e.message
    puts format
    puts ' ' * (e.pos - 1) + '^' if e.respond_to? :pos
    raise
  end
end

Instance Method Details

#accumulate(fun, x, list) ⇒ Object Also known as: foldleft



276
277
278
279
280
281
282
# File 'lib/carat/lisp.rb', line 276

def accumulate(fun, x, list)
  if null?(list)
    x
  else
    accumulate(fun, fun.call(x, car(list)), cdr(list))
  end
end

#all?(pred, list) ⇒ Boolean



264
265
266
267
268
269
270
271
272
273
274
# File 'lib/carat/lisp.rb', line 264

def all?(pred, list)
  if null?(list)
    true
  else
    if pred.call(car(list))
      all?(pred, cdr(list))
    else
      false
    end
  end
end

#append(l, m) ⇒ Object



181
182
183
184
185
186
187
188
189
190
191
# File 'lib/carat/lisp.rb', line 181

def append(l, m)
  if null?(l)
    if null?(m)
      nil
    else
      cons(car(m), append(l, cdr(m)))
    end
  else
    cons(car(l), append(cdr(l), m))
  end
end

#assoc(x, list) ⇒ Object



247
248
249
250
# File 'lib/carat/lisp.rb', line 247

def assoc(x, list)
  f = filter(lambda { |y| x == car(y)}, list)
  if null?(f) then nil else car(f) end
end

#atom?(x) ⇒ Boolean



165
166
167
# File 'lib/carat/lisp.rb', line 165

def atom?(x)
  not pair?(x) || null?(x)
end

#car(pair) ⇒ Object



130
131
132
133
# File 'lib/carat/lisp.rb', line 130

def car(pair)
  pair = pair!(pair)
  pair.first
end

#cdr(pair) ⇒ Object



135
136
137
138
# File 'lib/carat/lisp.rb', line 135

def cdr(pair)
  pair = pair!(pair)
  pair.second
end

#cons(car, cdr) ⇒ Object

Functional API



122
123
124
# File 'lib/carat/lisp.rb', line 122

def cons(car, cdr)
  DottedPair.new(car, cdr)
end

#consonto(cdr, car) ⇒ Object



126
127
128
# File 'lib/carat/lisp.rb', line 126

def consonto(cdr, car)
  DottedPair.new(car, cdr)
end

#drop(l, n) ⇒ Object



328
329
330
331
332
333
334
# File 'lib/carat/lisp.rb', line 328

def drop(l, n)
  if n > 0 and not null?(l)
      drop(cdr(l), n - 1)
  else
      l
  end
end

#equal?(l, m) ⇒ Boolean



169
170
171
# File 'lib/carat/lisp.rb', line 169

def equal?(l, m)
  l == m
end

#exists?(pred, list) ⇒ Boolean



252
253
254
255
256
257
258
259
260
261
262
# File 'lib/carat/lisp.rb', line 252

def exists?(pred, list)
  if null?(list)
    false
  else
    if pred.call(car(list))
      true
    else
      exists?(pred, cdr(list))
    end
  end
end

#explode(string) ⇒ Object



300
301
302
# File 'lib/carat/lisp.rb', line 300

def explode(string)
  list(*(string.split(//)))
end

#filter(pred, list) ⇒ Object



235
236
237
238
239
240
241
242
243
244
245
# File 'lib/carat/lisp.rb', line 235

def filter(pred, list)
  if null?(list)
    nil
  else
    if pred.call(car(list))
      cons(car(list), filter(pred, cdr(list)))
    else
      filter(pred, cdr(list))
    end
  end
end

#implode(list) ⇒ Object



304
305
306
# File 'lib/carat/lisp.rb', line 304

def implode(list)
  accumulate(lambda { |x, y| x + y }, '', list)
end

#length(list) ⇒ Object



193
194
195
196
197
198
199
# File 'lib/carat/lisp.rb', line 193

def length(list)
  if null?(list)
    0
  else
    1 + length(cdr(list))
  end
end


296
297
298
# File 'lib/carat/lisp.rb', line 296

def link(lists)
  accumulate(lambda { |x, y| append(x, y) }, nil, lists)
end

#list(*elms) ⇒ Object



173
174
175
176
177
178
179
# File 'lib/carat/lisp.rb', line 173

def list(*elms)
  if elms.empty?
    nil
  else
    cons(elms.shift, list(*elms))
  end
end

#map(fun, list) ⇒ Object



201
202
203
204
205
206
207
# File 'lib/carat/lisp.rb', line 201

def map(fun, list)
  if null?(list)
    nil
  else
    cons(fun.call(car(list)), map(fun, cdr(list)))
  end
end

#member?(x, list) ⇒ Boolean



223
224
225
226
227
228
229
230
231
232
233
# File 'lib/carat/lisp.rb', line 223

def member?(x, list)
  if null?(list)
    false
  else
    if x == car(list)
      true
    else
      member?(x, cdr(list))
    end
  end
end

#null?(x) ⇒ Boolean



152
153
154
# File 'lib/carat/lisp.rb', line 152

def null?(x)
  x == nil
end

#pair!(x) ⇒ Object



160
161
162
163
# File 'lib/carat/lisp.rb', line 160

def pair!(x)
  return x if pair?(x)
  return DottedPair[*x]
end

#pair?(x) ⇒ Boolean



156
157
158
# File 'lib/carat/lisp.rb', line 156

def pair?(x)
  x.is_a?(DottedPair)
end

#pairlis(l, m) ⇒ Object



219
220
221
# File 'lib/carat/lisp.rb', line 219

def pairlis(l, m)
  zip(lambda { |x, y| cons(x, y) }, l, m)
end

#prod(list) ⇒ Object



312
313
314
# File 'lib/carat/lisp.rb', line 312

def prod(list)
  accumulate(lambda { |x, y| x * y }, 1, list)
end

#reduce(fun, x, list) ⇒ Object Also known as: foldright



286
287
288
289
290
291
292
# File 'lib/carat/lisp.rb', line 286

def reduce(fun, x, list)
  if null?(list)
    x
  else
    fun.call(car(list), reduce(fun, x, cdr(list)))
  end
end

#reverse(lists) ⇒ Object



316
317
318
# File 'lib/carat/lisp.rb', line 316

def reverse(lists)
  accumulate(lambda { |x, y| consonto(x, y) }, nil, lists)
end

#set(var, val, binding) ⇒ Object



140
141
142
# File 'lib/carat/lisp.rb', line 140

def set(var, val, binding)
  eval "var = #{val}", binding
end

#set_car!(pair, val) ⇒ Object



144
145
146
# File 'lib/carat/lisp.rb', line 144

def set_car!(pair, val)
  pair.first = val
end

#set_cdr!(pair, val) ⇒ Object



148
149
150
# File 'lib/carat/lisp.rb', line 148

def set_cdr!(pair, val)
  pair.second = val
end

#sum(list) ⇒ Object



308
309
310
# File 'lib/carat/lisp.rb', line 308

def sum(list)
  accumulate(lambda { |x, y| x + y }, 0, list)
end

#take(l, n) ⇒ Object



320
321
322
323
324
325
326
# File 'lib/carat/lisp.rb', line 320

def take(l, n)
  if n > 0 and not null?(l)
    cons(car(l), take(cdr(l), n - 1))
  else
    nil
  end
end

#zip(fun, l, m) ⇒ Object



209
210
211
212
213
214
215
216
217
# File 'lib/carat/lisp.rb', line 209

def zip(fun, l, m)
  if null?(l) and null?(m)
    nil
  elsif null?(l) or null?(m)
    raise ArgumentError.new("zip with unequal length lists")
  else
    cons(fun.call(car(l), car(m)), zip(fun, cdr(l), cdr(m)))
  end
end