Class: Lisp::PrimAssignment

Inherits:
Object show all
Defined in:
lib/rubylisp/prim_assignment.rb

Class Method Summary collapse

Class Method Details

.registerObject



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/rubylisp/prim_assignment.rb', line 5

def self.register
  Primitive.register("set!", "2",
                     "(set! name new-value)\n\nThe way to assign (i.e. rebind) a symbol. `name` is the symbol to be rebound.
The `new-value` sexpr is evaluated to arrive at the new value to be bound to. Use of `set!` is frowned upon, and should not be used without thought.",
                     true) { |args, env| Lisp::PrimAssignment::setbang_impl(args, env) }
  
  Primitive.register("set-car!", "2",
                     "(set-car! cons-cell new-value)\n\nSet the `car` pointer of `cons-cell`.") { |args, env| Lisp::PrimAssignment::setcarbang_impl(args, env) }
  
  Primitive.register("set-cdr!", "2",
                     "(set-cdr! cons-cell new-value)\n\nSet the `cdr` pointer of `cons-cell`.") { |args, env| Lisp::PrimAssignment::setcdrbang_impl(args, env) }
  
  Primitive.register("set-nth!", "3",
                     "(set-nth! n list-or-vector new-value)\n\nSets the `n`th element of `list-or-vector` to `new-value`.") { |args, env| Lisp::PrimAssignment::setnthbang_impl(args, env) }
  
end

.setbang_impl(args, env) ⇒ Object



23
24
25
26
27
28
# File 'lib/rubylisp/prim_assignment.rb', line 23

def self.setbang_impl(args, env)
  sym = args.car
  return Lisp::Debug.process_error("set! requires a raw (unevaluated) symbol as it's first argument.", env) unless sym.symbol?
  value = args.cadr.evaluate(env)
  env.set(sym, value)
end

.setcarbang_impl(args, env) ⇒ Object



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

def self.setcarbang_impl(args, env)
  pair = args.car
  return Lisp::Debug.process_error("set-car! requires a pair as it's first argument.", env) unless pair.pair?
  value = args.cadr
  pair.set_car!(value)
end

.setcdrbang_impl(args, env) ⇒ Object



39
40
41
42
43
44
# File 'lib/rubylisp/prim_assignment.rb', line 39

def self.setcdrbang_impl(args, env)
  pair = args.car
  return Lisp::Debug.process_error("set-cdr! requires a pair as it's first argument.", env) unless pair.pair?
  value = args.cadr
  pair.set_cdr!(value)
end

.setnthbang_impl(args, env) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
# File 'lib/rubylisp/prim_assignment.rb', line 47

def self.setnthbang_impl(args, env)
  n = args.car
  return Lisp::Debug.process_error("The first argument of set-nth! has to be an number.", env) unless n.number?
  return Lisp::Debug.process_error("The first argument of set-nth! has to be non negative.", env) unless n.value >= 0

  l = args.cadr
  return Lisp::Debug.process_error("set-nth! requires a list or vector as it's first argument.", env) unless l.list? || l.vector?
  value = args.caddr
  l.set_nth!(n.value, value)
  l
end