2009-08-28 11:39:57 -06:00
|
|
|
// 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";
|
|
|
|
)
|
|
|
|
|
2009-09-02 15:11:40 -06:00
|
|
|
// 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 {
|
|
|
|
panicln("abort:", err.String());
|
2009-08-28 11:39:57 -06:00
|
|
|
}
|
2009-09-02 15:11:40 -06:00
|
|
|
t.abort <- err;
|
2009-08-28 11:39:57 -06:00
|
|
|
runtime.Goexit();
|
|
|
|
}
|
|
|
|
|
2009-09-02 15:11:40 -06:00
|
|
|
// 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;
|
2009-08-28 11:39:57 -06:00
|
|
|
go func() {
|
2009-09-02 15:11:40 -06:00
|
|
|
f(t);
|
|
|
|
c <- nil;
|
2009-08-28 11:39:57 -06:00
|
|
|
}();
|
2009-09-02 15:11:40 -06:00
|
|
|
err := <-c;
|
|
|
|
t.abort = oc;
|
|
|
|
return err;
|
2009-08-28 11:39:57 -06:00
|
|
|
}
|
|
|
|
|
2009-09-02 13:03:20 -06:00
|
|
|
type DivByZeroError struct {}
|
2009-08-28 11:39:57 -06:00
|
|
|
|
2009-09-02 13:03:20 -06:00
|
|
|
func (DivByZeroError) String() string {
|
2009-08-28 11:39:57 -06:00
|
|
|
return "divide by zero";
|
|
|
|
}
|
|
|
|
|
2009-09-02 13:03:20 -06:00
|
|
|
type NilPointerError struct {}
|
2009-08-28 11:39:57 -06:00
|
|
|
|
2009-09-02 13:03:20 -06:00
|
|
|
func (NilPointerError) String() string {
|
2009-08-28 11:39:57 -06:00
|
|
|
return "nil pointer dereference";
|
|
|
|
}
|
|
|
|
|
2009-09-02 13:03:20 -06:00
|
|
|
type IndexError struct {
|
2009-08-28 11:39:57 -06:00
|
|
|
Idx, Len int64;
|
|
|
|
}
|
|
|
|
|
2009-09-02 13:03:20 -06:00
|
|
|
func (e IndexError) String() string {
|
2009-08-28 11:39:57 -06:00
|
|
|
if e.Idx < 0 {
|
|
|
|
return fmt.Sprintf("negative index: %d", e.Idx);
|
|
|
|
}
|
|
|
|
return fmt.Sprintf("index %d exceeds length %d", e.Idx, e.Len);
|
|
|
|
}
|
|
|
|
|
2009-09-02 13:03:20 -06:00
|
|
|
type KeyError struct {
|
2009-08-28 11:39:57 -06:00
|
|
|
Key interface {};
|
|
|
|
}
|
|
|
|
|
2009-09-02 13:03:20 -06:00
|
|
|
func (e KeyError) String() string {
|
2009-08-28 19:03:03 -06:00
|
|
|
return fmt.Sprintf("key '%v' not found in map", e.Key);
|
|
|
|
}
|
|
|
|
|
2009-09-02 13:03:20 -06:00
|
|
|
type NegativeLengthError struct {
|
2009-08-28 19:03:03 -06:00
|
|
|
Len int64;
|
|
|
|
}
|
|
|
|
|
2009-09-02 13:03:20 -06:00
|
|
|
func (e NegativeLengthError) String() string {
|
2009-08-28 19:03:03 -06:00
|
|
|
return fmt.Sprintf("negative length: %d", e.Len);
|
|
|
|
}
|
|
|
|
|
2009-09-02 13:03:20 -06:00
|
|
|
type NegativeCapacityError struct {
|
2009-08-28 19:03:03 -06:00
|
|
|
Len int64;
|
|
|
|
}
|
|
|
|
|
2009-09-02 13:03:20 -06:00
|
|
|
func (e NegativeCapacityError) String() string {
|
2009-08-28 19:03:03 -06:00
|
|
|
return fmt.Sprintf("negative capacity: %d", e.Len);
|
2009-08-28 11:39:57 -06:00
|
|
|
}
|