summaryrefslogtreecommitdiff
path: root/libgo/go/exp/eval/abort.go
blob: 22e17cec405444285aa692779060623f73dd6fff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// 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)
}