| // Copyright 2009 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package eval |
| |
| import ( |
| "fmt" |
| "os" |
| "runtime" |
| ) |
| |
| // Abort aborts the thread's current computation, |
| // causing the innermost Try to return err. |
| func (t *Thread) Abort(err os.Error) { |
| if t.abort == nil { |
| panic("abort: " + err.String()) |
| } |
| t.abort <- err |
| runtime.Goexit() |
| } |
| |
| // Try executes a computation; if the computation |
| // Aborts, Try returns the error passed to abort. |
| func (t *Thread) Try(f func(t *Thread)) os.Error { |
| oc := t.abort |
| c := make(chan os.Error) |
| t.abort = c |
| go func() { |
| f(t) |
| c <- nil |
| }() |
| err := <-c |
| t.abort = oc |
| return err |
| } |
| |
| type DivByZeroError struct{} |
| |
| func (DivByZeroError) String() string { return "divide by zero" } |
| |
| type NilPointerError struct{} |
| |
| func (NilPointerError) String() string { return "nil pointer dereference" } |
| |
| type IndexError struct { |
| Idx, Len int64 |
| } |
| |
| func (e IndexError) String() string { |
| if e.Idx < 0 { |
| return fmt.Sprintf("negative index: %d", e.Idx) |
| } |
| return fmt.Sprintf("index %d exceeds length %d", e.Idx, e.Len) |
| } |
| |
| type SliceError struct { |
| Lo, Hi, Cap int64 |
| } |
| |
| func (e SliceError) String() string { |
| return fmt.Sprintf("slice [%d:%d]; cap %d", e.Lo, e.Hi, e.Cap) |
| } |
| |
| type KeyError struct { |
| Key interface{} |
| } |
| |
| func (e KeyError) String() string { return fmt.Sprintf("key '%v' not found in map", e.Key) } |
| |
| type NegativeLengthError struct { |
| Len int64 |
| } |
| |
| func (e NegativeLengthError) String() string { |
| return fmt.Sprintf("negative length: %d", e.Len) |
| } |
| |
| type NegativeCapacityError struct { |
| Len int64 |
| } |
| |
| func (e NegativeCapacityError) String() string { |
| return fmt.Sprintf("negative capacity: %d", e.Len) |
| } |