about summary refs log tree commit diff
path: root/pkg/lang/vm/errors.go
blob: 0c1b916ba005e03c30ec8431d73c7bcd6a305652 (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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package vm

import (
	"fmt"
	"jinx/pkg/lang/vm/code"
	"jinx/pkg/lang/vm/mem"
	"jinx/pkg/lang/vm/text"
	"jinx/pkg/lang/vm/value"
)

type Error struct {
	Pos    code.Pos
	Module string
	Line   int
	Err    error
}

func (e Error) Error() string {
	if e.Line == -1 {
		return fmt.Sprintf("vm error in module '%s' at pc %d, unknown line: %v", e.Module, e.Pos.PC, e.Err)
	}
	return fmt.Sprintf("vm error in module '%s' at pc %d, line %d: %v", e.Module, e.Pos.PC, e.Line, e.Err)
}

// Fatal errors

type ErrNullPtrDereference struct {
	At mem.Ptr
}

func (e ErrNullPtrDereference) Error() string {
	return fmt.Sprintf("null pointer dereference at %v", e.At)
}

type ErrInvalidOp struct {
	Op uint8
}

func (e ErrInvalidOp) Error() string {
	return fmt.Sprintf("invalid opcode: %d", e.Op)
}

type ErrUnexpectedMemCell struct {
	Ptr      mem.Ptr
	Expected mem.CellKind
	Got      mem.CellKind
}

func (e ErrUnexpectedMemCell) Error() string {
	return fmt.Sprintf("unexpected memory cell at %s: expected %v, got %v", e.Ptr.String(), e.Expected, e.Got)
}

type ErrMemNilCell struct {
	Ptr mem.Ptr
}

func (e ErrMemNilCell) Error() string {
	return fmt.Sprintf("found no value at %s", e.Ptr.String())
}

type ErrCorruptedMemCell struct {
	Ptr mem.Ptr
}

func (e ErrCorruptedMemCell) Error() string {
	return fmt.Sprintf("corrupted memory cell at %s", e.Ptr.String())
}

type ErrCantReanchorType struct {
	Type value.TypeKind
}

func (e ErrCantReanchorType) Error() string {
	return fmt.Sprintf("can't reanchor type of value which already is of type %v", e.Type)
}

// Non-fatal errors, which will later be implemented as catchable exceptions

type ErrInvalidOperandType struct {
	Op code.Op
	X  value.TypeKind
}

func (e ErrInvalidOperandType) Error() string {
	return fmt.Sprintf("invalid operand type for op %s: %v", text.OpToString(e.Op), e.X)
}

type ErrInvalidOperandTypes struct {
	Op code.Op
	X  value.TypeKind
	Y  value.TypeKind
}

func (e ErrInvalidOperandTypes) Error() string {
	return fmt.Sprintf("invalid operand types for op %s: %v, %v", text.OpToString(e.Op), e.X, e.Y)
}

type ErrArrayIndexOutOfBounds struct {
	Index int
	Len   int
}

func (e ErrArrayIndexOutOfBounds) Error() string {
	return fmt.Sprintf("array index out of bounds: %d (len: %d)", e.Index, e.Len)
}

type ErrWrongNumberOfArguments struct {
	Needed uint
	Got    uint
}

func (e ErrWrongNumberOfArguments) Error() string {
	return fmt.Sprintf("wrong number of arguments: needed %d, got %d", e.Needed, e.Got)
}

type ErrCantAddGlobalFromMain struct {
	GlobalName string
}

func (e ErrCantAddGlobalFromMain) Error() string {
	return fmt.Sprintf("can't export '%s' from main module", e.GlobalName)
}

type ErrGlobalAlreadyExists struct {
	GlobalName string
}

func (e ErrGlobalAlreadyExists) Error() string {
	return fmt.Sprintf("global '%s' already exists", e.GlobalName)
}

type ErrNoSuchGlobal struct {
	GlobalName string
}

func (e ErrNoSuchGlobal) Error() string {
	return fmt.Sprintf("no such global '%s'", e.GlobalName)
}