Class: Lisp::Exception
Class Method Summary collapse
- .do_exception(name, with_message, args, env) ⇒ Object
- .raise_impl(args, env) ⇒ Object
- .register ⇒ Object
- .reraise_impl(args, env) ⇒ Object
- .restart_impl(args, env) ⇒ Object
- .resume_impl(args, env) ⇒ Object
- .try_impl(args, env) ⇒ Object
Instance Method Summary collapse
Class Method Details
.do_exception(name, with_message, args, env) ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/rubylisp/exception.rb', line 26 def self.do_exception(name, , args, env) frame = env while !frame.nil? handlers = frame.value_of(Symbol.named("__handlers__")) unless handlers.nil? handler = handler_or_nil(handlers, for: name) unless handler.nil? handler.apply_to_without_evaluating(args, in: frame) break end end frame = frame.parent if frame.nil? = .empty? ? "" : ": #{}" raise "Unhandled Exception: #{exception_name}#{}" end end end |
.raise_impl(args, env) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/rubylisp/exception.rb', line 45 def self.raise_impl(args, env) raise "'raise' requires at least one argument." unless args.length > 0 exception_name = args.car.evaluate(env) raise "'raise' requires an exception name as it's first argument." unless exception_name.string? || class_name.symbol? = "" if args.length > 1 = args.cadr.evaluate(env) raise "The message parameter to 'raise' must be a string." unless .string? end handler_args = args.length > 2 ? Lisp::ConsCell.array_to_list(args.cdr.to_a.collect {|a| a.evaluate(env)}) : Lisp::ConsCell.new end |
.register ⇒ Object
5 6 7 8 9 10 11 12 |
# File 'lib/rubylisp/exception.rb', line 5 def self.register Primitive.register("raise") {|args, env| Lisp::Exception::raise_impl(args, env) } Primitive.register("reraise") {|args, env| Lisp::Exception::reraise_impl(args, env) } Primitive.register("try") {|args, env| Lisp::Exception::try_impl(args, env) } Primitive.register("reraise") {|args, env| Lisp::Exception::reraise_impl(args, env) } Primitive.register("resume") {|args, env| Lisp::Exception::resume_impl(args, env) } Primitive.register("restart") {|args, env| Lisp::Exception::restart_impl(args, env) } end |
.reraise_impl(args, env) ⇒ Object
84 85 |
# File 'lib/rubylisp/exception.rb', line 84 def self.reraise_impl(args, env) end |
.restart_impl(args, env) ⇒ Object
92 93 |
# File 'lib/rubylisp/exception.rb', line 92 def self.restart_impl(args, env) end |
.resume_impl(args, env) ⇒ Object
88 89 |
# File 'lib/rubylisp/exception.rb', line 88 def self.resume_impl(args, env) end |
.try_impl(args, env) ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/rubylisp/exception.rb', line 60 def self.try_impl(args, env) raw_handlers = args.car body = args.cdr raise "Exception handlers must be a list." unless raw_handlers.list? raise "Exception handlers must be a list of pairs." unless raw_handlers.all? {|h| h.list?} raise "Exception clause must be a symbol/string or a list of symbol/string." unless raw_handlers.all? do |h| ex = h.car ex.symbol? || ex.string? || (ex.list? && ex.all? {|h2| h2.symbol? || h2.string?}) end array_of_handlers = raw_handlers.to_a.collect do |h| ex = h.car f = h.cadr.evaluate(env) raise "Exception handler has to be a function." unless f.function? Lisp::ConsCell.cons(ex, f) end handlers = Lisp::ConsCell.array_to_list(array_of_handlers) env.bind_locally(Symbol.named("__handlers__"), handlers) body.evaluate_each(env) end |
Instance Method Details
#handler_or_nil(handlers, exception_name) ⇒ Object
15 16 17 18 19 20 21 22 23 24 |
# File 'lib/rubylisp/exception.rb', line 15 def handler_or_nil(handlers, exception_name) handlers.each do |handler_pair| exceptions = handler_pair.car if exceptions.eq(exception_name) || (exceptions.pair? && exceptions.include?(exception_name)) handler_pair.cdr else nil end end end |