PageRenderTime 38ms CodeModel.GetById 28ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/forth/error.go

http://github.com/unixdj/forego
Go | 95 lines | 81 code | 11 blank | 3 comment | 6 complexity | 15bf54e2ebb1563d0a8ea36849f67404 MD5 | raw file
 1package forth
 2
 3// List of VM traps for Errno
 4const (
 5	Bye = Errno(iota)
 6	EOF
 7	StackOverflow
 8	StackUnderflow
 9	RStackOverflow
10	RStackUnderflow
11	IllegalInstruction
12	IllegalAddress
13	UnalignedAddress
14	ZeroDivision
15	IOError
16)
17
18var strError = []string{
19	"BYE",
20	"EOF",
21	"stack overflow",
22	"stack underflow",
23	"return stack overflow",
24	"return stack underflow",
25	"illegal instruction",
26	"illegal address",
27	"unaligned address",
28	"zero division",
29	"I/O error",
30}
31
32// Errno describes the reason for a VM trap.
33type Errno int
34
35func (e Errno) Error() string {
36	return strError[e]
37}
38
39func rstackError(e error) error {
40	if e == nil {
41		return nil
42	}
43	return e.(Errno) + (RStackOverflow - StackOverflow)
44}
45
46// Error describes the cause and the context of a VM trap.
47type Error struct {
48	Errno  Errno // nature of the trap
49	Err    error // I/O error when Errno is IOError
50	PC     Cell  // program counter before the trap
51	Instr  Instr // instruction that raised the trap
52	Addr   Cell  // address when Errno is IllegalAddress or UnalignedAddress
53	Stack  Stack // data stack
54	RStack Stack // return stack
55}
56
57func (e *Error) Error() string {
58	var msg = "forego: "
59	if e.Err != nil {
60		msg += e.Err.Error()
61	} else {
62		msg += e.Errno.Error()
63		switch e.Errno {
64		case IllegalInstruction:
65			msg += " " + Cell(e.Instr).String()
66		case IllegalAddress, UnalignedAddress:
67			msg += " " + e.Addr.String()
68		}
69	}
70	return msg + " at " + e.PC.String()
71}
72
73func (vm *VM) newErrorFull(errno Errno, err error, addr Cell) error {
74	return &Error{
75		Errno:  errno,
76		Err:    err,
77		PC:     vm.lastpc,
78		Addr:   addr,
79		Instr:  vm.icell,
80		Stack:  append(make([]Cell, 0, stackDepth), vm.stack...),
81		RStack: append(make([]Cell, 0, stackDepth), vm.rstack...),
82	}
83}
84
85func (vm *VM) newErrorAddr(errno Errno, addr Cell) error {
86	return vm.newErrorFull(errno, nil, addr)
87}
88
89func (vm *VM) newError(errno Errno) error {
90	return vm.newErrorAddr(errno, 0)
91}
92
93func (vm *VM) newIOError(e error) error {
94	return vm.newErrorFull(IOError, e, 0)
95}