Method: Lisp::PrimEnvironment.make_top_level_environment_impl

Defined in:
lib/rubylisp/prim_environment.rb

.make_top_level_environment_impl(args, env) ⇒ Object



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/rubylisp/prim_environment.rb', line 167

def self.make_top_level_environment_impl(args, env)
  if args.car.string?
    name = args.car.value
    args = args.cdr
  else
    name = "anonymous top level"
  end

  new_env = Lisp::EnvironmentFrame.extending(Lisp::EnvironmentFrame.global, name)
  if args.length == 1
    return Lisp::Debug.process_error("make-top-level-environment expects binding names to be a list", env) unless args.car.list?
    args.to_a.map do |a|
      return Lisp::Debug.process_error("make-top-level-environment expects each binding name to be a symbol", env) unless a.car.symbol?
      new_env.bind_locally_to(a.car, nil)
    end
  elsif args.length == 2
    return Lisp::Debug.process_error("make-top-level-environment expects binding names to be a list", env) unless args.car.list?
    return Lisp::Debug.process_error("make-top-level-environment expects binding values to be a list", env) unless args.cadr.list?
    return Lisp::Debug.process_error("make-top-level-environment expects binding name and value lists to be the same length", env) if args.car.length != args.cadr.length
    args.car.zip(args.cadr).map do |name, value|
      return Lisp::Debug.process_error("make-top-level-environment expects each binding name to be a symbol", env) unless name.symbol?
      new_env.bind_locally_to(name, value)
    end
  end
  return Lisp::Environment.with_value(new_env)
end