-
Notifications
You must be signed in to change notification settings - Fork 29
/
exception.go
335 lines (284 loc) · 9.41 KB
/
exception.go
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
package engine
import (
"bytes"
)
// Exception is an error represented by a prolog term.
type Exception struct {
term Term
}
// NewException creates an Exception from a copy of the given Term.
func NewException(term Term, env *Env) Exception {
c, err := renamedCopy(term, nil, env)
if err != nil {
return err.(Exception) // Must be error(resource_error(memory), _).
}
return Exception{term: c}
}
// Term returns the underlying Term of the Exception.
func (e Exception) Term() Term {
return e.term
}
func (e Exception) Error() string {
var buf bytes.Buffer
_ = e.term.WriteTerm(&buf, &defaultWriteOptions, nil)
return buf.String()
}
// InstantiationError returns an instantiation error exception.
func InstantiationError(env *Env) Exception {
return NewException(atomError.Apply(atomInstantiationError, varContext), env)
}
// validType is the correct type for an argument or one of its components.
type validType uint8
const (
validTypeAtom validType = iota
validTypeAtomic
validTypeByte
validTypeCallable
validTypeCharacter
validTypeCompound
validTypeEvaluable
validTypeInByte
validTypeInCharacter
validTypeInteger
validTypeList
validTypeNumber
validTypePredicateIndicator
validTypePair
validTypeFloat
)
var validTypeAtoms = [...]Atom{
validTypeAtom: atomAtom,
validTypeAtomic: atomAtomic,
validTypeByte: atomByte,
validTypeCallable: atomCallable,
validTypeCharacter: atomCharacter,
validTypeCompound: atomCompound,
validTypeEvaluable: atomEvaluable,
validTypeInByte: atomInByte,
validTypeInCharacter: atomInCharacter,
validTypeInteger: atomInteger,
validTypeList: atomList,
validTypeNumber: atomNumber,
validTypePredicateIndicator: atomPredicateIndicator,
validTypePair: atomPair,
validTypeFloat: atomFloat,
}
// Term returns an Atom for the validType.
func (t validType) Term() Term {
return validTypeAtoms[t]
}
// TypeError creates a new type error exception.
func TypeError(typ, culprit Term, env *Env) Exception {
return NewException(atomError.Apply(atomTypeError.Apply(typ, culprit), varContext), env)
}
// typeError creates a new type error exception.
func typeError(validType validType, culprit Term, env *Env) Exception {
return TypeError(validType.Term(), culprit, env)
}
// validDomain is the domain which the procedure defines.
type validDomain uint8
const (
validDomainCharacterCodeList validDomain = iota
validDomainCloseOption
validDomainFlagValue
validDomainIOMode
validDomainNonEmptyList
validDomainNotLessThanZero
validDomainOperatorPriority
validDomainOperatorSpecifier
validDomainPrologFlag
validDomainReadOption
validDomainSourceSink
validDomainStream
validDomainStreamOption
validDomainStreamOrAlias
validDomainStreamPosition
validDomainStreamProperty
validDomainWriteOption
validDomainOrder
)
var validDomainAtoms = [...]Atom{
validDomainCharacterCodeList: atomCharacterCodeList,
validDomainCloseOption: atomCloseOption,
validDomainFlagValue: atomFlagValue,
validDomainIOMode: atomIOMode,
validDomainNonEmptyList: atomNonEmptyList,
validDomainNotLessThanZero: atomNotLessThanZero,
validDomainOperatorPriority: atomOperatorPriority,
validDomainOperatorSpecifier: atomOperatorSpecifier,
validDomainPrologFlag: atomPrologFlag,
validDomainReadOption: atomReadOption,
validDomainSourceSink: atomSourceSink,
validDomainStream: atomStream,
validDomainStreamOption: atomStreamOption,
validDomainStreamOrAlias: atomStreamOrAlias,
validDomainStreamPosition: atomStreamPosition,
validDomainStreamProperty: atomStreamProperty,
validDomainWriteOption: atomWriteOption,
validDomainOrder: atomOrder,
}
// Term returns an Atom for the validDomain.
func (vd validDomain) Term() Term {
return validDomainAtoms[vd]
}
// DomainError creates a new domain error exception.
func DomainError(domain, culprit Term, env *Env) Exception {
return NewException(atomError.Apply(atomDomainError.Apply(domain, culprit), varContext), env)
}
// domainError creates a new domain error exception.
func domainError(validDomain validDomain, culprit Term, env *Env) Exception {
return DomainError(validDomain.Term(), culprit, env)
}
// objectType is the object on which an operation is to be performed.
type objectType uint8
const (
objectTypeProcedure objectType = iota
objectTypeSourceSink
objectTypeStream
)
var objectTypeAtoms = [...]Atom{
objectTypeProcedure: atomProcedure,
objectTypeSourceSink: atomSourceSink,
objectTypeStream: atomStream,
}
// Term returns an Atom for the objectType.
func (ot objectType) Term() Term {
return objectTypeAtoms[ot]
}
// existenceError creates a new existence error exception.
func existenceError(objectType objectType, culprit Term, env *Env) Exception {
return NewException(atomError.Apply(atomExistenceError.Apply(objectType.Term(), culprit), varContext), env)
}
// operation is the operation to be performed.
type operation uint8
const (
operationAccess operation = iota
operationCreate
operationInput
operationModify
operationOpen
operationOutput
operationReposition
)
var operationAtoms = [...]Atom{
operationAccess: atomAccess,
operationCreate: atomCreate,
operationInput: atomInput,
operationModify: atomModify,
operationOpen: atomOpen,
operationOutput: atomOutput,
operationReposition: atomReposition,
}
// Term returns an Atom for the operation.
func (o operation) Term() Term {
return operationAtoms[o]
}
// permissionType is the type to which the operation is not permitted to perform.
type permissionType uint8
const (
permissionTypeBinaryStream permissionType = iota
permissionTypeFlag
permissionTypeOperator
permissionTypePastEndOfStream
permissionTypePrivateProcedure
permissionTypeStaticProcedure
permissionTypeSourceSink
permissionTypeStream
permissionTypeTextStream
)
var permissionTypeAtoms = [...]Atom{
permissionTypeBinaryStream: atomBinaryStream,
permissionTypeFlag: atomFlag,
permissionTypeOperator: atomOperator,
permissionTypePastEndOfStream: atomPastEndOfStream,
permissionTypePrivateProcedure: atomPrivateProcedure,
permissionTypeStaticProcedure: atomStaticProcedure,
permissionTypeSourceSink: atomSourceSink,
permissionTypeStream: atomStream,
permissionTypeTextStream: atomTextStream,
}
// Term returns an Atom for the permissionType.
func (pt permissionType) Term() Term {
return permissionTypeAtoms[pt]
}
// permissionError creates a new permission error exception.
func permissionError(operation operation, permissionType permissionType, culprit Term, env *Env) Exception {
return NewException(atomError.Apply(atomPermissionError.Apply(operation.Term(), permissionType.Term(), culprit), varContext), env)
}
// flag is an implementation defined limit.
type flag uint8
const (
flagCharacter flag = iota
flagCharacterCode
flagInCharacterCode
flagMaxArity
flagMaxInteger
flagMinInteger
)
var flagAtoms = [...]Atom{
flagCharacter: atomCharacter,
flagCharacterCode: atomCharacterCode,
flagInCharacterCode: atomInCharacterCode,
flagMaxArity: atomMaxArity,
flagMaxInteger: atomMaxInteger,
flagMinInteger: atomMinInteger,
}
// Term returns an Atom for the flag.
func (f flag) Term() Term {
return flagAtoms[f]
}
// representationError creates a new representation error exception.
func representationError(limit flag, env *Env) Exception {
return NewException(atomError.Apply(atomRepresentationError.Apply(limit.Term()), varContext), env)
}
// resource is a resource required to complete execution.
type resource uint8
// resource is one of these values.
const (
resourceFiniteMemory resource = iota
resourceMemory
)
var resourceAtoms = [...]Atom{
resourceFiniteMemory: atomFiniteMemory,
resourceMemory: atomMemory,
}
// Term returns an Atom for the resource.
func (r resource) Term() Term {
return resourceAtoms[r]
}
// resourceError creates a new resource error exception.
func resourceError(resource resource, env *Env) Exception {
// We can't call renamedCopy() since it can lead th resource_error(memory).
return Exception{term: atomError.Apply(atomResourceError.Apply(resource.Term()), env.Resolve(varContext))}
}
// syntaxError creates a new syntax error exception.
func syntaxError(err error, env *Env) Exception {
return NewException(atomError.Apply(atomSyntaxError.Apply(NewAtom(err.Error())), varContext), env)
}
// exceptionalValue is an evaluable functor's result which is not a number.
type exceptionalValue uint8
const (
exceptionalValueFloatOverflow exceptionalValue = iota
exceptionalValueIntOverflow
exceptionalValueUnderflow
exceptionalValueZeroDivisor
exceptionalValueUndefined
)
func (ev exceptionalValue) Error() string {
return ev.Term().(Atom).String()
}
var exceptionalValueAtoms = [...]Atom{
exceptionalValueFloatOverflow: atomFloatOverflow,
exceptionalValueIntOverflow: atomIntOverflow,
exceptionalValueUnderflow: atomUnderflow,
exceptionalValueZeroDivisor: atomZeroDivisor,
exceptionalValueUndefined: atomUndefined,
}
// Term returns an Atom for the exceptionalValue.
func (ev exceptionalValue) Term() Term {
return exceptionalValueAtoms[ev]
}
// evaluationError creates a new evaluation error exception.
func evaluationError(ev exceptionalValue, env *Env) Exception {
return NewException(atomError.Apply(atomEvaluationError.Apply(ev.Term()), varContext), env)
}