class Lisp::PrimAssignment

Public Class Methods

register() click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# 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