diff --git a/engine/builtin.go b/engine/builtin.go index 8bc18791..7b44417c 100644 --- a/engine/builtin.go +++ b/engine/builtin.go @@ -124,7 +124,7 @@ func (state *State) Negation(goal Term, k func(*Env) *Promise, env *Env) *Promis func (state *State) Call(goal Term, k func(*Env) *Promise, env *Env) *Promise { switch g := env.Resolve(goal).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) default: fvs := env.FreeVariables(g) args := make([]Term, len(fvs)) @@ -222,20 +222,21 @@ func (state *State) CallNth(goal, nth Term, k func(*Env) *Promise, env *Env) *Pr case Integer: switch { case nth < 0: - return Error(DomainError("not_less_than_zero", nth, env)) + return Error(DomainError(ValidDomainNotLessThanZero, nth, env)) case nth == 0: return Bool(false) } default: - return Error(TypeErrorInteger(nth, env)) + return Error(TypeError(ValidTypeInteger, nth, env)) } n := callNthInit + parentEnv := env var p *Promise p = state.Call(goal, func(env *Env) *Promise { if n == Integer(math.MaxInt64) { - return Error(representationError("max_integer")) + return Error(RepresentationError(FlagMaxInteger, parentEnv)) } n++ @@ -358,20 +359,20 @@ func Functor(t, name, arity Term, k func(*Env) *Promise, env *Env) *Promise { case Variable: switch arity := env.Resolve(arity).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case Integer: switch { case arity < 0: - return Error(domainErrorNotLessThanZero(arity, env)) + return Error(DomainError(ValidDomainNotLessThanZero, arity, env)) case arity == 0: return Unify(t, name, k, env) } switch name := env.Resolve(name).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case *Compound: - return Error(TypeErrorAtomic(name, env)) + return Error(TypeError(ValidTypeAtomic, name, env)) case Atom: vs := make([]Term, arity) for i := range vs { @@ -382,10 +383,10 @@ func Functor(t, name, arity Term, k func(*Env) *Promise, env *Env) *Promise { Args: vs, }, k, env) default: - return Error(TypeErrorAtom(name, env)) + return Error(TypeError(ValidTypeAtom, name, env)) } default: - return Error(TypeErrorInteger(arity, env)) + return Error(TypeError(ValidTypeInteger, arity, env)) } case *Compound: pattern := Compound{Args: []Term{name, arity}} @@ -400,26 +401,26 @@ func Functor(t, name, arity Term, k func(*Env) *Promise, env *Env) *Promise { func Arg(nth, t, arg Term, k func(*Env) *Promise, env *Env) *Promise { switch c := env.Resolve(t).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case *Compound: switch n := env.Resolve(nth).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case Integer: if n == 0 || int(n) > len(c.Args) { return Bool(false) } if n < 0 { - return Error(domainErrorNotLessThanZero(n, env)) + return Error(DomainError(ValidDomainNotLessThanZero, n, env)) } return Delay(func(context.Context) *Promise { return Unify(arg, c.Args[int(n)-1], k, env) }) default: - return Error(TypeErrorInteger(n, env)) + return Error(TypeError(ValidTypeInteger, n, env)) } default: - return Error(TypeErrorCompound(t, env)) + return Error(TypeError(ValidTypeCompound, t, env)) } } @@ -429,16 +430,16 @@ func Univ(t, list Term, k func(*Env) *Promise, env *Env) *Promise { case Variable: list = env.Resolve(list) if list == Atom("[]") { - return Error(domainErrorNotEmptyList(list, env)) + return Error(DomainError(ValidDomainNonEmptyList, list, env)) } cons, ok := list.(*Compound) if !ok || cons.Functor != "." || len(cons.Args) != 2 { - return Error(TypeErrorList(list, env)) + return Error(TypeError(ValidTypeList, list, env)) } f, ok := env.Resolve(cons.Args[0]).(Atom) if !ok { - return Error(TypeErrorAtom(cons.Args[0], env)) + return Error(TypeError(ValidTypeAtom, cons.Args[0], env)) } var args []Term @@ -527,15 +528,15 @@ func TermVariables(term, vars Term, k func(*Env) *Promise, env *Env) *Promise { func (state *State) Op(priority, specifier, op Term, k func(*Env) *Promise, env *Env) *Promise { p, ok := env.Resolve(priority).(Integer) if !ok { - return Error(TypeErrorInteger(priority, env)) + return Error(TypeError(ValidTypeInteger, priority, env)) } if p < 0 || p > 1200 { - return Error(domainErrorOperatorPriority(priority, env)) + return Error(DomainError(ValidDomainOperatorPriority, priority, env)) } s, ok := env.Resolve(specifier).(Atom) if !ok { - return Error(TypeErrorAtom(specifier, env)) + return Error(TypeError(ValidTypeAtom, specifier, env)) } spec, ok := map[Atom]operatorSpecifier{ @@ -548,12 +549,12 @@ func (state *State) Op(priority, specifier, op Term, k func(*Env) *Promise, env "yfx": operatorSpecifierYFX, }[s] if !ok { - return Error(domainErrorOperatorSpecifier(s, env)) + return Error(DomainError(ValidDomainOperatorSpecifier, s, env)) } o, ok := env.Resolve(op).(Atom) if !ok { - return Error(TypeErrorAtom(op, env)) + return Error(TypeError(ValidTypeAtom, op, env)) } // already defined? @@ -595,10 +596,10 @@ func (state *State) CurrentOp(priority, specifier, operator Term, k func(*Env) * break case Integer: if p < 0 || p > 1200 { - return Error(domainErrorOperatorPriority(priority, env)) + return Error(DomainError(ValidDomainOperatorPriority, priority, env)) } default: - return Error(domainErrorOperatorPriority(priority, env)) + return Error(DomainError(ValidDomainOperatorPriority, priority, env)) } switch s := env.Resolve(specifier).(type) { @@ -614,17 +615,17 @@ func (state *State) CurrentOp(priority, specifier, operator Term, k func(*Env) * "fx": {}, "fy": {}, }[s]; !ok { - return Error(domainErrorOperatorSpecifier(s, env)) + return Error(DomainError(ValidDomainOperatorSpecifier, s, env)) } default: - return Error(domainErrorOperatorSpecifier(s, env)) + return Error(DomainError(ValidDomainOperatorSpecifier, s, env)) } switch env.Resolve(operator).(type) { case Variable, Atom: break default: - return Error(TypeErrorAtom(operator, env)) + return Error(TypeError(ValidTypeAtom, operator, env)) } pattern := Compound{Args: []Term{priority, specifier, operator}} @@ -701,18 +702,18 @@ func (state *State) assert(t Term, force bool, merge func(clauses, clauses) clau return nil case builtin: if !force { - return permissionErrorModifyStaticProcedure(pi.Term(), env) + return PermissionError(OperationModify, PermissionTypeStaticProcedure, pi.Term(), env) } state.procedures[pi] = builtin{merge(existing.clauses, added)} return nil case static: if !force { - return permissionErrorModifyStaticProcedure(pi.Term(), env) + return PermissionError(OperationModify, PermissionTypeStaticProcedure, pi.Term(), env) } state.procedures[pi] = static{merge(existing.clauses, added)} return nil default: - return permissionErrorModifyStaticProcedure(pi.Term(), env) + return PermissionError(OperationModify, PermissionTypeStaticProcedure, pi.Term(), env) } } @@ -730,7 +731,7 @@ func (state *State) collectionOf(agg func(...Term) Term, template, goal, instanc var qualifier, body Term switch goal := env.Resolve(goal).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case *Compound: if goal.Functor != "^" || len(goal.Args) != 2 { qualifier = Atom("") @@ -831,10 +832,10 @@ func Compare(order, term1, term2 Term, k func(*Env) *Promise, env *Env) *Promise case "<", "=", ">": break default: - return Error(domainErrorOrder(order, env)) + return Error(DomainError(ValidDomainOrder, order, env)) } default: - return Error(TypeErrorAtom(order, env)) + return Error(TypeError(ValidTypeAtom, order, env)) } d := term1.Compare(term2, env) @@ -857,18 +858,18 @@ func Between(lower, upper, value Term, k func(*Env) *Promise, env *Env) *Promise case Integer: low = lower case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) default: - return Error(TypeErrorInteger(lower, env)) + return Error(TypeError(ValidTypeInteger, lower, env)) } switch upper := env.Resolve(upper).(type) { case Integer: high = upper case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) default: - return Error(TypeErrorInteger(upper, env)) + return Error(TypeError(ValidTypeInteger, upper, env)) } if low > high { @@ -893,7 +894,7 @@ func Between(lower, upper, value Term, k func(*Env) *Promise, env *Env) *Promise } return Delay(ks...) default: - return Error(TypeErrorInteger(value, env)) + return Error(TypeError(ValidTypeInteger, value, env)) } } @@ -915,9 +916,9 @@ func Sort(list, sorted Term, k func(*Env) *Promise, env *Env) *Promise { if s.Functor == "." && len(s.Args) == 2 { break } - return Error(TypeErrorList(sorted, env)) + return Error(TypeError(ValidTypeList, sorted, env)) default: - return Error(TypeErrorList(sorted, env)) + return Error(TypeError(ValidTypeList, sorted, env)) } return Unify(sorted, env.Set(elems...), k, env) @@ -930,14 +931,14 @@ func KeySort(pairs, sorted Term, k func(*Env) *Promise, env *Env) *Promise { for iter.Next() { switch e := env.Resolve(iter.Current()).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case *Compound: if e.Functor != "-" || len(e.Args) != 2 { - return Error(TypeErrorPair(e, env)) + return Error(TypeError(ValidTypePair, e, env)) } elems = append(elems, e) default: - return Error(TypeErrorPair(e, env)) + return Error(TypeError(ValidTypePair, e, env)) } } if err := iter.Err(); err != nil { @@ -955,10 +956,10 @@ func KeySort(pairs, sorted Term, k func(*Env) *Promise, env *Env) *Promise { continue case *Compound: if e.Functor != "-" || len(e.Args) != 2 { - return Error(TypeErrorPair(e, env)) + return Error(TypeError(ValidTypePair, e, env)) } default: - return Error(TypeErrorPair(e, env)) + return Error(TypeError(ValidTypePair, e, env)) } } if err := iter.Err(); err != nil { @@ -977,7 +978,7 @@ func KeySort(pairs, sorted Term, k func(*Env) *Promise, env *Env) *Promise { func Throw(ball Term, _ func(*Env) *Promise, env *Env) *Promise { switch b := env.Resolve(ball).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) default: return Error(NewException(b, env)) } @@ -986,7 +987,7 @@ func Throw(ball Term, _ func(*Env) *Promise, env *Env) *Promise { // Catch calls goal. If an exception is thrown and unifies with catcher, it calls recover. func (state *State) Catch(goal, catcher, recover Term, k func(*Env) *Promise, env *Env) *Promise { return Catch(func(err error) *Promise { - var e *Exception + var e Exception if !errors.As(err, &e) { return nil } @@ -1009,16 +1010,16 @@ func (state *State) CurrentPredicate(pi Term, k func(*Env) *Promise, env *Env) * break case *Compound: if pi.Functor != "/" || len(pi.Args) != 2 { - return Error(TypeErrorPredicateIndicator(pi, env)) + return Error(TypeError(ValidTypePredicateIndicator, pi, env)) } if _, ok := env.Resolve(pi.Args[0]).(Atom); !ok { - return Error(TypeErrorPredicateIndicator(pi, env)) + return Error(TypeError(ValidTypePredicateIndicator, pi, env)) } if _, ok := env.Resolve(pi.Args[1]).(Integer); !ok { - return Error(TypeErrorPredicateIndicator(pi, env)) + return Error(TypeError(ValidTypePredicateIndicator, pi, env)) } default: - return Error(TypeErrorPredicateIndicator(pi, env)) + return Error(TypeError(ValidTypePredicateIndicator, pi, env)) } ks := make([]func(context.Context) *Promise, 0, len(state.procedures)) @@ -1053,7 +1054,7 @@ func (state *State) Retract(t Term, k func(*Env) *Promise, env *Env) *Promise { cs, ok := p.(clauses) if !ok { - return Error(permissionErrorModifyStaticProcedure(pi.Term(), env)) + return Error(PermissionError(OperationModify, PermissionTypeStaticProcedure, pi.Term(), env)) } deleted := 0 @@ -1078,42 +1079,39 @@ func (state *State) Retract(t Term, k func(*Env) *Promise, env *Env) *Promise { func (state *State) Abolish(pi Term, k func(*Env) *Promise, env *Env) *Promise { switch pi := env.Resolve(pi).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case *Compound: if pi.Functor != "/" || len(pi.Args) != 2 { - return Error(TypeErrorPredicateIndicator(pi, env)) + return Error(TypeError(ValidTypePredicateIndicator, pi, env)) } name, arity := pi.Args[0], pi.Args[1] switch name := env.Resolve(name).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case Atom: switch arity := env.Resolve(arity).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case Integer: if arity < 0 { - return Error(domainErrorNotLessThanZero(arity, env)) + return Error(DomainError(ValidDomainNotLessThanZero, arity, env)) } key := ProcedureIndicator{Name: name, Arity: arity} if _, ok := state.procedures[key].(clauses); !ok { - return Error(permissionErrorModifyStaticProcedure(&Compound{ - Functor: "/", - Args: []Term{name, arity}, - }, env)) + return Error(PermissionError(OperationModify, PermissionTypeStaticProcedure, key.Term(), env)) } delete(state.procedures, key) return k(env) default: - return Error(TypeErrorInteger(arity, env)) + return Error(TypeError(ValidTypeInteger, arity, env)) } default: - return Error(TypeErrorAtom(name, env)) + return Error(TypeError(ValidTypeAtom, name, env)) } default: - return Error(TypeErrorPredicateIndicator(pi, env)) + return Error(TypeError(ValidTypePredicateIndicator, pi, env)) } } @@ -1123,7 +1121,7 @@ func (state *State) CurrentInput(stream Term, k func(*Env) *Promise, env *Env) * case Variable, *Stream: break default: - return Error(domainErrorStream(stream, env)) + return Error(DomainError(ValidDomainStream, stream, env)) } return Delay(func(context.Context) *Promise { @@ -1137,7 +1135,7 @@ func (state *State) CurrentOutput(stream Term, k func(*Env) *Promise, env *Env) case Variable, *Stream: break default: - return Error(domainErrorStream(stream, env)) + return Error(DomainError(ValidDomainStream, stream, env)) } return Delay(func(context.Context) *Promise { @@ -1153,7 +1151,7 @@ func (state *State) SetInput(streamOrAlias Term, k func(*Env) *Promise, env *Env } if s.mode != StreamModeRead { - return Error(permissionErrorInputStream(streamOrAlias, env)) + return Error(PermissionError(OperationInput, PermissionTypeStream, streamOrAlias, env)) } state.input = s @@ -1168,7 +1166,7 @@ func (state *State) SetOutput(streamOrAlias Term, k func(*Env) *Promise, env *En } if s.mode != StreamModeWrite && s.mode != StreamModeAppend { - return Error(permissionErrorOutputStream(streamOrAlias, env)) + return Error(PermissionError(OperationOutput, PermissionTypeStream, streamOrAlias, env)) } state.output = s @@ -1180,17 +1178,17 @@ func (state *State) Open(SourceSink, mode, stream, options Term, k func(*Env) *P var n Atom switch s := env.Resolve(SourceSink).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case Atom: n = s default: - return Error(domainErrorSourceSink(SourceSink, env)) + return Error(DomainError(ValidDomainSourceSink, SourceSink, env)) } var streamMode StreamMode switch m := env.Resolve(mode).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case Atom: var ok bool streamMode, ok = map[Atom]StreamMode{ @@ -1199,14 +1197,14 @@ func (state *State) Open(SourceSink, mode, stream, options Term, k func(*Env) *P "append": StreamModeAppend, }[m] if !ok { - return Error(domainErrorIOMode(m, env)) + return Error(DomainError(ValidDomainIOMode, m, env)) } default: - return Error(TypeErrorAtom(mode, env)) + return Error(TypeError(ValidTypeAtom, mode, env)) } if _, ok := env.Resolve(stream).(Variable); !ok { - return Error(ErrInstantiation) + return Error(InstantiationError(env)) } var opts []StreamOption @@ -1242,30 +1240,30 @@ func streamOption(state *State, option Term, env *Env) (StreamOption, error) { var oi optionIndicator switch o := env.Resolve(option).(type) { case Variable: - return nil, ErrInstantiation + return nil, InstantiationError(env) case *Compound: if len(o.Args) != 1 { - return nil, domainErrorStreamOption(option, env) + return nil, DomainError(ValidDomainStreamOption, option, env) } switch a := env.Resolve(o.Args[0]).(type) { case Variable: - return nil, ErrInstantiation + return nil, InstantiationError(env) case Atom: oi = optionIndicator{ functor: o.Functor, arg: a, } default: - return nil, TypeErrorAtom(a, env) + return nil, TypeError(ValidTypeAtom, a, env) } default: - return nil, domainErrorStreamOption(option, env) + return nil, DomainError(ValidDomainStreamOption, option, env) } // alias is a bit different. if oi.functor == "alias" { if _, ok := state.streams[oi.arg]; ok { - return nil, PermissionError("open", "source_sink", option, env) + return nil, PermissionError(OperationOpen, PermissionTypeSourceSink, option, env) } return WithAlias(state, oi.arg), nil @@ -1287,7 +1285,7 @@ func streamOption(state *State, option Term, env *Env) (StreamOption, error) { case optionIndicator{functor: "eof_action", arg: "reset"}: return WithEOFAction(EOFActionReset), nil default: - return nil, domainErrorStreamOption(option, env) + return nil, DomainError(ValidDomainStreamOption, option, env) } } @@ -1303,12 +1301,12 @@ func (state *State) Close(streamOrAlias, options Term, k func(*Env) *Promise, en for iter.Next() { switch option := env.Resolve(iter.Current()).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case *Compound: switch option.Functor { case "force": if len(option.Args) != 1 { - return Error(domainErrorStreamOption(option, env)) + return Error(DomainError(ValidDomainStreamOption, option, env)) } switch v := env.Resolve(option.Args[0]).(type) { @@ -1319,14 +1317,14 @@ func (state *State) Close(streamOrAlias, options Term, k func(*Env) *Promise, en case "true": force = true default: - return Error(domainErrorStreamOption(option, env)) + return Error(DomainError(ValidDomainStreamOption, option, env)) } default: - return Error(domainErrorStreamOption(option, env)) + return Error(DomainError(ValidDomainStreamOption, option, env)) } } default: - return Error(domainErrorStreamOption(option, env)) + return Error(DomainError(ValidDomainStreamOption, option, env)) } } if err := iter.Err(); err != nil { @@ -1334,7 +1332,7 @@ func (state *State) Close(streamOrAlias, options Term, k func(*Env) *Promise, en } if err := s.Close(); err != nil && !force { - return Error(resourceError(streamOrAlias, Atom(err.Error()), env)) + return Error(SystemError(err)) } if s.alias == "" { @@ -1356,7 +1354,7 @@ func (state *State) FlushOutput(streamOrAlias Term, k func(*Env) *Promise, env * } if s.mode != StreamModeWrite && s.mode != StreamModeAppend { - return Error(permissionErrorOutputStream(streamOrAlias, env)) + return Error(PermissionError(OperationOutput, PermissionTypeStream, streamOrAlias, env)) } if f, ok := s.file.(*os.File); ok { @@ -1376,11 +1374,11 @@ func (state *State) WriteTerm(streamOrAlias, t, options Term, k func(*Env) *Prom } if s.mode != StreamModeWrite && s.mode != StreamModeAppend { - return Error(permissionErrorOutputStream(streamOrAlias, env)) + return Error(PermissionError(OperationOutput, PermissionTypeStream, streamOrAlias, env)) } if s.streamType == StreamTypeBinary { - return Error(permissionErrorOutputBinaryStream(streamOrAlias, env)) + return Error(PermissionError(OperationOutput, PermissionTypeBinaryStream, streamOrAlias, env)) } var opts []WriteOption @@ -1412,16 +1410,16 @@ func (state *State) Write(w io.Writer, t Term, env *Env, opts ...WriteOption) er func writeTermOption(state *State, option Term, env *Env) (WriteOption, error) { switch o := env.Resolve(option).(type) { case Variable: - return nil, ErrInstantiation + return nil, InstantiationError(env) case *Compound: if len(o.Args) != 1 { - return nil, domainErrorWriteOption(o, env) + return nil, DomainError(ValidDomainWriteOption, o, env) } if o.Functor == "variable_names" { vns := variableNames(o.Args[0], env) if vns == nil { - return nil, domainErrorWriteOption(o, env) + return nil, DomainError(ValidDomainWriteOption, o, env) } return WithVariableNames(vns), nil } @@ -1429,7 +1427,7 @@ func writeTermOption(state *State, option Term, env *Env) (WriteOption, error) { var b bool switch v := env.Resolve(o.Args[0]).(type) { case Variable: - return nil, ErrInstantiation + return nil, InstantiationError(env) case Atom: switch v { case "true": @@ -1437,10 +1435,10 @@ func writeTermOption(state *State, option Term, env *Env) (WriteOption, error) { case "false": b = false default: - return nil, domainErrorWriteOption(o, env) + return nil, DomainError(ValidDomainWriteOption, o, env) } default: - return nil, domainErrorWriteOption(o, env) + return nil, DomainError(ValidDomainWriteOption, o, env) } switch o.Functor { @@ -1451,10 +1449,10 @@ func writeTermOption(state *State, option Term, env *Env) (WriteOption, error) { case "numbervars": return WithNumberVars(b), nil default: - return nil, domainErrorWriteOption(o, env) + return nil, DomainError(ValidDomainWriteOption, o, env) } default: - return nil, domainErrorWriteOption(o, env) + return nil, DomainError(ValidDomainWriteOption, o, env) } } @@ -1491,38 +1489,38 @@ func CharCode(char, code Term, k func(*Env) *Promise, env *Env) *Promise { case Variable: switch cd := env.Resolve(code).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case Integer: r := rune(cd) if !utf8.ValidRune(r) { - return Error(representationError("character_code")) + return Error(RepresentationError(FlagCharacterCode, env)) } return Delay(func(context.Context) *Promise { return Unify(ch, Atom(r), k, env) }) default: - return Error(TypeErrorInteger(code, env)) + return Error(TypeError(ValidTypeInteger, code, env)) } case Atom: switch code := env.Resolve(code).(type) { case Variable, Integer: break default: - return Error(TypeErrorInteger(code, env)) + return Error(TypeError(ValidTypeInteger, code, env)) } rs := []rune(ch) if len(rs) != 1 { - return Error(TypeErrorCharacter(ch, env)) + return Error(TypeError(ValidTypeCharacter, ch, env)) } return Delay(func(context.Context) *Promise { return Unify(code, Integer(rs[0]), k, env) }) default: - return Error(TypeErrorCharacter(ch, env)) + return Error(TypeError(ValidTypeCharacter, ch, env)) } } @@ -1536,19 +1534,19 @@ func (state *State) PutByte(streamOrAlias, byt Term, k func(*Env) *Promise, env } if s.mode != StreamModeWrite && s.mode != StreamModeAppend { - return Error(permissionErrorOutputStream(streamOrAlias, env)) + return Error(PermissionError(OperationOutput, PermissionTypeStream, streamOrAlias, env)) } if s.streamType == StreamTypeText { - return Error(permissionErrorOutputTextStream(streamOrAlias, env)) + return Error(PermissionError(OperationOutput, PermissionTypeTextStream, streamOrAlias, env)) } switch b := env.Resolve(byt).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case Integer: if 0 > b || 255 < b { - return Error(TypeErrorByte(byt, env)) + return Error(TypeError(ValidTypeByte, byt, env)) } if _, err := write(s.file, []byte{byte(b)}); err != nil { @@ -1557,7 +1555,7 @@ func (state *State) PutByte(streamOrAlias, byt Term, k func(*Env) *Promise, env return k(env) default: - return Error(TypeErrorByte(byt, env)) + return Error(TypeError(ValidTypeByte, byt, env)) } } @@ -1569,21 +1567,21 @@ func (state *State) PutCode(streamOrAlias, code Term, k func(*Env) *Promise, env } if s.mode != StreamModeWrite && s.mode != StreamModeAppend { - return Error(permissionErrorOutputStream(streamOrAlias, env)) + return Error(PermissionError(OperationOutput, PermissionTypeStream, streamOrAlias, env)) } if s.streamType == StreamTypeBinary { - return Error(permissionErrorOutputBinaryStream(streamOrAlias, env)) + return Error(PermissionError(OperationOutput, PermissionTypeBinaryStream, streamOrAlias, env)) } switch c := env.Resolve(code).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case Integer: r := rune(c) if !utf8.ValidRune(r) { - return Error(representationError("character_code")) + return Error(RepresentationError(FlagCharacterCode, env)) } if _, err := write(s.file, []byte(string(r))); err != nil { @@ -1592,7 +1590,7 @@ func (state *State) PutCode(streamOrAlias, code Term, k func(*Env) *Promise, env return k(env) default: - return Error(TypeErrorInteger(code, env)) + return Error(TypeError(ValidTypeInteger, code, env)) } } @@ -1610,11 +1608,11 @@ func (state *State) ReadTerm(streamOrAlias, out, options Term, k func(*Env) *Pro } if s.mode != StreamModeRead { - return Error(permissionErrorInputStream(streamOrAlias, env)) + return Error(PermissionError(OperationInput, PermissionTypeStream, streamOrAlias, env)) } if s.streamType == StreamTypeBinary { - return Error(permissionErrorInputBinaryStream(streamOrAlias, env)) + return Error(PermissionError(OperationInput, PermissionTypeBinaryStream, streamOrAlias, env)) } opts := readTermOptions{ @@ -1641,7 +1639,7 @@ func (state *State) ReadTerm(streamOrAlias, out, options Term, k func(*Env) *Pro switch { case errors.Is(err, io.EOF): return [...]*Promise{ - EOFActionError: Error(permissionErrorInputPastEndOfStream(streamOrAlias, env)), + EOFActionError: Error(PermissionError(OperationInput, PermissionTypePastEndOfStream, streamOrAlias, env)), EOFActionEOFCode: Delay(func(context.Context) *Promise { return Unify(out, Atom("end_of_file"), k, env) }), @@ -1650,9 +1648,9 @@ func (state *State) ReadTerm(streamOrAlias, out, options Term, k func(*Env) *Pro }), }[s.eofAction] case errors.Is(err, ErrInsufficient): - return Error(syntaxErrorInsufficient()) + return Error(SyntaxError(err, env)) case errors.As(err, &unexpectedToken): - return Error(syntaxErrorUnexpectedToken(Atom(err.Error()))) + return Error(SyntaxError(err, env)) default: return Error(SystemError(err)) } @@ -1691,10 +1689,10 @@ func (state *State) ReadTerm(streamOrAlias, out, options Term, k func(*Env) *Pro func readTermOption(opts *readTermOptions, option Term, env *Env) error { switch option := env.Resolve(option).(type) { case Variable: - return ErrInstantiation + return InstantiationError(env) case *Compound: if len(option.Args) != 1 { - return domainErrorReadOption(option, env) + return DomainError(ValidDomainReadOption, option, env) } v := env.Resolve(option.Args[0]) @@ -1706,11 +1704,11 @@ func readTermOption(opts *readTermOptions, option Term, env *Env) error { case "variable_names": opts.variableNames = v default: - return domainErrorReadOption(option, env) + return DomainError(ValidDomainReadOption, option, env) } return nil default: - return domainErrorReadOption(option, env) + return DomainError(ValidDomainReadOption, option, env) } } @@ -1724,11 +1722,11 @@ func (state *State) GetByte(streamOrAlias, inByte Term, k func(*Env) *Promise, e } if s.mode != StreamModeRead { - return Error(permissionErrorInputStream(streamOrAlias, env)) + return Error(PermissionError(OperationInput, PermissionTypeStream, streamOrAlias, env)) } if s.streamType == StreamTypeText { - return Error(permissionErrorInputTextStream(streamOrAlias, env)) + return Error(PermissionError(OperationInput, PermissionTypeTextStream, streamOrAlias, env)) } switch b := env.Resolve(inByte).(type) { @@ -1736,10 +1734,10 @@ func (state *State) GetByte(streamOrAlias, inByte Term, k func(*Env) *Promise, e break case Integer: if b < 0 || b > 255 { - return Error(TypeErrorInByte(inByte, env)) + return Error(TypeError(ValidTypeInByte, inByte, env)) } default: - return Error(TypeErrorInByte(inByte, env)) + return Error(TypeError(ValidTypeInByte, inByte, env)) } b, err := readByte(s.buf) @@ -1751,7 +1749,7 @@ func (state *State) GetByte(streamOrAlias, inByte Term, k func(*Env) *Promise, e case io.EOF: switch s.eofAction { case EOFActionError: - return Error(permissionErrorInputPastEndOfStream(streamOrAlias, env)) + return Error(PermissionError(OperationInput, PermissionTypePastEndOfStream, streamOrAlias, env)) case EOFActionEOFCode: return Delay(func(context.Context) *Promise { return Unify(inByte, Integer(-1), k, env) @@ -1778,11 +1776,11 @@ func (state *State) GetChar(streamOrAlias, char Term, k func(*Env) *Promise, env } if s.mode != StreamModeRead { - return Error(permissionErrorInputStream(streamOrAlias, env)) + return Error(PermissionError(OperationInput, PermissionTypeStream, streamOrAlias, env)) } if s.streamType == StreamTypeBinary { - return Error(permissionErrorInputBinaryStream(streamOrAlias, env)) + return Error(PermissionError(OperationInput, PermissionTypeBinaryStream, streamOrAlias, env)) } switch c := env.Resolve(char).(type) { @@ -1790,17 +1788,17 @@ func (state *State) GetChar(streamOrAlias, char Term, k func(*Env) *Promise, env break case Atom: if len([]rune(c)) != 1 { - return Error(TypeErrorInCharacter(char, env)) + return Error(TypeError(ValidTypeInCharacter, char, env)) } default: - return Error(TypeErrorInCharacter(char, env)) + return Error(TypeError(ValidTypeInCharacter, char, env)) } r, _, err := readRune(s.buf) switch err { case nil: if r == unicode.ReplacementChar { - return Error(representationError("character")) + return Error(RepresentationError(FlagCharacter, env)) } return Delay(func(context.Context) *Promise { @@ -1809,7 +1807,7 @@ func (state *State) GetChar(streamOrAlias, char Term, k func(*Env) *Promise, env case io.EOF: switch s.eofAction { case EOFActionError: - return Error(permissionErrorInputPastEndOfStream(streamOrAlias, env)) + return Error(PermissionError(OperationInput, PermissionTypePastEndOfStream, streamOrAlias, env)) case EOFActionEOFCode: return Delay(func(context.Context) *Promise { return Unify(char, Atom("end_of_file"), k, env) @@ -1836,11 +1834,11 @@ func (state *State) PeekByte(streamOrAlias, inByte Term, k func(*Env) *Promise, } if s.mode != StreamModeRead { - return Error(permissionErrorInputStream(streamOrAlias, env)) + return Error(PermissionError(OperationInput, PermissionTypeStream, streamOrAlias, env)) } if s.streamType == StreamTypeText { - return Error(permissionErrorInputTextStream(streamOrAlias, env)) + return Error(PermissionError(OperationInput, PermissionTypeTextStream, streamOrAlias, env)) } switch b := env.Resolve(inByte).(type) { @@ -1848,10 +1846,10 @@ func (state *State) PeekByte(streamOrAlias, inByte Term, k func(*Env) *Promise, break case Integer: if b < 0 || b > 255 { - return Error(TypeErrorInByte(inByte, env)) + return Error(TypeError(ValidTypeInByte, inByte, env)) } default: - return Error(TypeErrorInByte(inByte, env)) + return Error(TypeError(ValidTypeInByte, inByte, env)) } b, err := peek(s.buf, 1) @@ -1863,7 +1861,7 @@ func (state *State) PeekByte(streamOrAlias, inByte Term, k func(*Env) *Promise, case io.EOF: switch s.eofAction { case EOFActionError: - return Error(permissionErrorInputPastEndOfStream(streamOrAlias, env)) + return Error(PermissionError(OperationInput, PermissionTypePastEndOfStream, streamOrAlias, env)) case EOFActionEOFCode: return Delay(func(context.Context) *Promise { return Unify(inByte, Integer(-1), k, env) @@ -1890,11 +1888,11 @@ func (state *State) PeekChar(streamOrAlias, char Term, k func(*Env) *Promise, en } if s.mode != StreamModeRead { - return Error(permissionErrorInputStream(streamOrAlias, env)) + return Error(PermissionError(OperationInput, PermissionTypeStream, streamOrAlias, env)) } if s.streamType == StreamTypeBinary { - return Error(permissionErrorInputBinaryStream(streamOrAlias, env)) + return Error(PermissionError(OperationInput, PermissionTypeBinaryStream, streamOrAlias, env)) } switch c := env.Resolve(char).(type) { @@ -1902,10 +1900,10 @@ func (state *State) PeekChar(streamOrAlias, char Term, k func(*Env) *Promise, en break case Atom: if len([]rune(c)) != 1 { - return Error(TypeErrorInCharacter(char, env)) + return Error(TypeError(ValidTypeInCharacter, char, env)) } default: - return Error(TypeErrorInCharacter(char, env)) + return Error(TypeError(ValidTypeInCharacter, char, env)) } r, _, err := readRune(s.buf) @@ -1916,7 +1914,7 @@ func (state *State) PeekChar(streamOrAlias, char Term, k func(*Env) *Promise, en } if r == unicode.ReplacementChar { - return Error(representationError("character")) + return Error(RepresentationError(FlagCharacter, env)) } return Delay(func(context.Context) *Promise { @@ -1925,7 +1923,7 @@ func (state *State) PeekChar(streamOrAlias, char Term, k func(*Env) *Promise, en case io.EOF: switch s.eofAction { case EOFActionError: - return Error(permissionErrorInputPastEndOfStream(streamOrAlias, env)) + return Error(PermissionError(OperationInput, PermissionTypePastEndOfStream, streamOrAlias, env)) case EOFActionEOFCode: return Delay(func(context.Context) *Promise { return Unify(char, Atom("end_of_file"), k, env) @@ -1948,12 +1946,12 @@ var osExit = os.Exit func Halt(n Term, k func(*Env) *Promise, env *Env) *Promise { switch code := env.Resolve(n).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case Integer: osExit(int(code)) return k(env) default: - return Error(TypeErrorInteger(n, env)) + return Error(TypeError(ValidTypeInteger, n, env)) } } @@ -1968,7 +1966,7 @@ func (state *State) Clause(head, body Term, k func(*Env) *Promise, env *Env) *Pr case Variable, Atom, *Compound: break default: - return Error(TypeErrorCallable(body, env)) + return Error(TypeError(ValidTypeCallable, body, env)) } p, ok := state.procedures[pi] @@ -1978,7 +1976,7 @@ func (state *State) Clause(head, body Term, k func(*Env) *Promise, env *Env) *Pr cs, ok := p.(clauses) if !ok { - return Error(permissionErrorAccessPrivateProcedure(pi.Term(), env)) + return Error(PermissionError(OperationAccess, PermissionTypePrivateProcedure, pi.Term(), env)) } ks := make([]func(context.Context) *Promise, len(cs)) @@ -1998,24 +1996,24 @@ func (state *State) Clause(head, body Term, k func(*Env) *Promise, env *Env) *Pr func AtomLength(atom, length Term, k func(*Env) *Promise, env *Env) *Promise { switch a := env.Resolve(atom).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case Atom: switch l := env.Resolve(length).(type) { case Variable: break case Integer: if l < 0 { - return Error(domainErrorNotLessThanZero(length, env)) + return Error(DomainError(ValidDomainNotLessThanZero, length, env)) } default: - return Error(TypeErrorInteger(length, env)) + return Error(TypeError(ValidTypeInteger, length, env)) } return Delay(func(context.Context) *Promise { return Unify(length, Integer(len([]rune(a))), k, env) }) default: - return Error(TypeErrorAtom(atom, env)) + return Error(TypeError(ValidTypeAtom, atom, env)) } } @@ -2025,34 +2023,34 @@ func AtomConcat(atom1, atom2, atom3 Term, k func(*Env) *Promise, env *Env) *Prom case Variable: switch a1 := env.Resolve(atom1).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case Atom: switch a2 := env.Resolve(atom2).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case Atom: return Delay(func(context.Context) *Promise { return Unify(a1+a2, a3, k, env) }) default: - return Error(TypeErrorAtom(atom2, env)) + return Error(TypeError(ValidTypeAtom, atom2, env)) } default: - return Error(TypeErrorAtom(atom1, env)) + return Error(TypeError(ValidTypeAtom, atom1, env)) } case Atom: switch env.Resolve(atom1).(type) { case Variable, Atom: break default: - return Error(TypeErrorAtom(atom1, env)) + return Error(TypeError(ValidTypeAtom, atom1, env)) } switch env.Resolve(atom2).(type) { case Variable, Atom: break default: - return Error(TypeErrorAtom(atom2, env)) + return Error(TypeError(ValidTypeAtom, atom2, env)) } pattern := Compound{Args: []Term{atom1, atom2}} @@ -2068,7 +2066,7 @@ func AtomConcat(atom1, atom2, atom3 Term, k func(*Env) *Promise, env *Env) *Prom }) return Delay(ks...) default: - return Error(TypeErrorAtom(atom3, env)) + return Error(TypeError(ValidTypeAtom, atom3, env)) } } @@ -2076,7 +2074,7 @@ func AtomConcat(atom1, atom2, atom3 Term, k func(*Env) *Promise, env *Env) *Prom func SubAtom(atom, before, length, after, subAtom Term, k func(*Env) *Promise, env *Env) *Promise { switch whole := env.Resolve(atom).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case Atom: rs := []rune(whole) @@ -2096,7 +2094,7 @@ func SubAtom(atom, before, length, after, subAtom Term, k func(*Env) *Promise, e case Variable, Atom: break default: - return Error(TypeErrorAtom(subAtom, env)) + return Error(TypeError(ValidTypeAtom, subAtom, env)) } const subAtomPattern = Atom("$sub_atom_pattern") @@ -2112,7 +2110,7 @@ func SubAtom(atom, before, length, after, subAtom Term, k func(*Env) *Promise, e } return Delay(ks...) default: - return Error(TypeErrorAtom(atom, env)) + return Error(TypeError(ValidTypeAtom, atom, env)) } } @@ -2122,11 +2120,11 @@ func checkPositiveInteger(n Term, env *Env) error { return nil case Integer: if b < 0 { - return domainErrorNotLessThanZero(n, env) + return DomainError(ValidDomainNotLessThanZero, n, env) } return nil default: - return TypeErrorInteger(n, env) + return TypeError(ValidTypeInteger, n, env) } } @@ -2140,14 +2138,14 @@ func AtomChars(atom, chars Term, k func(*Env) *Promise, env *Env) *Promise { for iter.Next() { switch e := env.Resolve(iter.Current()).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case Atom: if len([]rune(e)) != 1 { - return Error(TypeErrorCharacter(e, env)) + return Error(TypeError(ValidTypeCharacter, e, env)) } _, _ = sb.WriteString(string(e)) default: - return Error(TypeErrorCharacter(e, env)) + return Error(TypeError(ValidTypeCharacter, e, env)) } } if err := iter.Err(); err != nil { @@ -2166,7 +2164,7 @@ func AtomChars(atom, chars Term, k func(*Env) *Promise, env *Env) *Promise { return Unify(chars, List(cs...), k, env) }) default: - return Error(TypeErrorAtom(a, env)) + return Error(TypeError(ValidTypeAtom, a, env)) } } @@ -2180,11 +2178,11 @@ func AtomCodes(atom, codes Term, k func(*Env) *Promise, env *Env) *Promise { for iter.Next() { switch e := env.Resolve(iter.Current()).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case Integer: _, _ = sb.WriteRune(rune(e)) default: - return Error(representationError("character_code")) + return Error(RepresentationError(FlagCharacterCode, env)) } } if err := iter.Err(); err != nil { @@ -2203,7 +2201,7 @@ func AtomCodes(atom, codes Term, k func(*Env) *Promise, env *Env) *Promise { return Unify(codes, List(cs...), k, env) }) default: - return Error(TypeErrorAtom(atom, env)) + return Error(TypeError(ValidTypeAtom, atom, env)) } } @@ -2220,17 +2218,17 @@ func NumberChars(num, chars Term, k func(*Env) *Promise, env *Env) *Promise { return numberCharsWrite(num, chars, k, env) case Atom: if len([]rune(e)) != 1 { - return Error(TypeErrorCharacter(e, env)) + return Error(TypeError(ValidTypeCharacter, e, env)) } _, _ = sb.WriteString(string(e)) default: - return Error(TypeErrorCharacter(e, env)) + return Error(TypeError(ValidTypeCharacter, e, env)) } } - switch err := iter.Err(); { - case errors.Is(err, ErrInstantiation): - return numberCharsWrite(num, chars, k, env) - case err != nil: + if err := iter.Err(); err != nil { + if _, ok := iter.Suffix().(Variable); ok { + return numberCharsWrite(num, chars, k, env) + } return Error(err) } @@ -2238,26 +2236,26 @@ func NumberChars(num, chars Term, k func(*Env) *Promise, env *Env) *Promise { t, err := p.Number() switch { case errors.Is(err, errNotANumber): - return Error(syntaxErrorNotANumber()) + return Error(SyntaxError(err, env)) case errors.Is(err, errExpectation): err := &unexpectedTokenError{ Actual: *p.current, } - return Error(syntaxErrorUnexpectedToken(Atom(err.Error()))) + return Error(SyntaxError(err, env)) } switch n := env.Resolve(num).(type) { case Variable, Number: return Unify(n, t, k, env) default: - return Error(TypeErrorNumber(n, env)) + return Error(TypeError(ValidTypeNumber, n, env)) } } func numberCharsWrite(num, chars Term, k func(*Env) *Promise, env *Env) *Promise { switch n := env.Resolve(num).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case Number: iter := ListIterator{List: chars, Env: env} for iter.Next() { @@ -2266,19 +2264,16 @@ func numberCharsWrite(num, chars Term, k func(*Env) *Promise, env *Env) *Promise break case Atom: if len(e) != 1 { - return Error(TypeErrorCharacter(e, env)) + return Error(TypeError(ValidTypeCharacter, e, env)) } default: - return Error(TypeErrorCharacter(e, env)) + return Error(TypeError(ValidTypeCharacter, e, env)) } } - switch err := iter.Err(); { - case err == nil: - break - case errors.Is(err, ErrInstantiation): - break - default: - return Error(err) + if err := iter.Err(); err != nil { + if _, ok := iter.Suffix().(Variable); !ok { + return Error(err) + } } var buf bytes.Buffer @@ -2291,7 +2286,7 @@ func numberCharsWrite(num, chars Term, k func(*Env) *Promise, env *Env) *Promise } return Unify(chars, List(cs...), k, env) default: - return Error(TypeErrorNumber(n, env)) + return Error(TypeError(ValidTypeNumber, n, env)) } } @@ -2306,7 +2301,7 @@ func NumberCodes(num, codes Term, k func(*Env) *Promise, env *Env) *Promise { case Variable, Integer, Float: break default: - return Error(TypeErrorNumber(n, env)) + return Error(TypeError(ValidTypeNumber, n, env)) } var sb strings.Builder @@ -2314,11 +2309,11 @@ func NumberCodes(num, codes Term, k func(*Env) *Promise, env *Env) *Promise { for iter.Next() { switch e := env.Resolve(iter.Current()).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case Integer: _, _ = sb.WriteRune(rune(e)) default: - return Error(representationError("character_code")) + return Error(RepresentationError(FlagCharacterCode, env)) } } if err := iter.Err(); err != nil { @@ -2331,7 +2326,7 @@ func NumberCodes(num, codes Term, k func(*Env) *Promise, env *Env) *Promise { case nil: break case errNotANumber: - return Error(syntaxErrorNotANumber()) + return Error(SyntaxError(err, env)) default: return Error(SystemError(err)) } @@ -2343,7 +2338,7 @@ func NumberCodes(num, codes Term, k func(*Env) *Promise, env *Env) *Promise { switch n := env.Resolve(num).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case Integer, Float: var buf bytes.Buffer if err := Write(&buf, n, nil); err != nil { @@ -2358,7 +2353,7 @@ func NumberCodes(num, codes Term, k func(*Env) *Promise, env *Env) *Promise { return Unify(codes, List(cs...), k, env) }) default: - return Error(TypeErrorNumber(num, env)) + return Error(TypeError(ValidTypeNumber, num, env)) } } @@ -2373,13 +2368,13 @@ func (state *State) StreamProperty(streamOrAlias, property Term, k func(*Env) *P case Atom: // ISO standard stream_property/2 doesn't take an alias but why not? v, ok := state.streams[s] if !ok { - return Error(existenceErrorStream(streamOrAlias, env)) + return Error(ExistenceError(ObjectTypeStream, streamOrAlias, env)) } streams = append(streams, v) case *Stream: streams = append(streams, s) default: - return Error(domainErrorStreamOrAlias(streamOrAlias, env)) + return Error(DomainError(ValidDomainStreamOrAlias, streamOrAlias, env)) } if err := checkStreamProperty(property, env); err != nil { @@ -2412,11 +2407,11 @@ func checkStreamProperty(property Term, env *Env) error { case "input", "output": return nil default: - return domainErrorStreamProperty(property, env) + return DomainError(ValidDomainStreamProperty, property, env) } case *Compound: if len(p.Args) != 1 { - return domainErrorStreamProperty(property, env) + return DomainError(ValidDomainStreamProperty, property, env) } arg := p.Args[0] switch p.Functor { @@ -2425,10 +2420,10 @@ func checkStreamProperty(property Term, env *Env) error { case "position": return checkInteger(arg, env) default: - return domainErrorStreamProperty(property, env) + return DomainError(ValidDomainStreamProperty, property, env) } default: - return domainErrorStreamProperty(property, env) + return DomainError(ValidDomainStreamProperty, property, env) } } @@ -2437,7 +2432,7 @@ func checkAtom(t Term, env *Env) error { case Variable, Atom: return nil default: - return TypeErrorAtom(t, env) + return TypeError(ValidTypeAtom, t, env) } } @@ -2446,7 +2441,7 @@ func checkInteger(t Term, env *Env) error { case Variable, Integer: return nil default: - return TypeErrorAtom(t, env) + return TypeError(ValidTypeAtom, t, env) } } @@ -2460,12 +2455,12 @@ func (state *State) SetStreamPosition(streamOrAlias, position Term, k func(*Env) } if !s.reposition { - return Error(PermissionError("reposition", "stream", streamOrAlias, env)) + return Error(PermissionError(OperationReposition, PermissionTypeStream, streamOrAlias, env)) } switch p := env.Resolve(position).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case Integer: if f, ok := s.file.(io.Seeker); ok { if _, err := seek(f, int64(p), 0); err != nil { @@ -2477,7 +2472,7 @@ func (state *State) SetStreamPosition(streamOrAlias, position Term, k func(*Env) return k(env) default: - return Error(TypeErrorInteger(position, env)) + return Error(TypeError(ValidTypeInteger, position, env)) } } @@ -2485,20 +2480,20 @@ func (state *State) SetStreamPosition(streamOrAlias, position Term, k func(*Env) func (state *State) CharConversion(inChar, outChar Term, k func(*Env) *Promise, env *Env) *Promise { switch in := env.Resolve(inChar).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case Atom: i := []rune(in) if len(i) != 1 { - return Error(representationError("character")) + return Error(RepresentationError(FlagCharacter, env)) } switch out := env.Resolve(outChar).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case Atom: o := []rune(out) if len(o) != 1 { - return Error(representationError("character")) + return Error(RepresentationError(FlagCharacter, env)) } if state.charConversions == nil { @@ -2511,10 +2506,10 @@ func (state *State) CharConversion(inChar, outChar Term, k func(*Env) *Promise, state.charConversions[i[0]] = o[0] return k(env) default: - return Error(representationError("character")) + return Error(RepresentationError(FlagCharacter, env)) } default: - return Error(representationError("character")) + return Error(RepresentationError(FlagCharacter, env)) } } @@ -2526,10 +2521,10 @@ func (state *State) CurrentCharConversion(inChar, outChar Term, k func(*Env) *Pr case Atom: i := []rune(in) if len(i) != 1 { - return Error(representationError("character")) + return Error(RepresentationError(FlagCharacter, env)) } default: - return Error(representationError("character")) + return Error(RepresentationError(FlagCharacter, env)) } switch out := env.Resolve(outChar).(type) { @@ -2538,10 +2533,10 @@ func (state *State) CurrentCharConversion(inChar, outChar Term, k func(*Env) *Pr case Atom: o := []rune(out) if len(o) != 1 { - return Error(representationError("character")) + return Error(RepresentationError(FlagCharacter, env)) } default: - return Error(representationError("character")) + return Error(RepresentationError(FlagCharacter, env)) } if c1, ok := env.Resolve(inChar).(Atom); ok { @@ -2576,12 +2571,12 @@ func (state *State) CurrentCharConversion(inChar, outChar Term, k func(*Env) *Pr func (state *State) SetPrologFlag(flag, value Term, k func(*Env) *Promise, env *Env) *Promise { switch f := env.Resolve(flag).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case Atom: var modify func(value Atom) error switch f { case "bounded", "max_integer", "min_integer", "integer_rounding_function", "max_arity": - return Error(PermissionError("modify", "flag", f, env)) + return Error(PermissionError(OperationModify, PermissionTypeFlag, f, env)) case "char_conversion": modify = state.modifyCharConversion case "debug": @@ -2591,25 +2586,25 @@ func (state *State) SetPrologFlag(flag, value Term, k func(*Env) *Promise, env * case "double_quotes": modify = state.modifyDoubleQuotes default: - return Error(domainErrorPrologFlag(f, env)) + return Error(DomainError(ValidDomainPrologFlag, f, env)) } switch v := env.Resolve(value).(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case Atom: if err := modify(v); err != nil { return Error(err) } return k(env) default: - return Error(domainErrorFlagValue(&Compound{ + return Error(DomainError(ValidDomainFlagValue, &Compound{ Functor: "+", Args: []Term{flag, value}, }, env)) } default: - return Error(TypeErrorAtom(f, env)) + return Error(TypeError(ValidTypeAtom, f, env)) } } @@ -2620,7 +2615,7 @@ func (state *State) modifyCharConversion(value Atom) error { case "off": state.charConvEnabled = false default: - return domainErrorFlagValue(&Compound{ + return DomainError(ValidDomainFlagValue, &Compound{ Functor: "+", Args: []Term{Atom("char_conversion"), value}, }, nil) @@ -2635,7 +2630,7 @@ func (state *State) modifyDebug(value Atom) error { case "off": state.debug = false default: - return domainErrorFlagValue(&Compound{ + return DomainError(ValidDomainFlagValue, &Compound{ Functor: "+", Args: []Term{Atom("debug"), value}, }, nil) @@ -2652,7 +2647,7 @@ func (state *State) modifyUnknown(value Atom) error { case "fail": state.unknown = unknownFail default: - return domainErrorFlagValue(&Compound{ + return DomainError(ValidDomainFlagValue, &Compound{ Functor: "+", Args: []Term{Atom("unknown"), value}, }, nil) @@ -2669,7 +2664,7 @@ func (state *State) modifyDoubleQuotes(value Atom) error { case "atom": state.doubleQuotes = doubleQuotesAtom default: - return domainErrorFlagValue(&Compound{ + return DomainError(ValidDomainFlagValue, &Compound{ Functor: "+", Args: []Term{Atom("double_quotes"), value}, }, nil) @@ -2687,10 +2682,10 @@ func (state *State) CurrentPrologFlag(flag, value Term, k func(*Env) *Promise, e case "bounded", "max_integer", "min_integer", "integer_rounding_function", "char_conversion", "debug", "max_arity", "unknown", "double_quotes": break default: - return Error(domainErrorPrologFlag(f, env)) + return Error(DomainError(ValidDomainPrologFlag, f, env)) } default: - return Error(TypeErrorAtom(f, env)) + return Error(TypeError(ValidTypeAtom, f, env)) } pattern := Compound{Args: []Term{flag, value}} @@ -2725,17 +2720,17 @@ func onOff(b bool) Atom { func (state *State) stream(streamOrAlias Term, env *Env) (*Stream, error) { switch s := env.Resolve(streamOrAlias).(type) { case Variable: - return nil, ErrInstantiation + return nil, InstantiationError(env) case Atom: v, ok := state.streams[s] if !ok { - return nil, existenceErrorStream(streamOrAlias, env) + return nil, ExistenceError(ObjectTypeStream, streamOrAlias, env) } return v, nil case *Stream: return s, nil default: - return nil, domainErrorStreamOrAlias(streamOrAlias, env) + return nil, DomainError(ValidDomainStreamOrAlias, streamOrAlias, env) } } @@ -2757,7 +2752,7 @@ func (state *State) Dynamic(pi Term, k func(*Env) *Promise, env *Env) *Promise { continue } if _, ok := p.(clauses); !ok { - return Error(permissionErrorModifyStaticProcedure(elem, env)) + return Error(PermissionError(OperationModify, PermissionTypeStaticProcedure, elem, env)) } } if err := iter.Err(); err != nil { @@ -2784,7 +2779,7 @@ func (state *State) BuiltIn(pi Term, k func(*Env) *Promise, env *Env) *Promise { continue } if _, ok := p.(builtin); !ok { - return Error(permissionErrorModifyStaticProcedure(elem, env)) + return Error(PermissionError(OperationModify, PermissionTypeStaticProcedure, elem, env)) } } if err := iter.Err(); err != nil { @@ -2887,7 +2882,7 @@ func nth(base Integer, n, list, elem Term, k func(*Env) *Promise, env *Env) *Pro } return Bool(false) default: - return Error(TypeErrorInteger(n, env)) + return Error(TypeError(ValidTypeInteger, n, env)) } } @@ -2897,26 +2892,30 @@ func Succ(x, s Term, k func(*Env) *Promise, env *Env) *Promise { case Variable: switch s := s.(type) { case Variable: - return Error(ErrInstantiation) + return Error(InstantiationError(env)) case Integer: switch { case s < Integer(0): - return Error(domainErrorNotLessThanZero(s, env)) + return Error(DomainError(ValidDomainNotLessThanZero, s, env)) case s == Integer(0): return Bool(false) default: return Unify(x, s-Integer(1), k, env) } default: - return Error(TypeErrorInteger(s, env)) + return Error(TypeError(ValidTypeInteger, s, env)) } case Integer: if x < Integer(0) { - return Error(domainErrorNotLessThanZero(x, env)) + return Error(DomainError(ValidDomainNotLessThanZero, x, env)) } r, err := Add(x, Integer(1)) if err != nil { + var ev ExceptionalValue + if errors.As(err, &ev) { + return Error(EvaluationError(ev, env)) + } return Error(err) } @@ -2925,13 +2924,13 @@ func Succ(x, s Term, k func(*Env) *Promise, env *Env) *Promise { return Unify(s, r, k, env) case Integer: if s < Integer(0) { - return Error(domainErrorNotLessThanZero(s, env)) + return Error(DomainError(ValidDomainNotLessThanZero, s, env)) } return Unify(s, r, k, env) default: - return Error(TypeErrorInteger(s, env)) + return Error(TypeError(ValidTypeInteger, s, env)) } default: - return Error(TypeErrorInteger(x, env)) + return Error(TypeError(ValidTypeInteger, x, env)) } } diff --git a/engine/builtin_test.go b/engine/builtin_test.go index 1982c962..56b08955 100644 --- a/engine/builtin_test.go +++ b/engine/builtin_test.go @@ -164,7 +164,7 @@ func TestState_Call(t *testing.T) { t.Run("undefined atom", func(t *testing.T) { ok, err := state.Call(Atom("foo"), Success, nil).Force(context.Background()) - assert.Equal(t, existenceErrorProcedure(&Compound{ + assert.Equal(t, ExistenceError(ObjectTypeProcedure, &Compound{ Functor: "/", Args: []Term{Atom("foo"), Integer(0)}, }, nil), err) @@ -181,7 +181,7 @@ func TestState_Call(t *testing.T) { t.Run("undefined compound", func(t *testing.T) { ok, err := state.Call(&Compound{Functor: "bar", Args: []Term{NewVariable(), NewVariable()}}, Success, nil).Force(context.Background()) - assert.Equal(t, existenceErrorProcedure(&Compound{ + assert.Equal(t, ExistenceError(ObjectTypeProcedure, &Compound{ Functor: "/", Args: []Term{Atom("bar"), Integer(2)}, }, nil), err) @@ -199,7 +199,7 @@ func TestState_Call(t *testing.T) { t.Run("variable", func(t *testing.T) { t.Run("single predicate", func(t *testing.T) { ok, err := state.Call(Variable("X"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) @@ -223,7 +223,7 @@ func TestState_Call(t *testing.T) { t.Run("not callable", func(t *testing.T) { t.Run("single predicate", func(t *testing.T) { ok, err := state.Call(Integer(0), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCallable(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeCallable, Integer(0), nil), err) assert.False(t, ok) }) @@ -236,7 +236,7 @@ func TestState_Call(t *testing.T) { Integer(0), }, }, Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCallable(&Compound{ + assert.Equal(t, TypeError(ValidTypeCallable, &Compound{ Functor: ",", Args: []Term{ Atom("true"), @@ -254,7 +254,7 @@ func TestState_Call(t *testing.T) { Atom("true"), }, }, Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCallable(&Compound{ + assert.Equal(t, TypeError(ValidTypeCallable, &Compound{ Functor: ";", Args: []Term{ Integer(1), @@ -283,13 +283,13 @@ func TestState_Call1(t *testing.T) { t.Run("closure is a variable", func(t *testing.T) { var state State _, err := state.Call1(Variable("P"), Atom("a"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) }) t.Run("closure is neither a variable nor a callable term", func(t *testing.T) { var state State _, err := state.Call1(Integer(3), Atom("a"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCallable(Integer(3), nil), err) + assert.Equal(t, TypeError(ValidTypeCallable, Integer(3), nil), err) }) } @@ -309,13 +309,13 @@ func TestState_Call2(t *testing.T) { t.Run("closure is a variable", func(t *testing.T) { var state State _, err := state.Call2(Variable("P"), Atom("a"), Atom("b"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) }) t.Run("closure is neither a variable nor a callable term", func(t *testing.T) { var state State _, err := state.Call2(Integer(3), Atom("a"), Atom("b"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCallable(Integer(3), nil), err) + assert.Equal(t, TypeError(ValidTypeCallable, Integer(3), nil), err) }) } @@ -335,13 +335,13 @@ func TestState_Call3(t *testing.T) { t.Run("closure is a variable", func(t *testing.T) { var state State _, err := state.Call3(Variable("P"), Atom("a"), Atom("b"), Atom("c"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) }) t.Run("closure is neither a variable nor a callable term", func(t *testing.T) { var state State _, err := state.Call3(Integer(3), Atom("a"), Atom("b"), Atom("c"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCallable(Integer(3), nil), err) + assert.Equal(t, TypeError(ValidTypeCallable, Integer(3), nil), err) }) } @@ -361,13 +361,13 @@ func TestState_Call4(t *testing.T) { t.Run("closure is a variable", func(t *testing.T) { var state State _, err := state.Call4(Variable("P"), Atom("a"), Atom("b"), Atom("c"), Atom("d"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) }) t.Run("closure is neither a variable nor a callable term", func(t *testing.T) { var state State _, err := state.Call4(Integer(3), Atom("a"), Atom("b"), Atom("c"), Atom("d"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCallable(Integer(3), nil), err) + assert.Equal(t, TypeError(ValidTypeCallable, Integer(3), nil), err) }) } @@ -387,13 +387,13 @@ func TestState_Call5(t *testing.T) { t.Run("closure is a variable", func(t *testing.T) { var state State _, err := state.Call5(Variable("P"), Atom("a"), Atom("b"), Atom("c"), Atom("d"), Atom("e"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) }) t.Run("closure is neither a variable nor a callable term", func(t *testing.T) { var state State _, err := state.Call5(Integer(3), Atom("a"), Atom("b"), Atom("c"), Atom("d"), Atom("e"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCallable(Integer(3), nil), err) + assert.Equal(t, TypeError(ValidTypeCallable, Integer(3), nil), err) }) } @@ -413,13 +413,13 @@ func TestState_Call6(t *testing.T) { t.Run("closure is a variable", func(t *testing.T) { var state State _, err := state.Call6(Variable("P"), Atom("a"), Atom("b"), Atom("c"), Atom("d"), Atom("e"), Atom("f"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) }) t.Run("closure is neither a variable nor a callable term", func(t *testing.T) { var state State _, err := state.Call6(Integer(3), Atom("a"), Atom("b"), Atom("c"), Atom("d"), Atom("e"), Atom("f"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCallable(Integer(3), nil), err) + assert.Equal(t, TypeError(ValidTypeCallable, Integer(3), nil), err) }) } @@ -439,13 +439,13 @@ func TestState_Call7(t *testing.T) { t.Run("closure is a variable", func(t *testing.T) { var state State _, err := state.Call7(Variable("P"), Atom("a"), Atom("b"), Atom("c"), Atom("d"), Atom("e"), Atom("f"), Atom("g"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) }) t.Run("closure is neither a variable nor a callable term", func(t *testing.T) { var state State _, err := state.Call7(Integer(3), Atom("a"), Atom("b"), Atom("c"), Atom("d"), Atom("e"), Atom("f"), Atom("g"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCallable(Integer(3), nil), err) + assert.Equal(t, TypeError(ValidTypeCallable, Integer(3), nil), err) }) } @@ -503,22 +503,22 @@ func TestState_CallNth(t *testing.T) { t.Run("goal is a variable and nth is not zero", func(t *testing.T) { _, err := state.CallNth(Variable("Goal"), Integer(3), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) }) t.Run("goal is neither a variable nor a callable term", func(t *testing.T) { _, err := state.CallNth(Integer(0), Integer(3), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCallable(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeCallable, Integer(0), nil), err) }) t.Run("nth is neither a variable nor an integer", func(t *testing.T) { _, err := state.CallNth(Atom("foo"), Atom("bar"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInteger(Atom("bar"), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Atom("bar"), nil), err) }) t.Run("nth is an integer which is less than zero", func(t *testing.T) { _, err := state.CallNth(Atom("foo"), Integer(-1), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorNotLessThanZero(Integer(-1), nil), err) + assert.Equal(t, DomainError(ValidDomainNotLessThanZero, Integer(-1), nil), err) }) t.Run("n+1 is larger than max_integer", func(t *testing.T) { @@ -527,7 +527,7 @@ func TestState_CallNth(t *testing.T) { callNthInit = 0 }() _, err := state.CallNth(Atom("foo"), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, representationError("max_integer"), err) + assert.Equal(t, RepresentationError(FlagMaxInteger, nil), err) }) } @@ -803,7 +803,7 @@ func TestFunctor(t *testing.T) { t.Run("name is a variable", func(t *testing.T) { name := NewVariable() ok, err := Functor(NewVariable(), name, Integer(2), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) @@ -814,7 +814,7 @@ func TestFunctor(t *testing.T) { Atom("a"), }, }, Integer(1), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorAtomic(&Compound{ + assert.Equal(t, TypeError(ValidTypeAtomic, &Compound{ Functor: "foo", Args: []Term{ Atom("a"), @@ -825,26 +825,26 @@ func TestFunctor(t *testing.T) { t.Run("name is not an atom", func(t *testing.T) { ok, err := Functor(NewVariable(), Integer(0), Integer(2), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorAtom(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeAtom, Integer(0), nil), err) assert.False(t, ok) }) t.Run("arity is a variable", func(t *testing.T) { arity := NewVariable() ok, err := Functor(NewVariable(), Atom("f"), arity, Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("arity is not an integer", func(t *testing.T) { ok, err := Functor(NewVariable(), Atom("f"), Float(2.0), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInteger(Float(2.0), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Float(2.0), nil), err) assert.False(t, ok) }) t.Run("arity is negative", func(t *testing.T) { ok, err := Functor(NewVariable(), Atom("f"), Integer(-2), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorNotLessThanZero(Integer(-2), nil), err) + assert.Equal(t, DomainError(ValidDomainNotLessThanZero, Integer(-2), nil), err) assert.False(t, ok) }) }) @@ -854,13 +854,13 @@ func TestArg(t *testing.T) { t.Run("term is a variable", func(t *testing.T) { v := NewVariable() ok, err := Arg(NewVariable(), v, NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("term is not a compound", func(t *testing.T) { ok, err := Arg(NewVariable(), Atom("foo"), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCompound(Atom("foo"), nil), err) + assert.Equal(t, TypeError(ValidTypeCompound, Atom("foo"), nil), err) assert.False(t, ok) }) @@ -870,7 +870,7 @@ func TestArg(t *testing.T) { Functor: "f", Args: []Term{Atom("a"), Atom("b"), Atom("a")}, }, Atom("a"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) }) t.Run("nth is an integer", func(t *testing.T) { @@ -918,7 +918,7 @@ func TestArg(t *testing.T) { Functor: "f", Args: []Term{Atom("a"), Atom("b"), Atom("c")}, }, Atom("b"), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorNotLessThanZero(Integer(-2), nil), err) + assert.Equal(t, DomainError(ValidDomainNotLessThanZero, Integer(-2), nil), err) assert.False(t, ok) }) }) @@ -928,7 +928,7 @@ func TestArg(t *testing.T) { Functor: "f", Args: []Term{Atom("a"), Atom("b"), Atom("c")}, }, Atom("b"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInteger(Atom("foo"), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Atom("foo"), nil), err) assert.False(t, ok) }) } @@ -951,27 +951,27 @@ func TestUniv(t *testing.T) { t.Run("list is empty", func(t *testing.T) { v := NewVariable() ok, err := Univ(v, List(), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorNotEmptyList(Atom("[]"), nil), err) + assert.Equal(t, DomainError(ValidDomainNonEmptyList, Atom("[]"), nil), err) assert.False(t, ok) }) t.Run("list is not a list", func(t *testing.T) { v := NewVariable() ok, err := Univ(v, Atom("list"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorList(Atom("list"), nil), err) + assert.Equal(t, TypeError(ValidTypeList, Atom("list"), nil), err) assert.False(t, ok) }) t.Run("list's first element is not an atom", func(t *testing.T) { v := NewVariable() ok, err := Univ(v, List(Integer(0), Atom("a"), Atom("b")), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorAtom(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeAtom, Integer(0), nil), err) assert.False(t, ok) }) t.Run("list is not fully instantiated", func(t *testing.T) { ok, err := Univ(NewVariable(), ListRest(Variable("Rest"), Atom("f"), Atom("a"), Atom("b")), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) }) @@ -1118,42 +1118,42 @@ func TestState_Op(t *testing.T) { t.Run("priority is not an integer", func(t *testing.T) { var state State ok, err := state.Op(Atom("foo"), Atom("xfx"), Atom("+"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInteger(Atom("foo"), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Atom("foo"), nil), err) assert.False(t, ok) }) t.Run("priority is negative", func(t *testing.T) { var state State ok, err := state.Op(Integer(-1), Atom("xfx"), Atom("+"), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorOperatorPriority(Integer(-1), nil), err) + assert.Equal(t, DomainError(ValidDomainOperatorPriority, Integer(-1), nil), err) assert.False(t, ok) }) t.Run("priority is more than 1200", func(t *testing.T) { var state State ok, err := state.Op(Integer(1201), Atom("xfx"), Atom("+"), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorOperatorPriority(Integer(1201), nil), err) + assert.Equal(t, DomainError(ValidDomainOperatorPriority, Integer(1201), nil), err) assert.False(t, ok) }) t.Run("specifier is not an atom", func(t *testing.T) { var state State ok, err := state.Op(Integer(1000), Integer(0), Atom("+"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorAtom(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeAtom, Integer(0), nil), err) assert.False(t, ok) }) t.Run("specifier is not a valid operator specifier", func(t *testing.T) { var state State ok, err := state.Op(Integer(1000), Atom("foo"), Atom("+"), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorOperatorSpecifier(Atom("foo"), nil), err) + assert.Equal(t, DomainError(ValidDomainOperatorSpecifier, Atom("foo"), nil), err) assert.False(t, ok) }) t.Run("operator is not an atom", func(t *testing.T) { var state State ok, err := state.Op(Integer(1000), Atom("xfx"), Integer(0), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorAtom(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeAtom, Integer(0), nil), err) assert.False(t, ok) }) } @@ -1217,13 +1217,13 @@ func TestState_CurrentOp(t *testing.T) { t.Run("priority is not an operator priority", func(t *testing.T) { t.Run("priority is not an integer", func(t *testing.T) { ok, err := state.CurrentOp(Atom("foo"), Atom("xfx"), Atom("+"), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorOperatorPriority(Atom("foo"), nil), err) + assert.Equal(t, DomainError(ValidDomainOperatorPriority, Atom("foo"), nil), err) assert.False(t, ok) }) t.Run("priority is negative", func(t *testing.T) { ok, err := state.CurrentOp(Integer(-1), Atom("xfx"), Atom("+"), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorOperatorPriority(Integer(-1), nil), err) + assert.Equal(t, DomainError(ValidDomainOperatorPriority, Integer(-1), nil), err) assert.False(t, ok) }) }) @@ -1231,20 +1231,20 @@ func TestState_CurrentOp(t *testing.T) { t.Run("specifier is not an operator specifier", func(t *testing.T) { t.Run("specifier is not an atom", func(t *testing.T) { ok, err := state.CurrentOp(Integer(1100), Integer(0), Atom("+"), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorOperatorSpecifier(Integer(0), nil), err) + assert.Equal(t, DomainError(ValidDomainOperatorSpecifier, Integer(0), nil), err) assert.False(t, ok) }) t.Run("specifier is a non-specifier atom", func(t *testing.T) { ok, err := state.CurrentOp(Integer(1100), Atom("foo"), Atom("+"), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorOperatorSpecifier(Atom("foo"), nil), err) + assert.Equal(t, DomainError(ValidDomainOperatorSpecifier, Atom("foo"), nil), err) assert.False(t, ok) }) }) t.Run("operator is not an atom", func(t *testing.T) { ok, err := state.CurrentOp(Integer(1100), Atom("xfx"), Integer(0), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorAtom(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeAtom, Integer(0), nil), err) assert.False(t, ok) }) } @@ -1386,14 +1386,14 @@ func TestState_BagOf(t *testing.T) { t.Run("goal is a variable", func(t *testing.T) { var state State ok, err := state.BagOf(NewVariable(), Variable("Goal"), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("goal is neither a variable nor a callable term", func(t *testing.T) { var state State ok, err := state.BagOf(NewVariable(), Integer(0), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCallable(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeCallable, Integer(0), nil), err) assert.False(t, ok) }) @@ -1643,14 +1643,14 @@ func TestState_SetOf(t *testing.T) { t.Run("goal is a variable", func(t *testing.T) { var state State ok, err := state.SetOf(NewVariable(), Variable("Goal"), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("goal is neither a variable nor a callable term", func(t *testing.T) { var state State ok, err := state.SetOf(NewVariable(), Integer(0), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCallable(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeCallable, Integer(0), nil), err) assert.False(t, ok) }) } @@ -1720,14 +1720,14 @@ func TestState_FindAll(t *testing.T) { t.Run("goal is a variable", func(t *testing.T) { var state State ok, err := state.FindAll(NewVariable(), Variable("Goal"), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("goal is neither a variable nor a callable term", func(t *testing.T) { var state State ok, err := state.FindAll(NewVariable(), Integer(0), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCallable(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeCallable, Integer(0), nil), err) assert.False(t, ok) }) @@ -1798,13 +1798,13 @@ func TestCompare(t *testing.T) { t.Run("order is neither a variable nor an atom", func(t *testing.T) { ok, err := Compare(Integer(0), NewVariable(), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorAtom(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeAtom, Integer(0), nil), err) assert.False(t, ok) }) t.Run("order is an atom but not <, =, or >", func(t *testing.T) { ok, err := Compare(Atom("foo"), NewVariable(), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorOrder(Atom("foo"), nil), err) + assert.Equal(t, DomainError(ValidDomainOrder, Atom("foo"), nil), err) assert.False(t, ok) }) } @@ -1904,27 +1904,27 @@ func TestBetween(t *testing.T) { t.Run("lower is uninstantiated", func(t *testing.T) { _, err := Between(Variable("X"), Integer(2), Integer(1), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) }) t.Run("upper is uninstantiated", func(t *testing.T) { _, err := Between(Integer(1), Variable("X"), Integer(1), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) }) t.Run("lower is not an integer", func(t *testing.T) { _, err := Between(Atom("inf"), Integer(2), Integer(1), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInteger(Atom("inf"), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Atom("inf"), nil), err) }) t.Run("upper is not an integer", func(t *testing.T) { _, err := Between(Integer(1), Atom("inf"), Integer(1), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInteger(Atom("inf"), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Atom("inf"), nil), err) }) t.Run("value is not an integer or variable", func(t *testing.T) { _, err := Between(Integer(1), Integer(1), Atom("foo"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInteger(Atom("foo"), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Atom("foo"), nil), err) }) } @@ -1949,23 +1949,23 @@ func TestSort(t *testing.T) { t.Run("list is a partial list", func(t *testing.T) { _, err := Sort(ListRest(Variable("X"), Atom("a"), Atom("b")), Variable("Sorted"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) }) t.Run("list is neither a partial list nor a list", func(t *testing.T) { _, err := Sort(Atom("a"), Variable("Sorted"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorList(Atom("a"), nil), err) + assert.Equal(t, TypeError(ValidTypeList, Atom("a"), nil), err) }) t.Run("sorted is neither a partial list nor a list", func(t *testing.T) { t.Run("obviously not a list", func(t *testing.T) { _, err := Sort(List(Atom("a")), Atom("a"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorList(Atom("a"), nil), err) + assert.Equal(t, TypeError(ValidTypeList, Atom("a"), nil), err) }) t.Run("list-ish", func(t *testing.T) { _, err := Sort(List(Atom("a")), &Compound{Functor: ".", Args: []Term{Atom("a")}}, Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorList(&Compound{Functor: ".", Args: []Term{Atom("a")}}, nil), err) + assert.Equal(t, TypeError(ValidTypeList, &Compound{Functor: ".", Args: []Term{Atom("a")}}, nil), err) }) }) } @@ -2015,45 +2015,45 @@ func TestKeySort(t *testing.T) { t.Run("pairs is a partial list", func(t *testing.T) { _, err := KeySort(ListRest(Variable("Rest"), Pair(Atom("a"), Integer(1))), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) }) t.Run("pairs is neither a partial list nor a list", func(t *testing.T) { _, err := KeySort(Atom("a"), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorList(Atom("a"), nil), err) + assert.Equal(t, TypeError(ValidTypeList, Atom("a"), nil), err) }) t.Run("sorted is neither a partial list nor a list", func(t *testing.T) { _, err := KeySort(List(), Atom("foo"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorList(Atom("foo"), nil), err) + assert.Equal(t, TypeError(ValidTypeList, Atom("foo"), nil), err) }) t.Run("an element of a list prefix of pairs is a variable", func(t *testing.T) { _, err := KeySort(List(Variable("X")), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) }) t.Run("an element of a list prefix of pairs is neither a variable nor a compound term with principal functor (-)/2", func(t *testing.T) { t.Run("atomic", func(t *testing.T) { _, err := KeySort(List(Atom("foo")), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorPair(Atom("foo"), nil), err) + assert.Equal(t, TypeError(ValidTypePair, Atom("foo"), nil), err) }) t.Run("compound", func(t *testing.T) { _, err := KeySort(List(Atom("f").Apply(Atom("a"))), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorPair(Atom("f").Apply(Atom("a")), nil), err) + assert.Equal(t, TypeError(ValidTypePair, Atom("f").Apply(Atom("a")), nil), err) }) }) t.Run("an element of a list prefix of sorted is neither a variable nor a compound term with principal functor (-)/2", func(t *testing.T) { t.Run("atomic", func(t *testing.T) { _, err := KeySort(List(), List(Atom("foo")), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorPair(Atom("foo"), nil), err) + assert.Equal(t, TypeError(ValidTypePair, Atom("foo"), nil), err) }) t.Run("compound", func(t *testing.T) { _, err := KeySort(List(), List(Atom("f").Apply(Atom("a"))), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorPair(Atom("f").Apply(Atom("a")), nil), err) + assert.Equal(t, TypeError(ValidTypePair, Atom("f").Apply(Atom("a")), nil), err) }) }) } @@ -2061,13 +2061,13 @@ func TestKeySort(t *testing.T) { func TestThrow(t *testing.T) { t.Run("ok", func(t *testing.T) { ok, err := Throw(Atom("a"), Success, nil).Force(context.Background()) - assert.Equal(t, &Exception{term: Atom("a")}, err) + assert.Equal(t, Exception{term: Atom("a")}, err) assert.False(t, ok) }) t.Run("ball is a variable", func(t *testing.T) { ok, err := Throw(Variable("Ball"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) } @@ -2102,7 +2102,7 @@ func TestState_Catch(t *testing.T) { Args: []Term{Atom("a")}, }, Atom("b"), Atom("fail"), Success, nil).Force(context.Background()) assert.False(t, ok) - ex, ok := err.(*Exception) + ex, ok := err.(Exception) assert.True(t, ok) assert.Equal(t, Atom("a"), ex.term) }) @@ -2199,7 +2199,7 @@ func TestState_CurrentPredicate(t *testing.T) { t.Run("atom", func(t *testing.T) { var state State ok, err := state.CurrentPredicate(Atom("foo"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorPredicateIndicator(Atom("foo"), nil), err) + assert.Equal(t, TypeError(ValidTypePredicateIndicator, Atom("foo"), nil), err) assert.False(t, ok) }) @@ -2210,7 +2210,7 @@ func TestState_CurrentPredicate(t *testing.T) { Functor: "f", Args: []Term{Atom("a")}, }, Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorPredicateIndicator(&Compound{ + assert.Equal(t, TypeError(ValidTypePredicateIndicator, &Compound{ Functor: "f", Args: []Term{Atom("a")}, }, nil), err) @@ -2223,7 +2223,7 @@ func TestState_CurrentPredicate(t *testing.T) { Functor: "/", Args: []Term{Integer(0), Integer(0)}, }, Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorPredicateIndicator(&Compound{ + assert.Equal(t, TypeError(ValidTypePredicateIndicator, &Compound{ Functor: "/", Args: []Term{Integer(0), Integer(0)}, }, nil), err) @@ -2236,7 +2236,7 @@ func TestState_CurrentPredicate(t *testing.T) { Functor: "/", Args: []Term{Atom("foo"), Atom("bar")}, }, Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorPredicateIndicator(&Compound{ + assert.Equal(t, TypeError(ValidTypePredicateIndicator, &Compound{ Functor: "/", Args: []Term{Atom("foo"), Atom("bar")}, }, nil), err) @@ -2306,14 +2306,14 @@ func TestState_Assertz(t *testing.T) { var state State ok, err := state.Assertz(clause, Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("clause is neither a variable, nor callable", func(t *testing.T) { var state State ok, err := state.Assertz(Integer(0), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCallable(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeCallable, Integer(0), nil), err) assert.False(t, ok) }) @@ -2325,7 +2325,7 @@ func TestState_Assertz(t *testing.T) { Functor: ":-", Args: []Term{head, Atom("true")}, }, Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) @@ -2335,7 +2335,7 @@ func TestState_Assertz(t *testing.T) { Functor: ":-", Args: []Term{Integer(0), Atom("true")}, }, Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCallable(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeCallable, Integer(0), nil), err) assert.False(t, ok) }) @@ -2354,7 +2354,7 @@ func TestState_Assertz(t *testing.T) { }, }, }, Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCallable(&Compound{ + assert.Equal(t, TypeError(ValidTypeCallable, &Compound{ Functor: ",", Args: []Term{ Atom("true"), @@ -2374,7 +2374,7 @@ func TestState_Assertz(t *testing.T) { } ok, err := state.Assertz(Atom("foo"), Success, nil).Force(context.Background()) - assert.Equal(t, permissionErrorModifyStaticProcedure(&Compound{ + assert.Equal(t, PermissionError(OperationModify, PermissionTypeStaticProcedure, &Compound{ Functor: "/", Args: []Term{ Atom("foo"), @@ -2394,7 +2394,7 @@ func TestState_Assertz(t *testing.T) { } ok, err := state.Assertz(Atom("foo"), Success, nil).Force(context.Background()) - assert.Equal(t, permissionErrorModifyStaticProcedure(&Compound{ + assert.Equal(t, PermissionError(OperationModify, PermissionTypeStaticProcedure, &Compound{ Functor: "/", Args: []Term{ Atom("foo"), @@ -2542,14 +2542,14 @@ func TestState_Asserta(t *testing.T) { var state State ok, err := state.Asserta(clause, Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("clause is neither a variable, nor callable", func(t *testing.T) { var state State ok, err := state.Asserta(Integer(0), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCallable(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeCallable, Integer(0), nil), err) assert.False(t, ok) }) @@ -2561,7 +2561,7 @@ func TestState_Asserta(t *testing.T) { Functor: ":-", Args: []Term{head, Atom("true")}, }, Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) @@ -2571,7 +2571,7 @@ func TestState_Asserta(t *testing.T) { Functor: ":-", Args: []Term{Integer(0), Atom("true")}, }, Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCallable(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeCallable, Integer(0), nil), err) assert.False(t, ok) }) @@ -2581,7 +2581,7 @@ func TestState_Asserta(t *testing.T) { Functor: ":-", Args: []Term{Atom("foo"), Integer(0)}, }, Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCallable(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeCallable, Integer(0), nil), err) assert.False(t, ok) }) @@ -2599,7 +2599,7 @@ func TestState_Asserta(t *testing.T) { }, }, }, Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCallable(&Compound{ + assert.Equal(t, TypeError(ValidTypeCallable, &Compound{ Functor: ",", Args: []Term{ Atom("true"), @@ -2618,7 +2618,7 @@ func TestState_Asserta(t *testing.T) { } ok, err := state.Asserta(Atom("foo"), Success, nil).Force(context.Background()) - assert.Equal(t, permissionErrorModifyStaticProcedure(&Compound{ + assert.Equal(t, PermissionError(OperationModify, PermissionTypeStaticProcedure, &Compound{ Functor: "/", Args: []Term{ Atom("foo"), @@ -2638,7 +2638,7 @@ func TestState_Asserta(t *testing.T) { } ok, err := state.Asserta(Atom("foo"), Success, nil).Force(context.Background()) - assert.Equal(t, permissionErrorModifyStaticProcedure(&Compound{ + assert.Equal(t, PermissionError(OperationModify, PermissionTypeStaticProcedure, &Compound{ Functor: "/", Args: []Term{ Atom("foo"), @@ -2717,19 +2717,19 @@ func TestState_Assert(t *testing.T) { clause := Variable("Term") var state State - assert.Equal(t, ErrInstantiation, state.Assert(clause, nil)) + assert.Equal(t, InstantiationError(nil), state.Assert(clause, nil)) }) t.Run("clause is neither a variable, nor callable", func(t *testing.T) { var state State - assert.Equal(t, TypeErrorCallable(Integer(0), nil), state.Assert(Integer(0), nil)) + assert.Equal(t, TypeError(ValidTypeCallable, Integer(0), nil), state.Assert(Integer(0), nil)) }) t.Run("head is a variable", func(t *testing.T) { head := Variable("Head") var state State - assert.Equal(t, ErrInstantiation, state.Assert(&Compound{ + assert.Equal(t, InstantiationError(nil), state.Assert(&Compound{ Functor: ":-", Args: []Term{head, Atom("true")}, }, nil)) @@ -2737,7 +2737,7 @@ func TestState_Assert(t *testing.T) { t.Run("head is neither a variable, nor callable", func(t *testing.T) { var state State - assert.Equal(t, TypeErrorCallable(Integer(0), nil), state.Assert(&Compound{ + assert.Equal(t, TypeError(ValidTypeCallable, Integer(0), nil), state.Assert(&Compound{ Functor: ":-", Args: []Term{Integer(0), Atom("true")}, }, nil)) @@ -2745,7 +2745,7 @@ func TestState_Assert(t *testing.T) { t.Run("body contains a term which is not callable", func(t *testing.T) { var state State - assert.Equal(t, TypeErrorCallable(&Compound{ + assert.Equal(t, TypeError(ValidTypeCallable, &Compound{ Functor: ",", Args: []Term{ Atom("true"), @@ -2814,7 +2814,7 @@ func TestState_Assert(t *testing.T) { }, } - assert.Equal(t, permissionErrorModifyStaticProcedure(&Compound{ + assert.Equal(t, PermissionError(OperationModify, PermissionTypeStaticProcedure, &Compound{ Functor: "/", Args: []Term{ Atom("foo"), @@ -2902,14 +2902,14 @@ func TestState_Retract(t *testing.T) { t.Run("variable", func(t *testing.T) { var state State ok, err := state.Retract(Variable("X"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("not callable", func(t *testing.T) { var state State ok, err := state.Retract(Integer(0), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCallable(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeCallable, Integer(0), nil), err) assert.False(t, ok) }) @@ -2934,7 +2934,7 @@ func TestState_Retract(t *testing.T) { } ok, err := state.Retract(Atom("foo"), Success, nil).Force(context.Background()) - assert.Equal(t, permissionErrorModifyStaticProcedure(&Compound{ + assert.Equal(t, PermissionError(OperationModify, PermissionTypeStaticProcedure, &Compound{ Functor: "/", Args: []Term{Atom("foo"), Integer(0)}, }, nil), err) @@ -2994,7 +2994,7 @@ func TestState_Abolish(t *testing.T) { t.Run("pi is a variable", func(t *testing.T) { var state State ok, err := state.Abolish(Variable("PI"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) @@ -3005,7 +3005,7 @@ func TestState_Abolish(t *testing.T) { Functor: "/", Args: []Term{Variable("Name"), Integer(2)}, }, Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) @@ -3015,7 +3015,7 @@ func TestState_Abolish(t *testing.T) { Functor: "/", Args: []Term{Atom("foo"), Variable("Arity")}, }, Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) }) @@ -3024,14 +3024,14 @@ func TestState_Abolish(t *testing.T) { t.Run("compound", func(t *testing.T) { var state State ok, err := state.Abolish(Atom("+").Apply(Atom("foo"), Integer(1)), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorPredicateIndicator(Atom("+").Apply(Atom("foo"), Integer(1)), nil), err) + assert.Equal(t, TypeError(ValidTypePredicateIndicator, Atom("+").Apply(Atom("foo"), Integer(1)), nil), err) assert.False(t, ok) }) t.Run("not a comnpound", func(t *testing.T) { var state State ok, err := state.Abolish(Integer(0), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorPredicateIndicator(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypePredicateIndicator, Integer(0), nil), err) assert.False(t, ok) }) }) @@ -3042,7 +3042,7 @@ func TestState_Abolish(t *testing.T) { Functor: "/", Args: []Term{Integer(0), Integer(2)}, }, Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorAtom(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeAtom, Integer(0), nil), err) assert.False(t, ok) }) @@ -3052,7 +3052,7 @@ func TestState_Abolish(t *testing.T) { Functor: "/", Args: []Term{Atom("foo"), Atom("bar")}, }, Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInteger(Atom("bar"), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Atom("bar"), nil), err) assert.False(t, ok) }) @@ -3062,7 +3062,7 @@ func TestState_Abolish(t *testing.T) { Functor: "/", Args: []Term{Atom("foo"), Integer(-2)}, }, Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorNotLessThanZero(Integer(-2), nil), err) + assert.Equal(t, DomainError(ValidDomainNotLessThanZero, Integer(-2), nil), err) assert.False(t, ok) }) @@ -3078,7 +3078,7 @@ func TestState_Abolish(t *testing.T) { Functor: "/", Args: []Term{Atom("foo"), Integer(0)}, }, Success, nil).Force(context.Background()) - assert.Equal(t, permissionErrorModifyStaticProcedure(&Compound{ + assert.Equal(t, PermissionError(OperationModify, PermissionTypeStaticProcedure, &Compound{ Functor: "/", Args: []Term{Atom("foo"), Integer(0)}, }, nil), err) @@ -3101,7 +3101,7 @@ func TestState_CurrentInput(t *testing.T) { t.Run("stream is neither a variable nor a stream", func(t *testing.T) { var state State ok, err := state.CurrentInput(Integer(0), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorStream(Integer(0), nil), err) + assert.Equal(t, DomainError(ValidDomainStream, Integer(0), nil), err) assert.False(t, ok) }) } @@ -3121,7 +3121,7 @@ func TestState_CurrentOutput(t *testing.T) { t.Run("stream is neither a variable nor a stream", func(t *testing.T) { var state State ok, err := state.CurrentOutput(Integer(0), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorStream(Integer(0), nil), err) + assert.Equal(t, DomainError(ValidDomainStream, Integer(0), nil), err) assert.False(t, ok) }) } @@ -3158,21 +3158,21 @@ func TestState_SetInput(t *testing.T) { t.Run("streamOrAlias is a variable", func(t *testing.T) { var state State ok, err := state.SetInput(Variable("Stream"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("streamOrAlias is neither a variable, nor a stream term or alias", func(t *testing.T) { var state State ok, err := state.SetInput(Integer(0), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorStreamOrAlias(Integer(0), nil), err) + assert.Equal(t, DomainError(ValidDomainStreamOrAlias, Integer(0), nil), err) assert.False(t, ok) }) t.Run("streamOrAlias is not associated with an open stream", func(t *testing.T) { var state State ok, err := state.SetInput(Atom("x"), Success, nil).Force(context.Background()) - assert.Equal(t, existenceErrorStream(Atom("x"), nil), err) + assert.Equal(t, ExistenceError(ObjectTypeStream, Atom("x"), nil), err) assert.False(t, ok) }) @@ -3182,7 +3182,7 @@ func TestState_SetInput(t *testing.T) { Bind(v, NewStream(os.Stdout, StreamModeWrite)) var state State ok, err := state.SetInput(v, Success, env).Force(context.Background()) - assert.Equal(t, permissionErrorInputStream(v, env), err) + assert.Equal(t, PermissionError(OperationInput, PermissionTypeStream, v, env), err) assert.False(t, ok) }) } @@ -3216,21 +3216,21 @@ func TestState_SetOutput(t *testing.T) { t.Run("streamOrAlias is a variable", func(t *testing.T) { var state State ok, err := state.SetOutput(Variable("Stream"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("streamOrAlias is neither a variable, nor a stream term or alias", func(t *testing.T) { var state State ok, err := state.SetOutput(Integer(0), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorStreamOrAlias(Integer(0), nil), err) + assert.Equal(t, DomainError(ValidDomainStreamOrAlias, Integer(0), nil), err) assert.False(t, ok) }) t.Run("streamOrAlias is not associated with an open stream", func(t *testing.T) { var state State ok, err := state.SetOutput(Atom("x"), Success, nil).Force(context.Background()) - assert.Equal(t, existenceErrorStream(Atom("x"), nil), err) + assert.Equal(t, ExistenceError(ObjectTypeStream, Atom("x"), nil), err) assert.False(t, ok) }) @@ -3241,7 +3241,7 @@ func TestState_SetOutput(t *testing.T) { var state State ok, err := state.SetOutput(s, Success, env).Force(context.Background()) - assert.Equal(t, permissionErrorOutputStream(s, env), err) + assert.Equal(t, PermissionError(OperationOutput, PermissionTypeStream, s, env), err) assert.False(t, ok) }) } @@ -3541,14 +3541,14 @@ func TestState_Open(t *testing.T) { t.Run("sourceSink is a variable", func(t *testing.T) { var state State ok, err := state.Open(Variable("Source_Sink"), Atom("read"), Variable("Stream"), List(), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("mode is a variable", func(t *testing.T) { var state State ok, err := state.Open(Atom("/dev/null"), Variable("Mode"), Variable("Stream"), List(), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) @@ -3559,7 +3559,7 @@ func TestState_Open(t *testing.T) { &Compound{Functor: "type", Args: []Term{Atom("text")}}, &Compound{Functor: "alias", Args: []Term{Atom("foo")}}, ), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) @@ -3570,7 +3570,7 @@ func TestState_Open(t *testing.T) { &Compound{Functor: "type", Args: []Term{Atom("text")}}, &Compound{Functor: "alias", Args: []Term{Atom("foo")}}, ), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) }) @@ -3578,42 +3578,42 @@ func TestState_Open(t *testing.T) { t.Run("mode is neither a variable nor an atom", func(t *testing.T) { var state State ok, err := state.Open(Atom("/dev/null"), Integer(0), Variable("Stream"), List(), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorAtom(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeAtom, Integer(0), nil), err) assert.False(t, ok) }) t.Run("options is neither a partial list nor a list", func(t *testing.T) { var state State ok, err := state.Open(Atom("/dev/null"), Atom("read"), Variable("Stream"), Atom("list"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorList(Atom("list"), nil), err) + assert.Equal(t, TypeError(ValidTypeList, Atom("list"), nil), err) assert.False(t, ok) }) t.Run("stream is not a variable", func(t *testing.T) { var state State ok, err := state.Open(Atom("/dev/null"), Atom("read"), Atom("stream"), List(), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("sourceSink is neither a variable nor a source/sink", func(t *testing.T) { var state State ok, err := state.Open(Integer(0), Atom("read"), Variable("Stream"), List(), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorSourceSink(Integer(0), nil), err) + assert.Equal(t, DomainError(ValidDomainSourceSink, Integer(0), nil), err) assert.False(t, ok) }) t.Run("mode is an atom but not an input/output mode", func(t *testing.T) { var state State ok, err := state.Open(Atom("/dev/null"), Atom("foo"), Variable("Stream"), List(), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorIOMode(Atom("foo"), nil), err) + assert.Equal(t, DomainError(ValidDomainIOMode, Atom("foo"), nil), err) assert.False(t, ok) }) t.Run("an element E of the options list is neither a variable nor a stream-option", func(t *testing.T) { var state State ok, err := state.Open(Atom("/dev/null"), Atom("read"), Variable("Stream"), List(Atom("foo")), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorStreamOption(Atom("foo"), nil), err) + assert.Equal(t, DomainError(ValidDomainStreamOption, Atom("foo"), nil), err) assert.False(t, ok) }) @@ -3624,7 +3624,7 @@ func TestState_Open(t *testing.T) { var state State ok, err := state.Open(Atom(f.Name()), Atom("read"), Variable("Stream"), List(), Success, nil).Force(context.Background()) - assert.Equal(t, existenceErrorSourceSink(Atom(f.Name()), nil), err) + assert.Equal(t, ExistenceError(ObjectTypeSourceSink, Atom(f.Name()), nil), err) assert.False(t, ok) }) @@ -3639,7 +3639,7 @@ func TestState_Open(t *testing.T) { var state State ok, err := state.Open(Atom(f.Name()), Atom("read"), Variable("Stream"), List(), Success, nil).Force(context.Background()) - assert.Equal(t, PermissionError("open", "source_sink", Atom(f.Name()), nil), err) + assert.Equal(t, PermissionError(OperationOpen, PermissionTypeSourceSink, Atom(f.Name()), nil), err) assert.False(t, ok) }) @@ -3659,7 +3659,7 @@ func TestState_Open(t *testing.T) { Functor: "alias", Args: []Term{Atom("foo")}, }), Success, nil).Force(context.Background()) - assert.Equal(t, PermissionError("open", "source_sink", &Compound{ + assert.Equal(t, PermissionError(OperationOpen, PermissionTypeSourceSink, &Compound{ Functor: "alias", Args: []Term{Atom("foo")}, }, nil), err) @@ -3735,7 +3735,7 @@ func TestState_Close(t *testing.T) { Functor: "force", Args: []Term{Atom("false")}, }), Success, nil).Force(context.Background()) - assert.Equal(t, resourceError(s, Atom("ng"), nil), err) + assert.Equal(t, SystemError(errors.New("ng")), err) assert.False(t, ok) }) }) @@ -3795,7 +3795,7 @@ func TestState_Close(t *testing.T) { t.Run("streamOrAlias ia a variable", func(t *testing.T) { var state State ok, err := state.Close(Variable("Stream"), List(), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) @@ -3805,14 +3805,14 @@ func TestState_Close(t *testing.T) { ok, err := state.Close(&Stream{}, ListRest(Variable("Rest"), &Compound{Functor: "force", Args: []Term{Atom("true")}}, ), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("variable element", func(t *testing.T) { var state State ok, err := state.Close(&Stream{}, List(Variable("Option"), &Compound{Functor: "force", Args: []Term{Atom("true")}}), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) }) @@ -3820,14 +3820,14 @@ func TestState_Close(t *testing.T) { t.Run("options is neither a partial list nor a list", func(t *testing.T) { var state State ok, err := state.Close(&Stream{}, Atom("foo"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorList(Atom("foo"), nil), err) + assert.Equal(t, TypeError(ValidTypeList, Atom("foo"), nil), err) assert.False(t, ok) }) t.Run("streamOrAlias is neither a variable nor a stream-term or alias", func(t *testing.T) { var state State ok, err := state.Close(Integer(0), List(), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorStreamOrAlias(Integer(0), nil), err) + assert.Equal(t, DomainError(ValidDomainStreamOrAlias, Integer(0), nil), err) assert.False(t, ok) }) @@ -3835,7 +3835,7 @@ func TestState_Close(t *testing.T) { t.Run("not a compound", func(t *testing.T) { var state State ok, err := state.Close(&Stream{}, List(Atom("foo")), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorStreamOption(Atom("foo"), nil), err) + assert.Equal(t, DomainError(ValidDomainStreamOption, Atom("foo"), nil), err) assert.False(t, ok) }) @@ -3843,21 +3843,21 @@ func TestState_Close(t *testing.T) { t.Run("force but arity is not 1", func(t *testing.T) { var state State ok, err := state.Close(&Stream{}, List(Atom("force").Apply(Atom("a"), Atom("b"))), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorStreamOption(Atom("force").Apply(Atom("a"), Atom("b")), nil), err) + assert.Equal(t, DomainError(ValidDomainStreamOption, Atom("force").Apply(Atom("a"), Atom("b")), nil), err) assert.False(t, ok) }) t.Run("force but the argument is a variable", func(t *testing.T) { var state State _, err := state.Close(&Stream{}, List(Atom("force").Apply(Variable("X"))), Success, nil).Force(context.Background()) - _, ok := domainErrorStreamOption(Atom("force").Apply(NewVariable()), nil).term.Unify(err.(*Exception).term, false, nil) + _, ok := DomainError(ValidDomainStreamOption, Atom("force").Apply(NewVariable()), nil).term.Unify(err.(Exception).term, false, nil) assert.True(t, ok) }) t.Run("force but the argument is neither true nor false", func(t *testing.T) { var state State ok, err := state.Close(&Stream{}, List(Atom("force").Apply(Atom("meh"))), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorStreamOption(Atom("force").Apply(Atom("meh")), nil), err) + assert.Equal(t, DomainError(ValidDomainStreamOption, Atom("force").Apply(Atom("meh")), nil), err) assert.False(t, ok) }) }) @@ -3866,7 +3866,7 @@ func TestState_Close(t *testing.T) { t.Run("streamOrAlias is not associated with an open stream", func(t *testing.T) { var state State ok, err := state.Close(Atom("foo"), List(), Success, nil).Force(context.Background()) - assert.Equal(t, existenceErrorStream(Atom("foo"), nil), err) + assert.Equal(t, ExistenceError(ObjectTypeStream, Atom("foo"), nil), err) assert.False(t, ok) }) } @@ -3918,21 +3918,21 @@ func TestState_FlushOutput(t *testing.T) { t.Run("streamOrAlias is a variable", func(t *testing.T) { var state State ok, err := state.FlushOutput(Variable("Stream"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("streamOrAlias is neither a variable nor a stream-term or alias", func(t *testing.T) { var state State ok, err := state.FlushOutput(Integer(0), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorStreamOrAlias(Integer(0), nil), err) + assert.Equal(t, DomainError(ValidDomainStreamOrAlias, Integer(0), nil), err) assert.False(t, ok) }) t.Run("streamOrAlias is not associated with an open stream", func(t *testing.T) { var state State ok, err := state.FlushOutput(Atom("foo"), Success, nil).Force(context.Background()) - assert.Equal(t, existenceErrorStream(Atom("foo"), nil), err) + assert.Equal(t, ExistenceError(ObjectTypeStream, Atom("foo"), nil), err) assert.False(t, ok) }) @@ -3941,7 +3941,7 @@ func TestState_FlushOutput(t *testing.T) { var state State ok, err := state.FlushOutput(s, Success, nil).Force(context.Background()) - assert.Equal(t, permissionErrorOutputStream(s, nil), err) + assert.Equal(t, PermissionError(OperationOutput, PermissionTypeStream, s, nil), err) assert.False(t, ok) }) } @@ -4017,7 +4017,7 @@ func TestState_WriteTerm(t *testing.T) { Functor: "quoted", Args: []Term{Atom("meh")}, }), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorWriteOption(&Compound{ + assert.Equal(t, DomainError(ValidDomainWriteOption, &Compound{ Functor: "quoted", Args: []Term{Atom("meh")}, }, nil), err) @@ -4031,7 +4031,7 @@ func TestState_WriteTerm(t *testing.T) { Functor: "quoted", Args: []Term{Variable("Bool")}, }), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) }) t.Run("not an atom", func(t *testing.T) { @@ -4042,7 +4042,7 @@ func TestState_WriteTerm(t *testing.T) { Functor: "quoted", Args: []Term{Integer(0)}, }), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorWriteOption(&Compound{ + assert.Equal(t, DomainError(ValidDomainWriteOption, &Compound{ Functor: "quoted", Args: []Term{Integer(0)}, }, nil), err) @@ -4090,7 +4090,7 @@ func TestState_WriteTerm(t *testing.T) { Functor: "ignore_ops", Args: []Term{Atom("meh")}, }), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorWriteOption(&Compound{ + assert.Equal(t, DomainError(ValidDomainWriteOption, &Compound{ Functor: "ignore_ops", Args: []Term{Atom("meh")}, }, nil), err) @@ -4104,7 +4104,7 @@ func TestState_WriteTerm(t *testing.T) { Functor: "ignore_ops", Args: []Term{Variable("Bool")}, }), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) }) t.Run("not an atom", func(t *testing.T) { @@ -4115,7 +4115,7 @@ func TestState_WriteTerm(t *testing.T) { Functor: "ignore_ops", Args: []Term{Integer(0)}, }), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorWriteOption(&Compound{ + assert.Equal(t, DomainError(ValidDomainWriteOption, &Compound{ Functor: "ignore_ops", Args: []Term{Integer(0)}, }, nil), err) @@ -4156,9 +4156,9 @@ func TestState_WriteTerm(t *testing.T) { Args: []Term{Atom("=").Apply(Atom("foo"), Variable("X"))}, }), Success, nil).Force(context.Background()) assert.Error(t, err) - e, ok := err.(*Exception) + e, ok := err.(Exception) assert.True(t, ok) - _, ok = e.term.Unify(domainErrorWriteOption(&Compound{ + _, ok = e.term.Unify(DomainError(ValidDomainWriteOption, &Compound{ Functor: "variable_names", Args: []Term{Atom("=").Apply(Atom("foo"), Variable("X"))}, }, nil).term, false, nil) @@ -4175,7 +4175,7 @@ func TestState_WriteTerm(t *testing.T) { Atom("foo"), )}, }), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorWriteOption(&Compound{ + assert.Equal(t, DomainError(ValidDomainWriteOption, &Compound{ Functor: "variable_names", Args: []Term{List( Atom("foo"), @@ -4193,9 +4193,9 @@ func TestState_WriteTerm(t *testing.T) { Atom("=").Apply(Integer(0), Variable("X")), )}, }), Success, nil).Force(context.Background()) - e, ok := err.(*Exception) + e, ok := err.(Exception) assert.True(t, ok) - _, ok = e.term.Unify(domainErrorWriteOption(&Compound{ + _, ok = e.term.Unify(DomainError(ValidDomainWriteOption, &Compound{ Functor: "variable_names", Args: []Term{List( Atom("=").Apply(Integer(0), Variable("X")), @@ -4214,7 +4214,7 @@ func TestState_WriteTerm(t *testing.T) { Atom("=").Apply(Atom("foo"), Integer(0)), )}, }), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorWriteOption(&Compound{ + assert.Equal(t, DomainError(ValidDomainWriteOption, &Compound{ Functor: "variable_names", Args: []Term{List( Atom("=").Apply(Atom("foo"), Integer(0)), @@ -4266,7 +4266,7 @@ func TestState_WriteTerm(t *testing.T) { Functor: "numbervars", Args: []Term{Atom("meh")}, }), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorWriteOption(&Compound{ + assert.Equal(t, DomainError(ValidDomainWriteOption, &Compound{ Functor: "numbervars", Args: []Term{Atom("meh")}, }, nil), err) @@ -4280,7 +4280,7 @@ func TestState_WriteTerm(t *testing.T) { Functor: "numbervars", Args: []Term{Variable("Bool")}, }), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) }) t.Run("not an atom", func(t *testing.T) { @@ -4291,7 +4291,7 @@ func TestState_WriteTerm(t *testing.T) { Functor: "numbervars", Args: []Term{Integer(0)}, }), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorWriteOption(&Compound{ + assert.Equal(t, DomainError(ValidDomainWriteOption, &Compound{ Functor: "numbervars", Args: []Term{Integer(0)}, }, nil), err) @@ -4301,7 +4301,7 @@ func TestState_WriteTerm(t *testing.T) { t.Run("streamOrAlias is a variable", func(t *testing.T) { var state State ok, err := state.WriteTerm(Variable("Stream"), Atom("foo"), List(), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) @@ -4311,14 +4311,14 @@ func TestState_WriteTerm(t *testing.T) { ok, err := state.WriteTerm(s, Atom("foo"), ListRest(Variable("Rest"), &Compound{Functor: "quoted", Args: []Term{Atom("true")}}, ), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("variable element", func(t *testing.T) { var state State ok, err := state.WriteTerm(s, Atom("foo"), List(Variable("Option"), &Compound{Functor: "quoted", Args: []Term{Atom("true")}}), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) }) @@ -4326,14 +4326,14 @@ func TestState_WriteTerm(t *testing.T) { t.Run("streamOrAlias is neither a variable nor a stream term or alias", func(t *testing.T) { var state State ok, err := state.WriteTerm(Integer(0), Atom("foo"), List(), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorStreamOrAlias(Integer(0), nil), err) + assert.Equal(t, DomainError(ValidDomainStreamOrAlias, Integer(0), nil), err) assert.False(t, ok) }) t.Run("options is neither a partial list nor a list", func(t *testing.T) { var state State ok, err := state.WriteTerm(s, Atom("foo"), Atom("options"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorList(Atom("options"), nil), err) + assert.Equal(t, TypeError(ValidTypeList, Atom("options"), nil), err) assert.False(t, ok) }) @@ -4341,7 +4341,7 @@ func TestState_WriteTerm(t *testing.T) { t.Run("atom", func(t *testing.T) { var state State ok, err := state.WriteTerm(s, Atom("foo"), List(Atom("option")), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorWriteOption(Atom("option"), nil), err) + assert.Equal(t, DomainError(ValidDomainWriteOption, Atom("option"), nil), err) assert.False(t, ok) }) @@ -4351,7 +4351,7 @@ func TestState_WriteTerm(t *testing.T) { Functor: "unknown", Args: []Term{Atom("foo"), Atom("bar")}, }), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorWriteOption(&Compound{ + assert.Equal(t, DomainError(ValidDomainWriteOption, &Compound{ Functor: "unknown", Args: []Term{Atom("foo"), Atom("bar")}, }, nil), err) @@ -4364,7 +4364,7 @@ func TestState_WriteTerm(t *testing.T) { Functor: "unknown", Args: []Term{Atom("true")}, }), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorWriteOption(&Compound{ + assert.Equal(t, DomainError(ValidDomainWriteOption, &Compound{ Functor: "unknown", Args: []Term{Atom("true")}, }, nil), err) @@ -4375,7 +4375,7 @@ func TestState_WriteTerm(t *testing.T) { t.Run("streamOrAlias is not associated with an open stream", func(t *testing.T) { var state State ok, err := state.WriteTerm(Atom("stream"), Atom("foo"), List(), Success, nil).Force(context.Background()) - assert.Equal(t, existenceErrorStream(Atom("stream"), nil), err) + assert.Equal(t, ExistenceError(ObjectTypeStream, Atom("stream"), nil), err) assert.False(t, ok) }) @@ -4384,7 +4384,7 @@ func TestState_WriteTerm(t *testing.T) { var state State ok, err := state.WriteTerm(s, Atom("foo"), List(), Success, nil).Force(context.Background()) - assert.Equal(t, permissionErrorOutputStream(s, nil), err) + assert.Equal(t, PermissionError(OperationOutput, PermissionTypeStream, s, nil), err) assert.False(t, ok) }) @@ -4394,7 +4394,7 @@ func TestState_WriteTerm(t *testing.T) { var state State ok, err := state.WriteTerm(s, Atom("foo"), List(), Success, nil).Force(context.Background()) - assert.Equal(t, permissionErrorOutputBinaryStream(s, nil), err) + assert.Equal(t, PermissionError(OperationOutput, PermissionTypeBinaryStream, s, nil), err) assert.False(t, ok) }) @@ -4478,20 +4478,20 @@ func TestCharCode(t *testing.T) { char, code := Variable("Char"), Variable("Code") ok, err := CharCode(char, code, Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("char is neither a variable nor a one character atom", func(t *testing.T) { t.Run("atom", func(t *testing.T) { ok, err := CharCode(Atom("foo"), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCharacter(Atom("foo"), nil), err) + assert.Equal(t, TypeError(ValidTypeCharacter, Atom("foo"), nil), err) assert.False(t, ok) }) t.Run("non-atom", func(t *testing.T) { ok, err := CharCode(Integer(0), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCharacter(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeCharacter, Integer(0), nil), err) assert.False(t, ok) }) }) @@ -4499,20 +4499,20 @@ func TestCharCode(t *testing.T) { t.Run("code is neither a variable nor an integer", func(t *testing.T) { t.Run("char is variable", func(t *testing.T) { ok, err := CharCode(NewVariable(), Atom("foo"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInteger(Atom("foo"), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Atom("foo"), nil), err) assert.False(t, ok) }) t.Run("char is a character", func(t *testing.T) { ok, err := CharCode(Atom("a"), Atom("x"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInteger(Atom("x"), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Atom("x"), nil), err) assert.False(t, ok) }) }) t.Run("code is neither a variable nor a character-code", func(t *testing.T) { ok, err := CharCode(NewVariable(), Integer(-1), Success, nil).Force(context.Background()) - assert.Equal(t, representationError("character_code"), err) + assert.Equal(t, RepresentationError(FlagCharacterCode, nil), err) assert.False(t, ok) }) } @@ -4578,7 +4578,7 @@ func TestState_PutByte(t *testing.T) { t.Run("streamOrAlias is a variable", func(t *testing.T) { var state State ok, err := state.PutByte(Variable("Stream"), Integer(97), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) @@ -4588,7 +4588,7 @@ func TestState_PutByte(t *testing.T) { var state State ok, err := state.PutByte(s, Variable("Byte"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) @@ -4599,14 +4599,14 @@ func TestState_PutByte(t *testing.T) { t.Run("not even an integer", func(t *testing.T) { var state State ok, err := state.PutByte(s, Atom("byte"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorByte(Atom("byte"), nil), err) + assert.Equal(t, TypeError(ValidTypeByte, Atom("byte"), nil), err) assert.False(t, ok) }) t.Run("integer", func(t *testing.T) { var state State ok, err := state.PutByte(s, Integer(256), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorByte(Integer(256), nil), err) + assert.Equal(t, TypeError(ValidTypeByte, Integer(256), nil), err) assert.False(t, ok) }) }) @@ -4614,7 +4614,7 @@ func TestState_PutByte(t *testing.T) { t.Run("streamOrAlias is neither a variable nor a stream term or alias", func(t *testing.T) { var state State ok, err := state.PutByte(Integer(0), Integer(97), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorStreamOrAlias(Integer(0), nil), err) + assert.Equal(t, DomainError(ValidDomainStreamOrAlias, Integer(0), nil), err) assert.False(t, ok) }) @@ -4625,7 +4625,7 @@ func TestState_PutByte(t *testing.T) { var state State ok, err := state.PutByte(s, Integer(97), Success, env).Force(context.Background()) - assert.Equal(t, permissionErrorOutputStream(s, env), err) + assert.Equal(t, PermissionError(OperationOutput, PermissionTypeStream, s, env), err) assert.False(t, ok) }) @@ -4636,7 +4636,7 @@ func TestState_PutByte(t *testing.T) { var state State ok, err := state.PutByte(s, Integer(97), Success, env).Force(context.Background()) - assert.Equal(t, permissionErrorOutputTextStream(s, env), err) + assert.Equal(t, PermissionError(OperationOutput, PermissionTypeTextStream, s, env), err) assert.False(t, ok) }) } @@ -4699,35 +4699,35 @@ func TestState_PutCode(t *testing.T) { t.Run("streamOrAlias is a variable", func(t *testing.T) { var state State ok, err := state.PutCode(Variable("Stream"), Integer(97), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("code is a variable", func(t *testing.T) { var state State ok, err := state.PutCode(NewStream(os.Stdout, StreamModeWrite), Variable("Code"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("code is neither a variable nor an integer", func(t *testing.T) { var state State ok, err := state.PutCode(NewStream(os.Stdout, StreamModeWrite), Atom("code"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInteger(Atom("code"), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Atom("code"), nil), err) assert.False(t, ok) }) t.Run("streamOrAlias is neither a variable nor a stream term or alias", func(t *testing.T) { var state State ok, err := state.PutCode(Integer(0), Integer(97), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorStreamOrAlias(Integer(0), nil), err) + assert.Equal(t, DomainError(ValidDomainStreamOrAlias, Integer(0), nil), err) assert.False(t, ok) }) t.Run("streamOrAlias is not associated with an open stream", func(t *testing.T) { var state State ok, err := state.PutCode(Atom("foo"), Integer(97), Success, nil).Force(context.Background()) - assert.Equal(t, existenceErrorStream(Atom("foo"), nil), err) + assert.Equal(t, ExistenceError(ObjectTypeStream, Atom("foo"), nil), err) assert.False(t, ok) }) @@ -4738,7 +4738,7 @@ func TestState_PutCode(t *testing.T) { var state State ok, err := state.PutCode(s, Integer(97), Success, env).Force(context.Background()) - assert.Equal(t, permissionErrorOutputStream(s, env), err) + assert.Equal(t, PermissionError(OperationOutput, PermissionTypeStream, s, env), err) assert.False(t, ok) }) @@ -4752,14 +4752,14 @@ func TestState_PutCode(t *testing.T) { var state State ok, err := state.PutCode(s, Integer(97), Success, env).Force(context.Background()) - assert.Equal(t, permissionErrorOutputBinaryStream(s, env), err) + assert.Equal(t, PermissionError(OperationOutput, PermissionTypeBinaryStream, s, env), err) assert.False(t, ok) }) t.Run("code is an integer but not an character code", func(t *testing.T) { var state State ok, err := state.PutCode(NewStream(os.Stdout, StreamModeWrite), Integer(-1), Success, nil).Force(context.Background()) - assert.Equal(t, representationError("character_code"), err) + assert.Equal(t, RepresentationError(FlagCharacterCode, nil), err) assert.False(t, ok) }) @@ -4974,7 +4974,7 @@ func TestState_ReadTerm(t *testing.T) { t.Run("streamOrAlias is a variable", func(t *testing.T) { var state State ok, err := state.ReadTerm(Variable("Stream"), NewVariable(), List(), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) @@ -4984,14 +4984,14 @@ func TestState_ReadTerm(t *testing.T) { ok, err := state.ReadTerm(NewStream(os.Stdin, StreamModeRead), NewVariable(), ListRest(Variable("Rest"), &Compound{Functor: "variables", Args: []Term{Variable("VL")}}, ), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("variable element", func(t *testing.T) { var state State ok, err := state.ReadTerm(NewStream(os.Stdin, StreamModeRead), NewVariable(), List(Variable("Option"), &Compound{Functor: "variables", Args: []Term{Variable("VL")}}), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) }) @@ -4999,14 +4999,14 @@ func TestState_ReadTerm(t *testing.T) { t.Run("streamOrAlias is neither a variable nor a stream term or alias", func(t *testing.T) { var state State ok, err := state.ReadTerm(Integer(0), NewVariable(), List(), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorStreamOrAlias(Integer(0), nil), err) + assert.Equal(t, DomainError(ValidDomainStreamOrAlias, Integer(0), nil), err) assert.False(t, ok) }) t.Run("options is neither a partial list nor a list", func(t *testing.T) { var state State ok, err := state.ReadTerm(NewStream(os.Stdin, StreamModeRead), NewVariable(), Atom("options"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorList(Atom("options"), nil), err) + assert.Equal(t, TypeError(ValidTypeList, Atom("options"), nil), err) assert.False(t, ok) }) @@ -5016,7 +5016,7 @@ func TestState_ReadTerm(t *testing.T) { Functor: "unknown", Args: []Term{Atom("option")}, }), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorReadOption(&Compound{ + assert.Equal(t, DomainError(ValidDomainReadOption, &Compound{ Functor: "unknown", Args: []Term{Atom("option")}, }, nil), err) @@ -5026,7 +5026,7 @@ func TestState_ReadTerm(t *testing.T) { t.Run("streamOrAlias is not associated with an open stream", func(t *testing.T) { var state State ok, err := state.ReadTerm(Atom("foo"), NewVariable(), List(), Success, nil).Force(context.Background()) - assert.Equal(t, existenceErrorStream(Atom("foo"), nil), err) + assert.Equal(t, ExistenceError(ObjectTypeStream, Atom("foo"), nil), err) assert.False(t, ok) }) @@ -5037,7 +5037,7 @@ func TestState_ReadTerm(t *testing.T) { var state State ok, err := state.ReadTerm(s, NewVariable(), List(), Success, env).Force(context.Background()) - assert.Equal(t, permissionErrorInputStream(s, env), err) + assert.Equal(t, PermissionError(OperationInput, PermissionTypeStream, s, env), err) assert.False(t, ok) }) @@ -5051,7 +5051,7 @@ func TestState_ReadTerm(t *testing.T) { var state State ok, err := state.ReadTerm(s, NewVariable(), List(), Success, env).Force(context.Background()) - assert.Equal(t, permissionErrorInputBinaryStream(s, env), err) + assert.Equal(t, PermissionError(OperationInput, PermissionTypeBinaryStream, s, env), err) assert.False(t, ok) }) @@ -5070,7 +5070,7 @@ func TestState_ReadTerm(t *testing.T) { var state State ok, err := state.ReadTerm(s, NewVariable(), List(), Success, env).Force(context.Background()) - assert.Equal(t, permissionErrorInputPastEndOfStream(s, env), err) + assert.Equal(t, PermissionError(OperationInput, PermissionTypePastEndOfStream, s, env), err) assert.False(t, ok) }) @@ -5084,7 +5084,9 @@ func TestState_ReadTerm(t *testing.T) { var state State ok, err := state.ReadTerm(s, NewVariable(), List(), Success, nil).Force(context.Background()) - assert.Equal(t, syntaxErrorUnexpectedToken(Atom("unexpected token: ")), err) + assert.Equal(t, SyntaxError(&unexpectedTokenError{ + Actual: Token{Kind: TokenIdent, Val: "bar"}, + }, nil), err) assert.False(t, ok) }) @@ -5097,7 +5099,7 @@ func TestState_ReadTerm(t *testing.T) { var state State ok, err := state.ReadTerm(s, NewVariable(), List(), Success, nil).Force(context.Background()) - assert.Equal(t, syntaxErrorInsufficient(), err) + assert.Equal(t, SyntaxError(ErrInsufficient, nil), err) assert.False(t, ok) }) @@ -5112,7 +5114,9 @@ func TestState_ReadTerm(t *testing.T) { var state State ok, err := state.ReadTerm(s, NewVariable(), List(), Success, nil).Force(context.Background()) - assert.Equal(t, syntaxErrorUnexpectedToken(Atom("unexpected token: ")), err) + assert.Equal(t, SyntaxError(&unexpectedTokenError{ + Actual: Token{Kind: TokenGraphic, Val: "="}, + }, nil), err) assert.False(t, ok) }) } @@ -5200,7 +5204,7 @@ func TestState_GetByte(t *testing.T) { t.Run("streamOrAlias is a variable", func(t *testing.T) { var state State ok, err := state.GetByte(Variable("Stream"), Variable("InByte"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) @@ -5211,14 +5215,14 @@ func TestState_GetByte(t *testing.T) { t.Run("not even an integer", func(t *testing.T) { var state State ok, err := state.GetByte(s, Atom("inByte"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInByte(Atom("inByte"), nil), err) + assert.Equal(t, TypeError(ValidTypeInByte, Atom("inByte"), nil), err) assert.False(t, ok) }) t.Run("integer", func(t *testing.T) { var state State ok, err := state.GetByte(s, Integer(256), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInByte(Integer(256), nil), err) + assert.Equal(t, TypeError(ValidTypeInByte, Integer(256), nil), err) assert.False(t, ok) }) }) @@ -5226,14 +5230,14 @@ func TestState_GetByte(t *testing.T) { t.Run("streamOrAlias is neither a variable nor a stream-term or alias", func(t *testing.T) { var state State ok, err := state.GetByte(Integer(0), Variable("InByte"), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorStreamOrAlias(Integer(0), nil), err) + assert.Equal(t, DomainError(ValidDomainStreamOrAlias, Integer(0), nil), err) assert.False(t, ok) }) t.Run("streamOrAlias is not associated with an open stream", func(t *testing.T) { var state State ok, err := state.GetByte(Atom("foo"), Variable("InByte"), Success, nil).Force(context.Background()) - assert.Equal(t, existenceErrorStream(Atom("foo"), nil), err) + assert.Equal(t, ExistenceError(ObjectTypeStream, Atom("foo"), nil), err) assert.False(t, ok) }) @@ -5244,7 +5248,7 @@ func TestState_GetByte(t *testing.T) { var state State ok, err := state.GetByte(streamOrAlias, Variable("InByte"), Success, env).Force(context.Background()) - assert.Equal(t, permissionErrorInputStream(streamOrAlias, env), err) + assert.Equal(t, PermissionError(OperationInput, PermissionTypeStream, streamOrAlias, env), err) assert.False(t, ok) }) @@ -5255,7 +5259,7 @@ func TestState_GetByte(t *testing.T) { var state State ok, err := state.GetByte(streamOrAlias, Variable("InByte"), Success, env).Force(context.Background()) - assert.Equal(t, permissionErrorInputTextStream(streamOrAlias, env), err) + assert.Equal(t, PermissionError(OperationInput, PermissionTypeTextStream, streamOrAlias, env), err) assert.False(t, ok) }) @@ -5275,7 +5279,7 @@ func TestState_GetByte(t *testing.T) { var state State ok, err := state.GetByte(streamOrAlias, Variable("InByte"), Success, env).Force(context.Background()) - assert.Equal(t, permissionErrorInputPastEndOfStream(streamOrAlias, env), err) + assert.Equal(t, PermissionError(OperationInput, PermissionTypePastEndOfStream, streamOrAlias, env), err) assert.False(t, ok) }) } @@ -5358,7 +5362,7 @@ func TestState_GetChar(t *testing.T) { t.Run("streamOrAlias is a variable", func(t *testing.T) { var state State ok, err := state.GetChar(Variable("Stream"), Variable("Char"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) @@ -5366,14 +5370,14 @@ func TestState_GetChar(t *testing.T) { t.Run("not even an atom", func(t *testing.T) { var state State ok, err := state.GetChar(NewStream(os.Stdin, StreamModeRead), Integer(0), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInCharacter(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeInCharacter, Integer(0), nil), err) assert.False(t, ok) }) t.Run("atom", func(t *testing.T) { var state State ok, err := state.GetChar(NewStream(os.Stdin, StreamModeRead), Atom("ab"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInCharacter(Atom("ab"), nil), err) + assert.Equal(t, TypeError(ValidTypeInCharacter, Atom("ab"), nil), err) assert.False(t, ok) }) }) @@ -5381,7 +5385,7 @@ func TestState_GetChar(t *testing.T) { t.Run("streamOrAlias is neither a variable nor a stream term or alias", func(t *testing.T) { var state State ok, err := state.GetChar(Integer(0), Variable("Char"), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorStreamOrAlias(Integer(0), nil), err) + assert.Equal(t, DomainError(ValidDomainStreamOrAlias, Integer(0), nil), err) assert.False(t, ok) }) @@ -5392,7 +5396,7 @@ func TestState_GetChar(t *testing.T) { var state State ok, err := state.GetChar(streamOrAlias, Variable("Char"), Success, env).Force(context.Background()) - assert.Equal(t, permissionErrorInputStream(streamOrAlias, env), err) + assert.Equal(t, PermissionError(OperationInput, PermissionTypeStream, streamOrAlias, env), err) assert.False(t, ok) }) @@ -5406,7 +5410,7 @@ func TestState_GetChar(t *testing.T) { var state State ok, err := state.GetChar(streamOrAlias, Variable("Char"), Success, env).Force(context.Background()) - assert.Equal(t, permissionErrorInputBinaryStream(streamOrAlias, env), err) + assert.Equal(t, PermissionError(OperationInput, PermissionTypeBinaryStream, streamOrAlias, env), err) assert.False(t, ok) }) @@ -5425,7 +5429,7 @@ func TestState_GetChar(t *testing.T) { var state State ok, err := state.GetChar(streamOrAlias, Variable("Char"), Success, env).Force(context.Background()) - assert.Equal(t, permissionErrorInputPastEndOfStream(streamOrAlias, env), err) + assert.Equal(t, PermissionError(OperationInput, PermissionTypePastEndOfStream, streamOrAlias, env), err) assert.False(t, ok) }) @@ -5442,7 +5446,7 @@ func TestState_GetChar(t *testing.T) { var state State ok, err := state.GetChar(streamOrAlias, Variable("Char"), Success, env).Force(context.Background()) - assert.Equal(t, representationError("character"), err) + assert.Equal(t, RepresentationError(FlagCharacter, nil), err) assert.False(t, ok) }) } @@ -5536,7 +5540,7 @@ func TestState_PeekByte(t *testing.T) { t.Run("streamOrAlias is a variable", func(t *testing.T) { var state State ok, err := state.PeekByte(Variable("Stream"), Variable("Byte"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) @@ -5547,14 +5551,14 @@ func TestState_PeekByte(t *testing.T) { t.Run("not even an integer", func(t *testing.T) { var state State ok, err := state.PeekByte(s, Atom("byte"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInByte(Atom("byte"), nil), err) + assert.Equal(t, TypeError(ValidTypeInByte, Atom("byte"), nil), err) assert.False(t, ok) }) t.Run("integer", func(t *testing.T) { var state State ok, err := state.PeekByte(s, Integer(256), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInByte(Integer(256), nil), err) + assert.Equal(t, TypeError(ValidTypeInByte, Integer(256), nil), err) assert.False(t, ok) }) }) @@ -5562,7 +5566,7 @@ func TestState_PeekByte(t *testing.T) { t.Run("streamOrAlias is neither a variable nor a stream term or alias", func(t *testing.T) { var state State ok, err := state.PeekByte(Integer(0), Variable("Byte"), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorStreamOrAlias(Integer(0), nil), err) + assert.Equal(t, DomainError(ValidDomainStreamOrAlias, Integer(0), nil), err) assert.False(t, ok) }) @@ -5573,7 +5577,7 @@ func TestState_PeekByte(t *testing.T) { var state State ok, err := state.PeekByte(streamOrAlias, Variable("Byte"), Success, env).Force(context.Background()) - assert.Equal(t, permissionErrorInputStream(streamOrAlias, env), err) + assert.Equal(t, PermissionError(OperationInput, PermissionTypeStream, streamOrAlias, env), err) assert.False(t, ok) }) @@ -5584,7 +5588,7 @@ func TestState_PeekByte(t *testing.T) { var state State ok, err := state.PeekByte(streamOrAlias, Variable("Byte"), Success, env).Force(context.Background()) - assert.Equal(t, permissionErrorInputTextStream(streamOrAlias, env), err) + assert.Equal(t, PermissionError(OperationInput, PermissionTypeTextStream, streamOrAlias, env), err) assert.False(t, ok) }) @@ -5604,7 +5608,7 @@ func TestState_PeekByte(t *testing.T) { var state State ok, err := state.PeekByte(streamOrAlias, Variable("Byte"), Success, env).Force(context.Background()) - assert.Equal(t, permissionErrorInputPastEndOfStream(streamOrAlias, env), err) + assert.Equal(t, PermissionError(OperationInput, PermissionTypePastEndOfStream, streamOrAlias, env), err) assert.False(t, ok) }) } @@ -5718,7 +5722,7 @@ func TestState_PeekChar(t *testing.T) { t.Run("streamOrAlias is a variable", func(t *testing.T) { var state State ok, err := state.PeekChar(Variable("Stream"), Variable("Char"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) @@ -5726,14 +5730,14 @@ func TestState_PeekChar(t *testing.T) { t.Run("not even an atom", func(t *testing.T) { var state State ok, err := state.PeekChar(NewStream(os.Stdin, StreamModeRead), Integer(0), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInCharacter(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeInCharacter, Integer(0), nil), err) assert.False(t, ok) }) t.Run("atom", func(t *testing.T) { var state State ok, err := state.PeekChar(NewStream(os.Stdin, StreamModeRead), Atom("ab"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInCharacter(Atom("ab"), nil), err) + assert.Equal(t, TypeError(ValidTypeInCharacter, Atom("ab"), nil), err) assert.False(t, ok) }) }) @@ -5741,7 +5745,7 @@ func TestState_PeekChar(t *testing.T) { t.Run("streamOrAlias is neither a variable nor a stream term or alias", func(t *testing.T) { var state State ok, err := state.PeekChar(Integer(0), Variable("Char"), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorStreamOrAlias(Integer(0), nil), err) + assert.Equal(t, DomainError(ValidDomainStreamOrAlias, Integer(0), nil), err) assert.False(t, ok) }) @@ -5752,7 +5756,7 @@ func TestState_PeekChar(t *testing.T) { var state State ok, err := state.PeekChar(streamOrAlias, Variable("Char"), Success, env).Force(context.Background()) - assert.Equal(t, permissionErrorInputStream(streamOrAlias, env), err) + assert.Equal(t, PermissionError(OperationInput, PermissionTypeStream, streamOrAlias, env), err) assert.False(t, ok) }) @@ -5766,7 +5770,7 @@ func TestState_PeekChar(t *testing.T) { var state State ok, err := state.PeekChar(streamOrAlias, Variable("Char"), Success, env).Force(context.Background()) - assert.Equal(t, permissionErrorInputBinaryStream(streamOrAlias, env), err) + assert.Equal(t, PermissionError(OperationInput, PermissionTypeBinaryStream, streamOrAlias, env), err) assert.False(t, ok) }) @@ -5785,7 +5789,7 @@ func TestState_PeekChar(t *testing.T) { var state State ok, err := state.PeekChar(streamOrAlias, Variable("Char"), Success, env).Force(context.Background()) - assert.Equal(t, permissionErrorInputPastEndOfStream(streamOrAlias, env), err) + assert.Equal(t, PermissionError(OperationInput, PermissionTypePastEndOfStream, streamOrAlias, env), err) assert.False(t, ok) }) @@ -5802,7 +5806,7 @@ func TestState_PeekChar(t *testing.T) { var state State ok, err := state.PeekChar(streamOrAlias, Variable("Char"), Success, env).Force(context.Background()) - assert.Equal(t, representationError("character"), err) + assert.Equal(t, RepresentationError(FlagCharacter, nil), err) assert.False(t, ok) }) } @@ -5829,13 +5833,13 @@ func Test_Halt(t *testing.T) { n := Variable("N") ok, err := Halt(n, Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("n is neither a variable nor an integer", func(t *testing.T) { ok, err := Halt(Atom("foo"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInteger(Atom("foo"), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Atom("foo"), nil), err) assert.False(t, ok) }) } @@ -5890,14 +5894,14 @@ func TestState_Clause(t *testing.T) { t.Run("head is a variable", func(t *testing.T) { var state State ok, err := state.Clause(Variable("Head"), Atom("true"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("head is neither a variable nor a predication", func(t *testing.T) { var state State ok, err := state.Clause(Integer(0), Atom("true"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCallable(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeCallable, Integer(0), nil), err) assert.False(t, ok) }) @@ -5917,7 +5921,7 @@ func TestState_Clause(t *testing.T) { Functor: "green", Args: []Term{what}, }, body, Success, nil).Force(context.Background()) - assert.Equal(t, permissionErrorAccessPrivateProcedure(&Compound{ + assert.Equal(t, PermissionError(OperationAccess, PermissionTypePrivateProcedure, &Compound{ Functor: "/", Args: []Term{Atom("green"), Integer(1)}, }, nil), err) @@ -5927,7 +5931,7 @@ func TestState_Clause(t *testing.T) { t.Run("body is neither a variable nor a callable term", func(t *testing.T) { var state State ok, err := state.Clause(Atom("foo"), Integer(0), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCallable(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeCallable, Integer(0), nil), err) assert.False(t, ok) }) } @@ -5948,25 +5952,25 @@ func TestAtomLength(t *testing.T) { t.Run("atom is a variable", func(t *testing.T) { atom := Variable("Atom") ok, err := AtomLength(atom, Integer(0), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("atom is neither a variable nor an atom", func(t *testing.T) { ok, err := AtomLength(Integer(2), Integer(0), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorAtom(Integer(2), nil), err) + assert.Equal(t, TypeError(ValidTypeAtom, Integer(2), nil), err) assert.False(t, ok) }) t.Run("length is neither a variable nor an integer", func(t *testing.T) { ok, err := AtomLength(Atom("😀"), Atom("1"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInteger(Atom("1"), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Atom("1"), nil), err) assert.False(t, ok) }) t.Run("length is an integer less than zero", func(t *testing.T) { ok, err := AtomLength(Atom("😀"), Integer(-1), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorNotLessThanZero(Integer(-1), nil), err) + assert.Equal(t, DomainError(ValidDomainNotLessThanZero, Integer(-1), nil), err) assert.False(t, ok) }) } @@ -6014,7 +6018,7 @@ func TestAtomConcat(t *testing.T) { atom1, atom3 := Variable("Atom1"), Variable("Atom3") ok, err := AtomConcat(atom1, Atom("bar"), atom3, Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) @@ -6022,20 +6026,20 @@ func TestAtomConcat(t *testing.T) { atom2, atom3 := Variable("Atom2"), Variable("Atom3") ok, err := AtomConcat(Atom("foo"), atom2, atom3, Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("atom1 is neither a variable nor an atom", func(t *testing.T) { t.Run("atom3 is a variable", func(t *testing.T) { ok, err := AtomConcat(Integer(1), Atom("bar"), Variable("Atom3"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorAtom(Integer(1), nil), err) + assert.Equal(t, TypeError(ValidTypeAtom, Integer(1), nil), err) assert.False(t, ok) }) t.Run("atom3 is an atom", func(t *testing.T) { ok, err := AtomConcat(Integer(1), Atom("bar"), Atom("foobar"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorAtom(Integer(1), nil), err) + assert.Equal(t, TypeError(ValidTypeAtom, Integer(1), nil), err) assert.False(t, ok) }) }) @@ -6043,20 +6047,20 @@ func TestAtomConcat(t *testing.T) { t.Run("atom2 is neither a variable nor an atom", func(t *testing.T) { t.Run("atom3 is a variable", func(t *testing.T) { ok, err := AtomConcat(Atom("foo"), Integer(2), Variable("Atom3"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorAtom(Integer(2), nil), err) + assert.Equal(t, TypeError(ValidTypeAtom, Integer(2), nil), err) assert.False(t, ok) }) t.Run("atom3 is an atom", func(t *testing.T) { ok, err := AtomConcat(Atom("foo"), Integer(2), Atom("foobar"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorAtom(Integer(2), nil), err) + assert.Equal(t, TypeError(ValidTypeAtom, Integer(2), nil), err) assert.False(t, ok) }) }) t.Run("atom3 is neither a variable nor an atom", func(t *testing.T) { ok, err := AtomConcat(Atom("foo"), Atom("bar"), Integer(3), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorAtom(Integer(3), nil), err) + assert.Equal(t, TypeError(ValidTypeAtom, Integer(3), nil), err) assert.False(t, ok) }) } @@ -6105,55 +6109,55 @@ func TestSubAtom(t *testing.T) { t.Run("atom is a variable", func(t *testing.T) { ok, err := SubAtom(Variable("Atom"), Variable("Before"), Variable("Length"), Variable("After"), Variable("SubAtom"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("atom is neither a variable nor an atom", func(t *testing.T) { ok, err := SubAtom(Integer(0), Variable("Before"), Variable("Length"), Variable("After"), Variable("SubAtom"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorAtom(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeAtom, Integer(0), nil), err) assert.False(t, ok) }) t.Run("subAtom is neither a variable nor an atom", func(t *testing.T) { ok, err := SubAtom(Atom("foo"), Variable("Before"), Variable("Length"), Variable("After"), Integer(0), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorAtom(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeAtom, Integer(0), nil), err) assert.False(t, ok) }) t.Run("before is neither a variable nor an integer", func(t *testing.T) { ok, err := SubAtom(Atom("foo"), Atom("before"), Variable("Length"), Variable("After"), Variable("SubAtom"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInteger(Atom("before"), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Atom("before"), nil), err) assert.False(t, ok) }) t.Run("length is neither a variable nor an integer", func(t *testing.T) { ok, err := SubAtom(Atom("foo"), Variable("Before"), Atom("length"), Variable("After"), Variable("SubAtom"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInteger(Atom("length"), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Atom("length"), nil), err) assert.False(t, ok) }) t.Run("after is neither a variable nor an integer", func(t *testing.T) { ok, err := SubAtom(Atom("foo"), Variable("Before"), Variable("Length"), Atom("after"), Variable("SubAtom"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInteger(Atom("after"), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Atom("after"), nil), err) assert.False(t, ok) }) t.Run("before is an integer less than zero", func(t *testing.T) { ok, err := SubAtom(Atom("foo"), Integer(-1), Variable("Length"), Variable("After"), Variable("SubAtom"), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorNotLessThanZero(Integer(-1), nil), err) + assert.Equal(t, DomainError(ValidDomainNotLessThanZero, Integer(-1), nil), err) assert.False(t, ok) }) t.Run("length is an integer less than zero", func(t *testing.T) { ok, err := SubAtom(Atom("foo"), Variable("Before"), Integer(-1), Variable("After"), Variable("SubAtom"), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorNotLessThanZero(Integer(-1), nil), err) + assert.Equal(t, DomainError(ValidDomainNotLessThanZero, Integer(-1), nil), err) assert.False(t, ok) }) t.Run("after is an integer less than zero", func(t *testing.T) { ok, err := SubAtom(Atom("foo"), Variable("Before"), Variable("Length"), Integer(-1), Variable("SubAtom"), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorNotLessThanZero(Integer(-1), nil), err) + assert.Equal(t, DomainError(ValidDomainNotLessThanZero, Integer(-1), nil), err) assert.False(t, ok) }) } @@ -6192,40 +6196,40 @@ func TestAtomChars(t *testing.T) { ) ok, err := AtomChars(NewVariable(), chars, Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("variable element", func(t *testing.T) { char := Variable("Char") ok, err := AtomChars(NewVariable(), List(char, Atom("o"), Atom("o")), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) }) t.Run("atom is neither a variable nor an atom", func(t *testing.T) { ok, err := AtomChars(Integer(0), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorAtom(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeAtom, Integer(0), nil), err) assert.False(t, ok) }) t.Run("atom is a variable and List is neither a list nor a partial list", func(t *testing.T) { ok, err := AtomChars(NewVariable(), Atom("chars"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorList(Atom("chars"), nil), err) + assert.Equal(t, TypeError(ValidTypeList, Atom("chars"), nil), err) assert.False(t, ok) }) t.Run("atom is a variable and an element E of the list List is neither a variable nor a one-character atom", func(t *testing.T) { t.Run("not a one-character atom", func(t *testing.T) { ok, err := AtomChars(NewVariable(), List(Atom("chars")), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCharacter(Atom("chars"), nil), err) + assert.Equal(t, TypeError(ValidTypeCharacter, Atom("chars"), nil), err) assert.False(t, ok) }) t.Run("not an atom", func(t *testing.T) { ok, err := AtomChars(NewVariable(), List(Integer(0)), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCharacter(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeCharacter, Integer(0), nil), err) assert.False(t, ok) }) }) @@ -6261,7 +6265,7 @@ func TestAtomCodes(t *testing.T) { Integer(111), ) ok, err := AtomCodes(NewVariable(), codes, Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) @@ -6269,26 +6273,26 @@ func TestAtomCodes(t *testing.T) { code := Variable("Code") ok, err := AtomCodes(NewVariable(), List(code, Integer(111), Integer(111)), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) }) t.Run("atom is neither a variable nor an atom", func(t *testing.T) { ok, err := AtomCodes(Integer(0), List(Integer(102), Integer(111), Integer(111)), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorAtom(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeAtom, Integer(0), nil), err) assert.False(t, ok) }) t.Run("atom is a variable and List is neither a list nor a partial list", func(t *testing.T) { ok, err := AtomCodes(NewVariable(), Atom("codes"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorList(Atom("codes"), nil), err) + assert.Equal(t, TypeError(ValidTypeList, Atom("codes"), nil), err) assert.False(t, ok) }) t.Run("atom is a variable and an element E of the list List is neither a variable nor a character-code", func(t *testing.T) { ok, err := AtomCodes(NewVariable(), List(Atom("f"), Integer(111), Integer(111)), Success, nil).Force(context.Background()) - assert.Equal(t, representationError("character_code"), err) + assert.Equal(t, RepresentationError(FlagCharacterCode, nil), err) assert.False(t, ok) }) } @@ -6349,20 +6353,20 @@ func TestNumberChars(t *testing.T) { ) ok, err := NumberChars(NewVariable(), chars, Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("num is neither a variable nor a number", func(t *testing.T) { t.Run("chars is a list of one-char atoms", func(t *testing.T) { ok, err := NumberChars(Atom("23.4"), List(Atom("2"), Atom("3"), Atom("."), Atom("4")), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorNumber(Atom("23.4"), nil), err) + assert.Equal(t, TypeError(ValidTypeNumber, Atom("23.4"), nil), err) assert.False(t, ok) }) t.Run("chars is not a list of one-char atoms", func(t *testing.T) { ok, err := NumberChars(Atom("23.4"), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorNumber(Atom("23.4"), nil), err) + assert.Equal(t, TypeError(ValidTypeNumber, Atom("23.4"), nil), err) assert.False(t, ok) }) }) @@ -6370,33 +6374,35 @@ func TestNumberChars(t *testing.T) { t.Run("chars is neither a partial list nor a list", func(t *testing.T) { t.Run("not even list-ish", func(t *testing.T) { ok, err := NumberChars(NewVariable(), Atom("foo"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorList(Atom("foo"), nil), err) + assert.Equal(t, TypeError(ValidTypeList, Atom("foo"), nil), err) assert.False(t, ok) }) t.Run("list-ish", func(t *testing.T) { _, err := NumberChars(Integer(0), ListRest(Atom("b"), Variable("A")), Success, nil).Force(context.Background()) - _, ok := err.(*Exception).Term().Unify(TypeErrorList(ListRest(Atom("b"), NewVariable()), nil).Term(), false, nil) + _, ok := err.(Exception).Term().Unify(TypeError(ValidTypeList, ListRest(Atom("b"), NewVariable()), nil).Term(), false, nil) assert.True(t, ok) }) }) t.Run("num is a variable and an element of a list prefix of chars is a variable", func(t *testing.T) { ok, err := NumberChars(NewVariable(), List(Atom("1"), NewVariable()), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("chars is a list of one-char atoms but is not parsable as a number", func(t *testing.T) { t.Run("not a number", func(t *testing.T) { ok, err := NumberChars(NewVariable(), List(Atom("f"), Atom("o"), Atom("o")), Success, nil).Force(context.Background()) - assert.Equal(t, syntaxErrorNotANumber(), err) + assert.Equal(t, SyntaxError(errNotANumber, nil), err) assert.False(t, ok) }) t.Run("unexpected token", func(t *testing.T) { ok, err := NumberChars(NewVariable(), List(Atom("1"), Atom(".")), Success, nil).Force(context.Background()) - assert.Equal(t, syntaxErrorUnexpectedToken(Atom("unexpected token: ")), err) + assert.Equal(t, SyntaxError(&unexpectedTokenError{ + Actual: Token{Kind: TokenPeriod, Val: "."}, + }, nil), err) assert.False(t, ok) }) }) @@ -6405,13 +6411,13 @@ func TestNumberChars(t *testing.T) { t.Run("chars contains a variable", func(t *testing.T) { t.Run("not even an atom", func(t *testing.T) { ok, err := NumberChars(Integer(100), List(NewVariable(), Atom("0"), Integer(0)), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCharacter(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeCharacter, Integer(0), nil), err) assert.False(t, ok) }) t.Run("atom", func(t *testing.T) { ok, err := NumberChars(Integer(100), List(NewVariable(), Atom("00")), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCharacter(Atom("00"), nil), err) + assert.Equal(t, TypeError(ValidTypeCharacter, Atom("00"), nil), err) assert.False(t, ok) }) }) @@ -6419,13 +6425,13 @@ func TestNumberChars(t *testing.T) { t.Run("chars does not contain a variable", func(t *testing.T) { t.Run("not even an atom", func(t *testing.T) { ok, err := NumberChars(Integer(100), List(Atom("1"), Atom("0"), Integer(0)), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCharacter(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeCharacter, Integer(0), nil), err) assert.False(t, ok) }) t.Run("atom", func(t *testing.T) { ok, err := NumberChars(Integer(100), List(Atom("1"), Atom("00")), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorCharacter(Atom("00"), nil), err) + assert.Equal(t, TypeError(ValidTypeCharacter, Atom("00"), nil), err) assert.False(t, ok) }) }) @@ -6482,7 +6488,7 @@ func TestNumberCodes(t *testing.T) { ) ok, err := NumberCodes(NewVariable(), codes, Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) @@ -6490,32 +6496,32 @@ func TestNumberCodes(t *testing.T) { code := Variable("Code") ok, err := NumberCodes(NewVariable(), List(code, Integer(50), Integer(51), Integer(46), Integer(52)), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) }) t.Run("num is neither a variable nor a number", func(t *testing.T) { ok, err := NumberCodes(Atom("23.4"), List(Integer(50), Integer(51), Integer(46), Integer(52)), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorNumber(Atom("23.4"), nil), err) + assert.Equal(t, TypeError(ValidTypeNumber, Atom("23.4"), nil), err) assert.False(t, ok) }) t.Run("num is a variable and codes is neither a list nor partial list", func(t *testing.T) { ok, err := NumberCodes(NewVariable(), Atom("23.4"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorList(Atom("23.4"), nil), err) + assert.Equal(t, TypeError(ValidTypeList, Atom("23.4"), nil), err) assert.False(t, ok) }) t.Run("an element E of the list codes is neither a variable nor a one-character atom", func(t *testing.T) { ok, err := NumberCodes(NewVariable(), List(Atom("2"), Integer(51), Integer(46), Integer(52)), Success, nil).Force(context.Background()) - assert.Equal(t, representationError("character_code"), err) + assert.Equal(t, RepresentationError(FlagCharacterCode, nil), err) assert.False(t, ok) }) t.Run("codes is a list of one-char atoms but is not parsable as a number", func(t *testing.T) { ok, err := NumberCodes(NewVariable(), List(Integer(102), Integer(111), Integer(111)), Success, nil).Force(context.Background()) - assert.Equal(t, syntaxErrorNotANumber(), err) + assert.Equal(t, SyntaxError(errNotANumber, nil), err) assert.False(t, ok) }) } @@ -6679,21 +6685,21 @@ func TestState_StreamProperty(t *testing.T) { t.Run("streamOrAlias is neither a variable, a stream-term, nor an alias", func(t *testing.T) { var state State ok, err := state.StreamProperty(Integer(0), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorStreamOrAlias(Integer(0), nil), err) + assert.Equal(t, DomainError(ValidDomainStreamOrAlias, Integer(0), nil), err) assert.False(t, ok) }) t.Run("property is neither a variable nor a stream property", func(t *testing.T) { var state State ok, err := state.StreamProperty(NewVariable(), Atom("property"), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorStreamProperty(Atom("property"), nil), err) + assert.Equal(t, DomainError(ValidDomainStreamProperty, Atom("property"), nil), err) assert.False(t, ok) }) t.Run("streamOrAlias is not associated with an open stream", func(t *testing.T) { var state State ok, err := state.StreamProperty(Atom("foo"), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, existenceErrorStream(Atom("foo"), nil), err) + assert.Equal(t, ExistenceError(ObjectTypeStream, Atom("foo"), nil), err) assert.False(t, ok) }) @@ -6882,7 +6888,7 @@ func TestState_SetStreamPosition(t *testing.T) { t.Run("streamOrAlias is a variable", func(t *testing.T) { var state State ok, err := state.SetStreamPosition(Variable("Stream"), Integer(0), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) @@ -6895,21 +6901,21 @@ func TestState_SetStreamPosition(t *testing.T) { var state State ok, err := state.SetStreamPosition(s, Variable("Pos"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("streamOrAlias is neither a variable nor a stream term or alias", func(t *testing.T) { var state State ok, err := state.SetStreamPosition(Integer(2), Integer(0), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorStreamOrAlias(Integer(2), nil), err) + assert.Equal(t, DomainError(ValidDomainStreamOrAlias, Integer(2), nil), err) assert.False(t, ok) }) t.Run("streamOrAlias is not associated with an open stream", func(t *testing.T) { var state State ok, err := state.SetStreamPosition(Atom("foo"), Integer(0), Success, nil).Force(context.Background()) - assert.Equal(t, existenceErrorStream(Atom("foo"), nil), err) + assert.Equal(t, ExistenceError(ObjectTypeStream, Atom("foo"), nil), err) assert.False(t, ok) }) @@ -6924,7 +6930,7 @@ func TestState_SetStreamPosition(t *testing.T) { var state State ok, err := state.SetStreamPosition(s, Integer(0), Success, env).Force(context.Background()) - assert.Equal(t, PermissionError("reposition", "stream", s, env), err) + assert.Equal(t, PermissionError(OperationReposition, PermissionTypeStream, s, env), err) assert.False(t, ok) }) } @@ -6956,14 +6962,14 @@ func TestState_CharConversion(t *testing.T) { t.Run("inChar is a variable", func(t *testing.T) { var state State ok, err := state.CharConversion(Variable("In"), Atom("a"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("outChar is a variable", func(t *testing.T) { var state State ok, err := state.CharConversion(Atom("a"), Variable("Out"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) @@ -6971,14 +6977,14 @@ func TestState_CharConversion(t *testing.T) { t.Run("not even an atom", func(t *testing.T) { var state State ok, err := state.CharConversion(Integer(0), Atom("a"), Success, nil).Force(context.Background()) - assert.Equal(t, representationError("character"), err) + assert.Equal(t, RepresentationError(FlagCharacter, nil), err) assert.False(t, ok) }) t.Run("multi-character atom", func(t *testing.T) { var state State ok, err := state.CharConversion(Atom("foo"), Atom("a"), Success, nil).Force(context.Background()) - assert.Equal(t, representationError("character"), err) + assert.Equal(t, RepresentationError(FlagCharacter, nil), err) assert.False(t, ok) }) }) @@ -6987,14 +6993,14 @@ func TestState_CharConversion(t *testing.T) { t.Run("not even an atom", func(t *testing.T) { var state State ok, err := state.CharConversion(Atom("a"), Integer(0), Success, nil).Force(context.Background()) - assert.Equal(t, representationError("character"), err) + assert.Equal(t, RepresentationError(FlagCharacter, nil), err) assert.False(t, ok) }) t.Run("multi-character atom", func(t *testing.T) { var state State ok, err := state.CharConversion(Atom("a"), Atom("foo"), Success, nil).Force(context.Background()) - assert.Equal(t, representationError("character"), err) + assert.Equal(t, RepresentationError(FlagCharacter, nil), err) assert.False(t, ok) }) }) @@ -7053,14 +7059,14 @@ func TestState_CurrentCharConversion(t *testing.T) { t.Run("not even an atom", func(t *testing.T) { var state State ok, err := state.CurrentCharConversion(Integer(0), Atom("b"), Success, nil).Force(context.Background()) - assert.Equal(t, representationError("character"), err) + assert.Equal(t, RepresentationError(FlagCharacter, nil), err) assert.False(t, ok) }) t.Run("multi-character atom", func(t *testing.T) { var state State ok, err := state.CurrentCharConversion(Atom("foo"), Atom("b"), Success, nil).Force(context.Background()) - assert.Equal(t, representationError("character"), err) + assert.Equal(t, RepresentationError(FlagCharacter, nil), err) assert.False(t, ok) }) }) @@ -7069,14 +7075,14 @@ func TestState_CurrentCharConversion(t *testing.T) { t.Run("not even an atom", func(t *testing.T) { var state State ok, err := state.CurrentCharConversion(Atom("a"), Integer(0), Success, nil).Force(context.Background()) - assert.Equal(t, representationError("character"), err) + assert.Equal(t, RepresentationError(FlagCharacter, nil), err) assert.False(t, ok) }) t.Run("multi-character atom", func(t *testing.T) { var state State ok, err := state.CurrentCharConversion(Atom("a"), Atom("bar"), Success, nil).Force(context.Background()) - assert.Equal(t, representationError("character"), err) + assert.Equal(t, RepresentationError(FlagCharacter, nil), err) assert.False(t, ok) }) }) @@ -7086,28 +7092,28 @@ func TestState_SetPrologFlag(t *testing.T) { t.Run("bounded", func(t *testing.T) { var state State ok, err := state.SetPrologFlag(Atom("bounded"), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, PermissionError("modify", "flag", Atom("bounded"), nil), err) + assert.Equal(t, PermissionError(OperationModify, PermissionTypeFlag, Atom("bounded"), nil), err) assert.False(t, ok) }) t.Run("max_integer", func(t *testing.T) { var state State ok, err := state.SetPrologFlag(Atom("max_integer"), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, PermissionError("modify", "flag", Atom("max_integer"), nil), err) + assert.Equal(t, PermissionError(OperationModify, PermissionTypeFlag, Atom("max_integer"), nil), err) assert.False(t, ok) }) t.Run("min_integer", func(t *testing.T) { var state State ok, err := state.SetPrologFlag(Atom("min_integer"), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, PermissionError("modify", "flag", Atom("min_integer"), nil), err) + assert.Equal(t, PermissionError(OperationModify, PermissionTypeFlag, Atom("min_integer"), nil), err) assert.False(t, ok) }) t.Run("integer_rounding_function", func(t *testing.T) { var state State ok, err := state.SetPrologFlag(Atom("integer_rounding_function"), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, PermissionError("modify", "flag", Atom("integer_rounding_function"), nil), err) + assert.Equal(t, PermissionError(OperationModify, PermissionTypeFlag, Atom("integer_rounding_function"), nil), err) assert.False(t, ok) }) @@ -7164,7 +7170,7 @@ func TestState_SetPrologFlag(t *testing.T) { t.Run("max_arity", func(t *testing.T) { var state State ok, err := state.SetPrologFlag(Atom("max_arity"), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, PermissionError("modify", "flag", Atom("max_arity"), nil), err) + assert.Equal(t, PermissionError(OperationModify, PermissionTypeFlag, Atom("max_arity"), nil), err) assert.False(t, ok) }) @@ -7237,35 +7243,35 @@ func TestState_SetPrologFlag(t *testing.T) { t.Run("flag is a variable", func(t *testing.T) { var state State ok, err := state.SetPrologFlag(Variable("Flag"), Atom("fail"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("value is a variable", func(t *testing.T) { var state State ok, err := state.SetPrologFlag(Atom("unknown"), Variable("Value"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.False(t, ok) }) t.Run("flag is neither a variable nor an atom", func(t *testing.T) { var state State ok, err := state.SetPrologFlag(Integer(0), Atom("fail"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorAtom(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeAtom, Integer(0), nil), err) assert.False(t, ok) }) t.Run("flag is an atom but an invalid flag for the processor", func(t *testing.T) { var state State ok, err := state.SetPrologFlag(Atom("foo"), Atom("fail"), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorPrologFlag(Atom("foo"), nil), err) + assert.Equal(t, DomainError(ValidDomainPrologFlag, Atom("foo"), nil), err) assert.False(t, ok) }) t.Run("value is inadmissible for flag", func(t *testing.T) { var state State ok, err := state.SetPrologFlag(Atom("unknown"), Integer(0), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorFlagValue(&Compound{ + assert.Equal(t, DomainError(ValidDomainFlagValue, &Compound{ Functor: "+", Args: []Term{Atom("unknown"), Integer(0)}, }, nil), err) @@ -7275,7 +7281,7 @@ func TestState_SetPrologFlag(t *testing.T) { t.Run("value is admissible for flag but the flag is not modifiable", func(t *testing.T) { var state State ok, err := state.SetPrologFlag(Atom("bounded"), Atom("true"), Success, nil).Force(context.Background()) - assert.Equal(t, PermissionError("modify", "flag", Atom("bounded"), nil), err) + assert.Equal(t, PermissionError(OperationModify, PermissionTypeFlag, Atom("bounded"), nil), err) assert.False(t, ok) }) } @@ -7363,14 +7369,14 @@ func TestState_CurrentPrologFlag(t *testing.T) { t.Run("flag is neither a variable nor an atom", func(t *testing.T) { var state State ok, err := state.CurrentPrologFlag(Integer(0), Atom("error"), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorAtom(Integer(0), nil), err) + assert.Equal(t, TypeError(ValidTypeAtom, Integer(0), nil), err) assert.False(t, ok) }) t.Run("flag is an atom but an invalid flag for the processor", func(t *testing.T) { var state State ok, err := state.CurrentPrologFlag(Atom("foo"), Atom("error"), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorPrologFlag(Atom("foo"), nil), err) + assert.Equal(t, DomainError(ValidDomainPrologFlag, Atom("foo"), nil), err) assert.False(t, ok) }) } @@ -7432,7 +7438,7 @@ func TestState_Dynamic(t *testing.T) { Integer(1), }, }, Success, nil).Force(context.Background()) - assert.Equal(t, permissionErrorModifyStaticProcedure(&Compound{ + assert.Equal(t, PermissionError(OperationModify, PermissionTypeStaticProcedure, &Compound{ Functor: "/", Args: []Term{ Atom("foo"), @@ -7513,7 +7519,7 @@ func TestState_BuiltIn(t *testing.T) { Integer(1), }, }, Success, nil).Force(context.Background()) - assert.Equal(t, permissionErrorModifyStaticProcedure(&Compound{ + assert.Equal(t, PermissionError(OperationModify, PermissionTypeStaticProcedure, &Compound{ Functor: "/", Args: []Term{ Atom("foo"), @@ -7940,7 +7946,7 @@ func TestNth0(t *testing.T) { t.Run("list is an improper list", func(t *testing.T) { _, err := Nth0(Variable("N"), ListRest(Variable("X"), Atom("a")), Variable("Elem"), Failure, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) }) }) @@ -7967,13 +7973,13 @@ func TestNth0(t *testing.T) { t.Run("list is an improper list", func(t *testing.T) { _, err := Nth0(Integer(1), ListRest(NewVariable(), Atom("a")), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) }) }) t.Run("n is neither a variable nor an integer", func(t *testing.T) { _, err := Nth0(Atom("foo"), List(Atom("a"), Atom("b"), Atom("c")), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInteger(Atom("foo"), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Atom("foo"), nil), err) }) } @@ -8002,7 +8008,7 @@ func TestNth1(t *testing.T) { t.Run("list is an improper list", func(t *testing.T) { _, err := Nth1(Variable("N"), ListRest(Variable("X"), Atom("a")), Variable("Elem"), Failure, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) }) }) @@ -8029,13 +8035,13 @@ func TestNth1(t *testing.T) { t.Run("list is an improper list", func(t *testing.T) { _, err := Nth1(Integer(2), ListRest(NewVariable(), Atom("a")), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) }) }) t.Run("n is neither a variable nor an integer", func(t *testing.T) { _, err := Nth1(Atom("foo"), List(Atom("a"), Atom("b"), Atom("c")), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInteger(Atom("foo"), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Atom("foo"), nil), err) }) } @@ -8043,7 +8049,7 @@ func TestSucc(t *testing.T) { t.Run("x is a variable", func(t *testing.T) { t.Run("s is a variable", func(t *testing.T) { _, err := Succ(Variable("X"), Variable("S"), Success, nil).Force(context.Background()) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) }) t.Run("s is an integer", func(t *testing.T) { @@ -8059,7 +8065,7 @@ func TestSucc(t *testing.T) { t.Run("s < 0", func(t *testing.T) { _, err := Succ(Variable("X"), Integer(-1), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorNotLessThanZero(Integer(-1), nil), err) + assert.Equal(t, DomainError(ValidDomainNotLessThanZero, Integer(-1), nil), err) }) t.Run("s = 0", func(t *testing.T) { @@ -8071,7 +8077,7 @@ func TestSucc(t *testing.T) { t.Run("s is neither a variable nor an integer", func(t *testing.T) { _, err := Succ(Variable("X"), Float(1), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInteger(Float(1), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Float(1), nil), err) }) }) @@ -8094,27 +8100,27 @@ func TestSucc(t *testing.T) { t.Run("s is neither a variable nor an integer", func(t *testing.T) { _, err := Succ(Integer(0), Float(1), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInteger(Float(1), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Float(1), nil), err) }) t.Run("x is negative", func(t *testing.T) { _, err := Succ(Integer(-1), Integer(0), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorNotLessThanZero(Integer(-1), nil), err) + assert.Equal(t, DomainError(ValidDomainNotLessThanZero, Integer(-1), nil), err) }) t.Run("x is math.MaxInt64", func(t *testing.T) { _, err := Succ(Integer(math.MaxInt64), Integer(0), Success, nil).Force(context.Background()) - assert.Equal(t, ErrIntOverflow, err) + assert.Equal(t, EvaluationError(ExceptionalValueIntOverflow, nil), err) }) t.Run("s is negative", func(t *testing.T) { _, err := Succ(Integer(0), Integer(-1), Success, nil).Force(context.Background()) - assert.Equal(t, domainErrorNotLessThanZero(Integer(-1), nil), err) + assert.Equal(t, DomainError(ValidDomainNotLessThanZero, Integer(-1), nil), err) }) }) t.Run("x is neither a variable nor an integer", func(t *testing.T) { _, err := Succ(Float(0), NewVariable(), Success, nil).Force(context.Background()) - assert.Equal(t, TypeErrorInteger(Float(0), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Float(0), nil), err) }) } diff --git a/engine/clause.go b/engine/clause.go index 0a397f4d..31e9fabf 100644 --- a/engine/clause.go +++ b/engine/clause.go @@ -90,7 +90,7 @@ func compile(t Term) (clauses, error) { for iter.Next() { c, err := compileClause(head, iter.Current()) if err != nil { - return nil, TypeErrorCallable(body, nil) + return nil, TypeError(ValidTypeCallable, body, nil) } c.raw = t cs = append(cs, c) @@ -116,7 +116,7 @@ func compileClause(head Term, body Term) (clause, error) { } if body != nil { if err := c.compileBody(body); err != nil { - return c, TypeErrorCallable(body, nil) + return c, TypeError(ValidTypeCallable, body, nil) } } c.bytecode = append(c.bytecode, instruction{opcode: opExit}) diff --git a/engine/env.go b/engine/env.go index a967ef71..9fafbe4f 100644 --- a/engine/env.go +++ b/engine/env.go @@ -1,5 +1,10 @@ package engine +const ( + varContext = Variable("$context") + rootContext = Atom("root") +) + type color uint8 const ( @@ -21,6 +26,13 @@ type binding struct { // attributes? } +var rootEnv = &Env{ + binding: binding{ + variable: varContext, + value: rootContext, + }, +} + // NewEnv creates an empty environment. func NewEnv() *Env { return nil @@ -29,6 +41,9 @@ func NewEnv() *Env { // Lookup returns a term that the given variable is bound to. func (e *Env) Lookup(k Variable) (Term, bool) { node := e + if node == nil { + node = rootEnv + } for { if node == nil { return nil, false @@ -46,7 +61,11 @@ func (e *Env) Lookup(k Variable) (Term, bool) { // Bind adds a new entry to the environment. func (e *Env) Bind(k Variable, v Term) *Env { - ret := *e.insert(k, v) + node := e + if node == nil { + node = rootEnv + } + ret := *node.insert(k, v) ret.color = black return &ret } @@ -67,7 +86,9 @@ func (e *Env) insert(k Variable, v Term) *Env { ret.balance() return &ret default: - return e + ret := *e + ret.value = v + return &ret } } diff --git a/engine/env_test.go b/engine/env_test.go index 505f1325..95d7bddf 100644 --- a/engine/env_test.go +++ b/engine/env_test.go @@ -12,9 +12,15 @@ func TestEnv_Bind(t *testing.T) { var env *Env assert.Equal(t, &Env{ color: black, + right: &Env{ + binding: binding{ + variable: "A", + value: Atom("a"), + }, + }, binding: binding{ - variable: "A", - value: Atom("a"), + variable: varContext, + value: Atom("root"), }, }, env.Bind("A", Atom("a"))) } diff --git a/engine/exception.go b/engine/exception.go index dfc0deb6..c419fb29 100644 --- a/engine/exception.go +++ b/engine/exception.go @@ -2,35 +2,6 @@ package engine import ( "bytes" - "fmt" -) - -var ( - // ErrInstantiation is an instantiation error exception. - ErrInstantiation = &Exception{ - term: &Compound{ - Functor: "error", - Args: []Term{ - Atom("instantiation_error"), - Atom("Arguments are not sufficiently instantiated."), - }, - }, - } - - // ErrZeroDivisor is an exception that will be raised when an operation divided by zero. - ErrZeroDivisor = evaluationError(Atom("zero_divisor"), Atom("Divided by zero.")) - - // ErrIntOverflow is an exception that will be raised when an integer overflowed, either positively or negatively. - ErrIntOverflow = evaluationError(Atom("int_overflow"), Atom("Integer overflow.")) - - // ErrFloatOverflow is an exception that will be raised when a float overflowed, either positively or negatively. - ErrFloatOverflow = evaluationError(Atom("float_overflow"), Atom("Float overflow.")) - - // ErrUnderflow is an exception that will be raised when a float is too small to be represented by engine.Float. - ErrUnderflow = evaluationError(Atom("underflow"), Atom("Underflow.")) - - // ErrUndefined is an exception that will be raised when a function value for the arguments is undefined. - ErrUndefined = evaluationError(Atom("undefined"), Atom("Undefined.")) ) // Exception is an error represented by a prolog term. @@ -39,339 +10,364 @@ type Exception struct { } // NewException creates an exception from a copy of the given term. -func NewException(term Term, env *Env) *Exception { - return &Exception{term: copyTerm(term, nil, env)} +func NewException(term Term, env *Env) Exception { + return Exception{term: copyTerm(term, nil, env)} } // Term returns the underlying term of the exception. -func (e *Exception) Term() Term { +func (e Exception) Term() Term { return e.term } -func (e *Exception) Error() string { +func (e Exception) Error() string { var buf bytes.Buffer _ = Write(&buf, e.term, nil, WithQuoted(true)) return buf.String() } -// TypeErrorAtom returns a type error exception for atom. -func TypeErrorAtom(culprit Term, env *Env) *Exception { - return TypeError("atom", culprit, env) -} - -// TypeErrorAtomic returns a type error exception for atomic. -func TypeErrorAtomic(culprit Term, env *Env) *Exception { - return TypeError("atomic", culprit, env) -} - -// TypeErrorByte returns a type error exception for byte. -func TypeErrorByte(culprit Term, env *Env) *Exception { - return TypeError("byte", culprit, env) -} - -// TypeErrorCallable returns a type error exception for callable. -func TypeErrorCallable(culprit Term, env *Env) *Exception { - return TypeError("callable", culprit, env) -} - -// TypeErrorCharacter returns a type error exception for character. -func TypeErrorCharacter(culprit Term, env *Env) *Exception { - return TypeError("character", culprit, env) -} - -// TypeErrorCompound returns a type error exception for compound. -func TypeErrorCompound(culprit Term, env *Env) *Exception { - return TypeError("compound", culprit, env) -} - -// TypeErrorEvaluable returns a type error exception for evaluable. -func TypeErrorEvaluable(culprit Term, env *Env) *Exception { - return TypeError("evaluable", culprit, env) -} - -// TypeErrorInByte returns a type error exception for in_byte. -func TypeErrorInByte(culprit Term, env *Env) *Exception { - return TypeError("in_byte", culprit, env) -} - -// TypeErrorInCharacter returns a type error exception for in_character. -func TypeErrorInCharacter(culprit Term, env *Env) *Exception { - return TypeError("in_character", culprit, env) -} - -// TypeErrorInteger returns a type error exception for integer. -func TypeErrorInteger(culprit Term, env *Env) *Exception { - return TypeError("integer", culprit, env) -} - -// TypeErrorList returns a type error exception for list. -func TypeErrorList(culprit Term, env *Env) *Exception { - return TypeError("list", culprit, env) -} - -// TypeErrorNumber returns a type error exception for number. -func TypeErrorNumber(culprit Term, env *Env) *Exception { - return TypeError("number", culprit, env) -} - -// TypeErrorPredicateIndicator returns a type error exception for predicate_indicator. -func TypeErrorPredicateIndicator(culprit Term, env *Env) *Exception { - return TypeError("predicate_indicator", culprit, env) +// InstantiationError returns an instantiation error exception. +func InstantiationError(env *Env) Exception { + return NewException(&Compound{ + Functor: "error", + Args: []Term{ + Atom("instantiation_error"), + varContext, + }, + }, env) } -// TypeErrorPair returns a type error exception for pair. -func TypeErrorPair(culprit Term, env *Env) *Exception { - return TypeError("pair", culprit, env) -} +type ValidType uint8 + +const ( + ValidTypeAtom ValidType = iota + ValidTypeAtomic + ValidTypeByte + ValidTypeCallable + ValidTypeCharacter + ValidTypeCompound + ValidTypeEvaluable + ValidTypeInByte + ValidTypeInCharacter + ValidTypeInteger + ValidTypeList + ValidTypeNumber + ValidTypePredicateIndicator + ValidTypePair + ValidTypeFloat +) -// TypeErrorFloat returns a type error exception for float. -func TypeErrorFloat(culprit Term, env *Env) *Exception { - return TypeError("float", culprit, env) +func (t ValidType) Term() Term { + return [...]Atom{ + ValidTypeAtom: "atom", + ValidTypeAtomic: "atomic", + ValidTypeByte: "byte", + ValidTypeCallable: "callable", + ValidTypeCharacter: "character", + ValidTypeCompound: "compound", + ValidTypeEvaluable: "evaluable", + ValidTypeInByte: "in_byte", + ValidTypeInCharacter: "in_character", + ValidTypeInteger: "integer", + ValidTypeList: "list", + ValidTypeNumber: "number", + ValidTypePredicateIndicator: "predicate_indicator", + ValidTypePair: "pair", + ValidTypeFloat: "float", + }[t] } // TypeError creates a new type error exception. -func TypeError(validType Atom, culprit Term, env *Env) *Exception { +func TypeError(validType ValidType, culprit Term, env *Env) Exception { return NewException(&Compound{ Functor: "error", Args: []Term{ &Compound{ Functor: "type_error", - Args: []Term{validType, culprit}, + Args: []Term{validType.Term(), culprit}, }, - Atom(fmt.Sprintf("Expected %s, found %T.", validType, culprit)), + varContext, }, }, env) } -func domainErrorFlagValue(culprit Term, env *Env) *Exception { - return DomainError("flag_value", culprit, env) -} - -func domainErrorIOMode(culprit Term, env *Env) *Exception { - return DomainError("io_mode", culprit, env) -} - -func domainErrorNotEmptyList(culprit Term, env *Env) *Exception { - return DomainError("not_empty_list", culprit, env) -} - -func domainErrorNotLessThanZero(culprit Term, env *Env) *Exception { - return DomainError("not_less_than_zero", culprit, env) -} - -func domainErrorOperatorPriority(culprit Term, env *Env) *Exception { - return DomainError("operator_priority", culprit, env) -} - -func domainErrorOperatorSpecifier(culprit Term, env *Env) *Exception { - return DomainError("operator_specifier", culprit, env) -} - -func domainErrorPrologFlag(culprit Term, env *Env) *Exception { - return DomainError("prolog_flag", culprit, env) -} - -func domainErrorReadOption(culprit Term, env *Env) *Exception { - return DomainError("read_option", culprit, env) -} - -func domainErrorSourceSink(culprit Term, env *Env) *Exception { - return DomainError("source_sink", culprit, env) -} - -func domainErrorStream(culprit Term, env *Env) *Exception { - return DomainError("stream", culprit, env) -} - -func domainErrorStreamOption(culprit Term, env *Env) *Exception { - return DomainError("stream_option", culprit, env) -} - -func domainErrorStreamOrAlias(culprit Term, env *Env) *Exception { - return DomainError("stream_or_alias", culprit, env) -} - -func domainErrorStreamProperty(culprit Term, env *Env) *Exception { - return DomainError("stream_property", culprit, env) -} - -func domainErrorWriteOption(culprit Term, env *Env) *Exception { - return DomainError("write_option", culprit, env) -} +type ValidDomain uint8 + +const ( + ValidDomainCharacterCodeList ValidDomain = iota + ValidDomainCloseOption + ValidDomainFlagValue + ValidDomainIOMode + ValidDomainNonEmptyList + ValidDomainNotLessThanZero + ValidDomainOperatorPriority + ValidDomainOperatorSpecifier + ValidDomainPrologFlag + ValidDomainReadOption + ValidDomainSourceSink + ValidDomainStream + ValidDomainStreamOption + ValidDomainStreamOrAlias + ValidDomainStreamPosition + ValidDomainStreamProperty + ValidDomainWriteOption + + ValidDomainOrder +) -func domainErrorOrder(culprit Term, env *Env) *Exception { - return DomainError("order", culprit, env) +func (vd ValidDomain) Term() Term { + return [...]Atom{ + ValidDomainCharacterCodeList: "character_code_list", + ValidDomainCloseOption: "close_option", + ValidDomainFlagValue: "flag_value", + ValidDomainIOMode: "io_mode", + ValidDomainNonEmptyList: "non_empty_list", + ValidDomainNotLessThanZero: "not_less_than_zero", + ValidDomainOperatorPriority: "operator_priority", + ValidDomainOperatorSpecifier: "operator_specifier", + ValidDomainPrologFlag: "prolog_flag", + ValidDomainReadOption: "read_option", + ValidDomainSourceSink: "source_sink", + ValidDomainStream: "stream", + ValidDomainStreamOption: "stream_option", + ValidDomainStreamOrAlias: "stream_or_alias", + ValidDomainStreamPosition: "stream_position", + ValidDomainStreamProperty: "stream_property", + ValidDomainWriteOption: "write_option", + ValidDomainOrder: "order", + }[vd] } // DomainError creates a new domain error exception. -func DomainError(validDomain Atom, culprit Term, env *Env) *Exception { +func DomainError(validDomain ValidDomain, culprit Term, env *Env) Exception { return NewException(&Compound{ Functor: "error", Args: []Term{ &Compound{ Functor: "domain_error", - Args: []Term{validDomain, culprit}, + Args: []Term{validDomain.Term(), culprit}, }, - Atom(fmt.Sprintf("Invalid value for %s.", validDomain)), + varContext, }, }, env) } -func existenceErrorProcedure(culprit Term, env *Env) *Exception { - return ExistenceError("procedure", culprit, env) -} +type ObjectType uint8 -func existenceErrorSourceSink(culprit Term, env *Env) *Exception { - return ExistenceError("source_sink", culprit, env) -} +const ( + ObjectTypeProcedure ObjectType = iota + ObjectTypeSourceSink + ObjectTypeStream +) -func existenceErrorStream(culprit Term, env *Env) *Exception { - return ExistenceError("stream", culprit, env) +func (ot ObjectType) Term() Term { + return [...]Atom{ + ObjectTypeProcedure: "procedure", + ObjectTypeSourceSink: "source_sink", + ObjectTypeStream: "stream", + }[ot] } // ExistenceError creates a new existence error exception. -func ExistenceError(objectType Atom, culprit Term, env *Env) *Exception { +func ExistenceError(objectType ObjectType, culprit Term, env *Env) Exception { return NewException(&Compound{ Functor: "error", Args: []Term{ &Compound{ Functor: "existence_error", - Args: []Term{objectType, culprit}, + Args: []Term{objectType.Term(), culprit}, }, - Atom(fmt.Sprintf("Unknown %s.", objectType)), + varContext, }, }, env) } -func permissionErrorModifyStaticProcedure(culprit Term, env *Env) *Exception { - return PermissionError("modify", "static_procedure", culprit, env) -} - -func permissionErrorAccessPrivateProcedure(culprit Term, env *Env) *Exception { - return PermissionError("access", "private_procedure", culprit, env) -} +type Operation uint8 -func permissionErrorOutputStream(culprit Term, env *Env) *Exception { - return PermissionError("output", "stream", culprit, env) -} +const ( + OperationAccess Operation = iota + OperationCreate + OperationInput + OperationModify + OperationOpen + OperationOutput + OperationReposition +) -func permissionErrorOutputBinaryStream(culprit Term, env *Env) *Exception { - return PermissionError("output", "binary_stream", culprit, env) -} +func (o Operation) Term() Term { + return [...]Atom{ + OperationAccess: "access", + OperationCreate: "create", + OperationInput: "input", + OperationModify: "modify", + OperationOpen: "open", + OperationOutput: "output", + OperationReposition: "reposition", + }[o] +} + +type PermissionType uint8 + +const ( + PermissionTypeBinaryStream PermissionType = iota + PermissionTypeFlag + PermissionTypeOperator + PermissionTypePastEndOfStream + PermissionTypePrivateProcedure + PermissionTypeStaticProcedure + PermissionTypeSourceSink + PermissionTypeStream + PermissionTypeTextStream +) -func permissionErrorOutputTextStream(culprit Term, env *Env) *Exception { - return PermissionError("output", "text_stream", culprit, env) +func (pt PermissionType) Term() Term { + return [...]Atom{ + PermissionTypeBinaryStream: "binary_stream", + PermissionTypeFlag: "flag", + PermissionTypeOperator: "operator", + PermissionTypePastEndOfStream: "past_enf_of_stream", + PermissionTypePrivateProcedure: "private_procedure", + PermissionTypeStaticProcedure: "static_procedure", + PermissionTypeSourceSink: "source_sink", + PermissionTypeStream: "stream", + PermissionTypeTextStream: "text_stream", + }[pt] } -func permissionErrorInputStream(culprit Term, env *Env) *Exception { - return PermissionError("input", "stream", culprit, env) +// PermissionError creates a new permission error exception. +func PermissionError(operation Operation, permissionType PermissionType, culprit Term, env *Env) Exception { + return NewException(&Compound{ + Functor: "error", + Args: []Term{ + &Compound{ + Functor: "permission_error", + Args: []Term{operation.Term(), permissionType.Term(), culprit}, + }, + varContext, + }, + }, env) } -func permissionErrorInputBinaryStream(culprit Term, env *Env) *Exception { - return PermissionError("input", "binary_stream", culprit, env) -} +type Flag uint8 -func permissionErrorInputTextStream(culprit Term, env *Env) *Exception { - return PermissionError("input", "text_stream", culprit, env) -} +const ( + FlagCharacter Flag = iota + FlagCharacterCode + FlagInCharacterCode + FlagMaxArity + FlagMaxInteger + FlagMinInteger +) -func permissionErrorInputPastEndOfStream(culprit Term, env *Env) *Exception { - return PermissionError("input", "past_end_of_stream", culprit, env) +func (f Flag) Term() Term { + return [...]Atom{ + FlagCharacter: "character", + FlagCharacterCode: "character_code", + FlagInCharacterCode: "in_character_code", + FlagMaxArity: "max_arity", + FlagMaxInteger: "max_integer", + FlagMinInteger: "min_integer", + }[f] } -// PermissionError creates a new permission error exception. -func PermissionError(operation, permissionType Atom, culprit Term, env *Env) *Exception { +// RepresentationError creates a new representation error exception. +func RepresentationError(limit Flag, env *Env) Exception { return NewException(&Compound{ Functor: "error", Args: []Term{ &Compound{ - Functor: "permission_error", - Args: []Term{operation, permissionType, culprit}, + Functor: "representation_error", + Args: []Term{limit.Term()}, }, - Atom(fmt.Sprintf("Operation %s not allowed for %s.", operation, permissionType)), + varContext, }, }, env) } -func representationError(limit Atom) *Exception { - return &Exception{ - term: &Compound{ - Functor: "error", - Args: []Term{ - &Compound{ - Functor: "representation_error", - Args: []Term{limit}, - }, - Atom(fmt.Sprintf("Invalid %s.", limit)), - }, - }, - } +type Resource uint8 + +const ( + ResourceFiniteMemory Resource = iota +) + +func (r Resource) Term() Term { + return [...]Atom{ + ResourceFiniteMemory: "finite_memory", + }[r] } -func resourceError(resource, info Term, env *Env) *Exception { +// ResourceError creates a new resource error exception. +func ResourceError(resource Resource, env *Env) Exception { return NewException(&Compound{ Functor: "error", Args: []Term{ &Compound{ Functor: "resource_error", - Args: []Term{resource}, + Args: []Term{resource.Term()}, }, - info, + varContext, }, }, env) } -func syntaxErrorNotANumber() *Exception { - return syntaxError(Atom("not_a_number"), Atom("Not a number.")) +// SyntaxError creates a new syntax error exception. +func SyntaxError(err error, env *Env) Exception { + return NewException(&Compound{ + Functor: "error", + Args: []Term{ + &Compound{ + Functor: "syntax_error", + Args: []Term{Atom(err.Error())}, + }, + varContext, + }, + }, env) } -func syntaxErrorUnexpectedToken(info Term) *Exception { - return syntaxError(Atom("unexpected_token"), info) +// SystemError creates a new system error exception. +func SystemError(err error) Exception { + return NewException(&Compound{ + Functor: "error", + Args: []Term{ + Atom("system_error"), + Atom(err.Error()), + }, + }, nil) } -func syntaxErrorInsufficient() *Exception { - return syntaxError(Atom("insufficient"), Atom("Not enough input.")) -} +type ExceptionalValue uint8 -func syntaxError(detail, info Term) *Exception { - return &Exception{ - term: &Compound{ - Functor: "error", - Args: []Term{ - &Compound{ - Functor: "syntax_error", - Args: []Term{detail}, - }, - info, - }, - }, - } +const ( + ExceptionalValueFloatOverflow ExceptionalValue = iota + ExceptionalValueIntOverflow + ExceptionalValueUnderflow + ExceptionalValueZeroDivisor + ExceptionalValueUndefined +) + +func (ev ExceptionalValue) Error() string { + return string(ev.Term().(Atom)) } -// SystemError creates a new system error exception. -func SystemError(err error) *Exception { - return &Exception{ - term: &Compound{ - Functor: "error", - Args: []Term{ - Atom("system_error"), - Atom(err.Error()), - }, - }, - } +func (ev ExceptionalValue) Term() Term { + return [...]Atom{ + ExceptionalValueFloatOverflow: "float_overflow", + ExceptionalValueIntOverflow: "int_overflow", + ExceptionalValueUnderflow: "underflow", + ExceptionalValueZeroDivisor: "zero_divisor", + ExceptionalValueUndefined: "undefined", + }[ev] } -func evaluationError(error, info Term) *Exception { - return &Exception{ - term: &Compound{ - Functor: "error", - Args: []Term{ - &Compound{ - Functor: "evaluation_error", - Args: []Term{error}, - }, - info, +// EvaluationError creates a new evaluation error exception. +func EvaluationError(ev ExceptionalValue, env *Env) Exception { + return NewException(&Compound{ + Functor: "error", + Args: []Term{ + &Compound{ + Functor: "evaluation_error", + Args: []Term{ev.Term()}, }, + varContext, }, - } + }, env) } diff --git a/engine/exception_test.go b/engine/exception_test.go index 91ec6854..9c01c5aa 100644 --- a/engine/exception_test.go +++ b/engine/exception_test.go @@ -1,6 +1,7 @@ package engine import ( + "errors" "testing" "github.com/stretchr/testify/assert" @@ -10,3 +11,174 @@ func TestException_Error(t *testing.T) { e := Exception{term: Atom("foo")} assert.Equal(t, "foo", e.Error()) } + +func TestInstantiationError(t *testing.T) { + assert.Equal(t, Exception{ + term: &Compound{ + Functor: "error", + Args: []Term{ + Atom("instantiation_error"), + rootContext, + }, + }, + }, InstantiationError(nil)) +} + +func TestTypeError(t *testing.T) { + assert.Equal(t, Exception{ + term: &Compound{ + Functor: "error", + Args: []Term{ + &Compound{ + Functor: "type_error", + Args: []Term{ + Atom("atom"), + Integer(0), + }, + }, + rootContext, + }, + }, + }, TypeError(ValidTypeAtom, Integer(0), nil)) +} + +func TestDomainError(t *testing.T) { + assert.Equal(t, Exception{ + term: &Compound{ + Functor: "error", + Args: []Term{ + &Compound{ + Functor: "domain_error", + Args: []Term{ + Atom("not_less_than_zero"), + Integer(-1), + }, + }, + rootContext, + }, + }, + }, DomainError(ValidDomainNotLessThanZero, Integer(-1), nil)) +} + +func TestExistenceError(t *testing.T) { + pi := ProcedureIndicator{Name: "foo", Arity: 0}.Term() + assert.Equal(t, Exception{ + term: &Compound{ + Functor: "error", + Args: []Term{ + &Compound{ + Functor: "existence_error", + Args: []Term{ + Atom("procedure"), + pi, + }, + }, + rootContext, + }, + }, + }, ExistenceError(ObjectTypeProcedure, pi, nil)) +} + +func TestPermissionError(t *testing.T) { + pi := ProcedureIndicator{Name: "foo", Arity: 0}.Term() + assert.Equal(t, Exception{ + term: &Compound{ + Functor: "error", + Args: []Term{ + &Compound{ + Functor: "permission_error", + Args: []Term{ + Atom("modify"), + Atom("static_procedure"), + pi, + }, + }, + rootContext, + }, + }, + }, PermissionError(OperationModify, PermissionTypeStaticProcedure, pi, nil)) +} + +func TestRepresentationError(t *testing.T) { + assert.Equal(t, Exception{ + term: &Compound{ + Functor: "error", + Args: []Term{ + &Compound{ + Functor: "representation_error", + Args: []Term{ + Atom("max_integer"), + }, + }, + rootContext, + }, + }, + }, RepresentationError(FlagMaxInteger, nil)) +} + +func TestResourceError(t *testing.T) { + assert.Equal(t, Exception{ + term: &Compound{ + Functor: "error", + Args: []Term{ + &Compound{ + Functor: "resource_error", + Args: []Term{ + Atom("finite_memory"), + }, + }, + rootContext, + }, + }, + }, ResourceError(ResourceFiniteMemory, nil)) +} + +func TestSyntaxError(t *testing.T) { + assert.Equal(t, Exception{ + term: &Compound{ + Functor: "error", + Args: []Term{ + &Compound{ + Functor: "syntax_error", + Args: []Term{ + Atom("foo"), + }, + }, + rootContext, + }, + }, + }, SyntaxError(errors.New("foo"), nil)) +} + +func TestSystemError(t *testing.T) { + assert.Equal(t, Exception{ + term: &Compound{ + Functor: "error", + Args: []Term{ + Atom("system_error"), + Atom("foo"), + }, + }, + }, SystemError(errors.New("foo"))) +} + +func TestEvaluationError(t *testing.T) { + assert.Equal(t, Exception{ + term: &Compound{ + Functor: "error", + Args: []Term{ + &Compound{ + Functor: "evaluation_error", + Args: []Term{ + Atom("int_overflow"), + }, + }, + rootContext, + }, + }, + }, EvaluationError(ExceptionalValueIntOverflow, nil)) +} + +func TestExceptionalValue_Error(t *testing.T) { + assert.Equal(t, "int_overflow", ExceptionalValueIntOverflow.Error()) +} diff --git a/engine/iterator.go b/engine/iterator.go index 325f047e..37756326 100644 --- a/engine/iterator.go +++ b/engine/iterator.go @@ -13,37 +13,37 @@ type ListIterator struct { // Next proceeds to the next element of the list and returns true if there's such an element. func (i *ListIterator) Next() bool { if i.rest == nil { - i.rest = i.List + i.rest = i.Env.Resolve(i.List) } if i.visited == nil { i.visited = map[*Compound]struct{}{} } - switch l := i.Env.Resolve(i.rest).(type) { + switch l := i.rest.(type) { case Variable: - i.err = ErrInstantiation + i.err = InstantiationError(i.Env) return false case Atom: if l != "[]" { - i.err = TypeErrorList(i.List, i.Env) + i.err = TypeError(ValidTypeList, i.List, i.Env) } return false case *Compound: if l.Functor != "." || len(l.Args) != 2 { - i.err = TypeErrorList(i.List, i.Env) + i.err = TypeError(ValidTypeList, i.List, i.Env) return false } if _, ok := i.visited[l]; ok { - i.err = TypeErrorList(i.List, i.Env) + i.err = TypeError(ValidTypeList, i.List, i.Env) return false } i.visited[l] = struct{}{} - i.current, i.rest = l.Args[0], l.Args[1] + i.current, i.rest = l.Args[0], i.Env.Resolve(l.Args[1]) return true default: - i.err = TypeErrorList(i.List, i.Env) + i.err = TypeError(ValidTypeList, i.List, i.Env) return false } } @@ -58,6 +58,10 @@ func (i *ListIterator) Err() error { return i.err } +func (i *ListIterator) Suffix() Term { + return i.rest +} + // SeqIterator is an iterator for a sequence. type SeqIterator struct { Seq Term diff --git a/engine/iterator_test.go b/engine/iterator_test.go index a3363429..648120ac 100644 --- a/engine/iterator_test.go +++ b/engine/iterator_test.go @@ -27,7 +27,7 @@ func TestListIterator_Next(t *testing.T) { assert.True(t, iter.Next()) assert.Equal(t, Atom("b"), iter.Current()) assert.False(t, iter.Next()) - assert.Equal(t, ErrInstantiation, iter.Err()) + assert.Equal(t, InstantiationError(nil), iter.Err()) }) t.Run("atom", func(t *testing.T) { @@ -37,7 +37,7 @@ func TestListIterator_Next(t *testing.T) { assert.True(t, iter.Next()) assert.Equal(t, Atom("b"), iter.Current()) assert.False(t, iter.Next()) - assert.Equal(t, TypeErrorList(ListRest(Atom("foo"), Atom("a"), Atom("b")), nil), iter.Err()) + assert.Equal(t, TypeError(ValidTypeList, ListRest(Atom("foo"), Atom("a"), Atom("b")), nil), iter.Err()) }) t.Run("compound", func(t *testing.T) { @@ -47,7 +47,7 @@ func TestListIterator_Next(t *testing.T) { assert.True(t, iter.Next()) assert.Equal(t, Atom("b"), iter.Current()) assert.False(t, iter.Next()) - assert.Equal(t, TypeErrorList(ListRest(Atom("f").Apply(Integer(0)), Atom("a"), Atom("b")), nil), iter.Err()) + assert.Equal(t, TypeError(ValidTypeList, ListRest(Atom("f").Apply(Integer(0)), Atom("a"), Atom("b")), nil), iter.Err()) }) t.Run("other", func(t *testing.T) { @@ -57,7 +57,7 @@ func TestListIterator_Next(t *testing.T) { assert.True(t, iter.Next()) assert.Equal(t, Atom("b"), iter.Current()) assert.False(t, iter.Next()) - assert.Equal(t, TypeErrorList(ListRest(&mockTerm{}, Atom("a"), Atom("b")), nil), iter.Err()) + assert.Equal(t, TypeError(ValidTypeList, ListRest(&mockTerm{}, Atom("a"), Atom("b")), nil), iter.Err()) }) t.Run("circular list", func(t *testing.T) { @@ -67,7 +67,7 @@ func TestListIterator_Next(t *testing.T) { assert.True(t, iter.Next()) assert.Equal(t, Atom("a"), iter.Current()) assert.False(t, iter.Next()) - assert.Equal(t, TypeErrorList(l, env), iter.Err()) + assert.Equal(t, TypeError(ValidTypeList, l, env), iter.Err()) }) }) } @@ -148,7 +148,7 @@ func TestAnyIterator_Next(t *testing.T) { assert.True(t, iter.Next()) assert.Equal(t, Atom("b"), iter.Current()) assert.False(t, iter.Next()) - assert.Equal(t, ErrInstantiation, iter.Err()) + assert.Equal(t, InstantiationError(nil), iter.Err()) }) t.Run("atom", func(t *testing.T) { @@ -158,7 +158,7 @@ func TestAnyIterator_Next(t *testing.T) { assert.True(t, iter.Next()) assert.Equal(t, Atom("b"), iter.Current()) assert.False(t, iter.Next()) - assert.Equal(t, TypeErrorList(ListRest(Atom("foo"), Atom("a"), Atom("b")), nil), iter.Err()) + assert.Equal(t, TypeError(ValidTypeList, ListRest(Atom("foo"), Atom("a"), Atom("b")), nil), iter.Err()) }) }) diff --git a/engine/number.go b/engine/number.go index 36a369a2..3d996c6b 100644 --- a/engine/number.go +++ b/engine/number.go @@ -1,6 +1,9 @@ package engine -import "math" +import ( + "errors" + "math" +) // DefaultEvaluableFunctors is a EvaluableFunctors with builtin functions. var DefaultEvaluableFunctors = EvaluableFunctors{ @@ -295,14 +298,21 @@ func (e EvaluableFunctors) GreaterThanOrEqual(e1, e2 Term, k func(*Env) *Promise return k(env) } -func (e EvaluableFunctors) eval(expression Term, env *Env) (Number, error) { +func (e EvaluableFunctors) eval(expression Term, env *Env) (_ Number, err error) { + defer func() { + var ev ExceptionalValue + if errors.As(err, &ev) { + err = EvaluationError(ev, env) + } + }() + switch t := env.Resolve(expression).(type) { case Variable: - return nil, ErrInstantiation + return nil, InstantiationError(env) case Atom: c, ok := e.Constant[t] if !ok { - return nil, TypeErrorEvaluable(&Compound{ + return nil, TypeError(ValidTypeEvaluable, &Compound{ Functor: "/", Args: []Term{t, Integer(0)}, }, env) @@ -315,7 +325,7 @@ func (e EvaluableFunctors) eval(expression Term, env *Env) (Number, error) { case 1: f, ok := e.Unary[t.Functor] if !ok { - return nil, TypeErrorEvaluable(&Compound{ + return nil, TypeError(ValidTypeEvaluable, &Compound{ Functor: "/", Args: []Term{ t.Functor, @@ -331,7 +341,7 @@ func (e EvaluableFunctors) eval(expression Term, env *Env) (Number, error) { case 2: f, ok := e.Binary[t.Functor] if !ok { - return nil, TypeErrorEvaluable(&Compound{ + return nil, TypeError(ValidTypeEvaluable, &Compound{ Functor: "/", Args: []Term{ t.Functor, @@ -349,13 +359,13 @@ func (e EvaluableFunctors) eval(expression Term, env *Env) (Number, error) { } return f(x, y) default: - return nil, TypeErrorEvaluable(&Compound{ + return nil, TypeError(ValidTypeEvaluable, &Compound{ Functor: "/", Args: []Term{t.Functor, Integer(arity)}, }, env) } default: - return nil, TypeErrorEvaluable(&Compound{ + return nil, TypeError(ValidTypeEvaluable, &Compound{ Functor: "/", Args: []Term{t, Integer(0)}, }, env) @@ -380,7 +390,7 @@ func Add(x, y Number) (Number, error) { return addF(x, y) } } - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } // Sub returns subtraction of 2 numbers. @@ -401,7 +411,7 @@ func Sub(x, y Number) (Number, error) { return subF(x, y) } } - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } // Mul returns multiplication of 2 numbers. @@ -422,7 +432,7 @@ func Mul(x, y Number) (Number, error) { return mulF(x, y) } } - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } // IntDiv returns integer division of 2 numbers. @@ -433,10 +443,10 @@ func IntDiv(x, y Number) (Number, error) { case Integer: return intDivI(x, y) default: - return nil, TypeErrorInteger(y, nil) + return nil, TypeError(ValidTypeInteger, y, nil) } default: - return nil, TypeErrorInteger(x, nil) + return nil, TypeError(ValidTypeInteger, x, nil) } } @@ -458,7 +468,7 @@ func Div(x, y Number) (Number, error) { return divF(x, y) } } - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } // Rem returns remainder of 2 numbers. @@ -469,10 +479,10 @@ func Rem(x, y Number) (Number, error) { case Integer: return remI(x, y) default: - return nil, TypeErrorInteger(y, nil) + return nil, TypeError(ValidTypeInteger, y, nil) } default: - return nil, TypeErrorInteger(x, nil) + return nil, TypeError(ValidTypeInteger, x, nil) } } @@ -484,10 +494,10 @@ func Mod(x, y Number) (Number, error) { case Integer: return modI(x, y) default: - return nil, TypeErrorInteger(y, nil) + return nil, TypeError(ValidTypeInteger, y, nil) } default: - return nil, TypeErrorInteger(x, nil) + return nil, TypeError(ValidTypeInteger, x, nil) } } @@ -499,7 +509,7 @@ func Neg(x Number) (Number, error) { case Float: return negF(x), nil default: - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } } @@ -511,7 +521,7 @@ func Abs(x Number) (Number, error) { case Float: return absF(x), nil default: - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } } @@ -523,7 +533,7 @@ func Sign(x Number) (Number, error) { case Float: return signF(x), nil default: - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } } @@ -533,7 +543,7 @@ func FloatIntegerPart(x Number) (Number, error) { case Float: return intPartF(x), nil default: - return nil, TypeErrorFloat(x, nil) + return nil, TypeError(ValidTypeFloat, x, nil) } } @@ -543,7 +553,7 @@ func FloatFractionalPart(x Number) (Number, error) { case Float: return fractPartF(x), nil default: - return nil, TypeErrorFloat(x, nil) + return nil, TypeError(ValidTypeFloat, x, nil) } } @@ -555,7 +565,7 @@ func AsFloat(x Number) (Number, error) { case Float: return floatFtoF(x), nil default: - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } } @@ -565,7 +575,7 @@ func Floor(x Number) (Number, error) { case Float: return floorFtoI(x) default: - return nil, TypeErrorFloat(x, nil) + return nil, TypeError(ValidTypeFloat, x, nil) } } @@ -575,7 +585,7 @@ func Truncate(x Number) (Number, error) { case Float: return truncateFtoI(x) default: - return nil, TypeErrorFloat(x, nil) + return nil, TypeError(ValidTypeFloat, x, nil) } } @@ -585,7 +595,7 @@ func Round(x Number) (Number, error) { case Float: return roundFtoI(x) default: - return nil, TypeErrorFloat(x, nil) + return nil, TypeError(ValidTypeFloat, x, nil) } } @@ -595,7 +605,7 @@ func Ceiling(x Number) (Number, error) { case Float: return ceilingFtoI(x) default: - return nil, TypeErrorFloat(x, nil) + return nil, TypeError(ValidTypeFloat, x, nil) } } @@ -608,7 +618,7 @@ func Power(x, y Number) (Number, error) { case Float: vx = float64(x) default: - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } var vy float64 @@ -618,23 +628,23 @@ func Power(x, y Number) (Number, error) { case Float: vy = float64(y) default: - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } // 9.3.1.3 d) special case if vx == 0 && vy < 0 { - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } r := Float(math.Pow(vx, vy)) switch { case math.IsInf(float64(r), 0): - return nil, ErrFloatOverflow + return nil, ExceptionalValueFloatOverflow case r == 0 && vx != 0: // Underflow: r can be 0 iff x = 0. - return nil, ErrUnderflow + return nil, ExceptionalValueUnderflow case math.IsNaN(float64(r)): - return nil, ErrUndefined + return nil, ExceptionalValueUndefined default: return r, nil } @@ -648,7 +658,7 @@ func Sin(x Number) (Number, error) { case Float: return Float(math.Sin(float64(x))), nil default: - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } } @@ -660,7 +670,7 @@ func Cos(x Number) (Number, error) { case Float: return Float(math.Cos(float64(x))), nil default: - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } } @@ -672,7 +682,7 @@ func Atan(x Number) (Number, error) { case Float: return Float(math.Atan(float64(x))), nil default: - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } } @@ -685,7 +695,7 @@ func Exp(x Number) (Number, error) { case Float: vx = float64(x) default: - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } // Positive overflow: @@ -694,13 +704,13 @@ func Exp(x Number) (Number, error) { // x * log(e) > log(max) // x > log(max) if vx > math.Log(math.MaxFloat64) { - return nil, ErrFloatOverflow + return nil, ExceptionalValueFloatOverflow } r := Float(math.Exp(vx)) if r == 0 { // e^x != 0. - return nil, ErrUnderflow + return nil, ExceptionalValueUnderflow } return r, nil @@ -715,11 +725,11 @@ func Log(x Number) (Number, error) { case Float: vx = float64(x) default: - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } if vx <= 0 { - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } return Float(math.Log(vx)), nil @@ -734,11 +744,11 @@ func Sqrt(x Number) (Number, error) { case Float: vx = float64(x) default: - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } if vx < 0 { - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } return Float(math.Sqrt(vx)), nil @@ -752,10 +762,10 @@ func BitwiseRightShift(n, s Number) (Number, error) { case Integer: return Integer(n >> s), nil default: - return nil, TypeErrorInteger(s, nil) + return nil, TypeError(ValidTypeInteger, s, nil) } default: - return nil, TypeErrorInteger(n, nil) + return nil, TypeError(ValidTypeInteger, n, nil) } } @@ -767,10 +777,10 @@ func BitwiseLeftShift(n, s Number) (Number, error) { case Integer: return Integer(n << s), nil default: - return nil, TypeErrorInteger(s, nil) + return nil, TypeError(ValidTypeInteger, s, nil) } default: - return nil, TypeErrorInteger(n, nil) + return nil, TypeError(ValidTypeInteger, n, nil) } } @@ -782,10 +792,10 @@ func BitwiseAnd(b1, b2 Number) (Number, error) { case Integer: return b1 & b2, nil default: - return nil, TypeErrorInteger(b2, nil) + return nil, TypeError(ValidTypeInteger, b2, nil) } default: - return nil, TypeErrorInteger(b1, nil) + return nil, TypeError(ValidTypeInteger, b1, nil) } } @@ -797,10 +807,10 @@ func BitwiseOr(b1, b2 Number) (Number, error) { case Integer: return b1 | b2, nil default: - return nil, TypeErrorInteger(b2, nil) + return nil, TypeError(ValidTypeInteger, b2, nil) } default: - return nil, TypeErrorInteger(b1, nil) + return nil, TypeError(ValidTypeInteger, b1, nil) } } @@ -810,7 +820,7 @@ func BitwiseComplement(b1 Number) (Number, error) { case Integer: return ^b1, nil default: - return nil, TypeErrorInteger(b1, nil) + return nil, TypeError(ValidTypeInteger, b1, nil) } } @@ -822,7 +832,7 @@ func Pos(x Number) (Number, error) { case Float: return posF(x) default: - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } } @@ -834,10 +844,10 @@ func IntFloorDiv(x, y Number) (Number, error) { case Integer: return intFloorDivI(x, y) default: - return nil, TypeErrorInteger(y, nil) + return nil, TypeError(ValidTypeInteger, y, nil) } default: - return nil, TypeErrorInteger(x, nil) + return nil, TypeError(ValidTypeInteger, x, nil) } } @@ -857,7 +867,7 @@ func Max(x, y Number) (Number, error) { } return x, nil default: - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } case Float: switch y := y.(type) { @@ -872,10 +882,10 @@ func Max(x, y Number) (Number, error) { } return x, nil default: - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } default: - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } } @@ -895,7 +905,7 @@ func Min(x, y Number) (Number, error) { } return x, nil default: - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } case Float: switch y := y.(type) { @@ -910,10 +920,10 @@ func Min(x, y Number) (Number, error) { } return x, nil default: - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } default: - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } } @@ -932,7 +942,7 @@ func IntegerPower(x, y Number) (Number, error) { if vy < 0 { switch vx { case 0: - return nil, ErrUndefined + return nil, ExceptionalValueUndefined case 1, -1: vy, err := negI(vy) // y can be math.MinInt64 if err != nil { @@ -941,7 +951,7 @@ func IntegerPower(x, y Number) (Number, error) { r, _ := intPow(vx, vy) // Since x is either 1 or -1, no errors occur. return intDivI(1, r) default: - return nil, TypeErrorFloat(vx, nil) + return nil, TypeError(ValidTypeFloat, vx, nil) } } @@ -984,11 +994,11 @@ func Asin(x Number) (Number, error) { case Float: vx = float64(x) default: - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } if vx > 1 || vx < -1 { - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } return Float(math.Asin(vx)), nil @@ -1003,11 +1013,11 @@ func Acos(x Number) (Number, error) { case Float: vx = float64(x) default: - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } if vx > 1 || vx < -1 { - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } return Float(math.Acos(vx)), nil @@ -1022,7 +1032,7 @@ func Atan2(y, x Number) (Number, error) { case Float: vy = float64(y) default: - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } var vx float64 @@ -1032,11 +1042,11 @@ func Atan2(y, x Number) (Number, error) { case Float: vx = float64(x) default: - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } if vx == 0 && vy == 0 { - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } return Float(math.Atan2(vy, vx)), nil @@ -1051,7 +1061,7 @@ func Tan(x Number) (Number, error) { case Float: vx = float64(x) default: - return nil, ErrUndefined + return nil, ExceptionalValueUndefined } return Float(math.Tan(vx)), nil @@ -1061,12 +1071,12 @@ func Tan(x Number) (Number, error) { func Xor(x, y Number) (Number, error) { vx, ok := x.(Integer) if !ok { - return nil, TypeErrorInteger(x, nil) + return nil, TypeError(ValidTypeInteger, x, nil) } vy, ok := y.(Integer) if !ok { - return nil, TypeErrorInteger(y, nil) + return nil, TypeError(ValidTypeInteger, y, nil) } return vx ^ vy, nil @@ -1189,7 +1199,7 @@ func floatFtoF(x Float) Float { func floorFtoI(x Float) (Integer, error) { f := math.Floor(float64(x)) if f > math.MaxInt64 || f < math.MinInt64 { - return 0, ErrIntOverflow + return 0, ExceptionalValueIntOverflow } return Integer(f), nil } @@ -1197,7 +1207,7 @@ func floorFtoI(x Float) (Integer, error) { func truncateFtoI(x Float) (Integer, error) { t := math.Trunc(float64(x)) if t > math.MaxInt64 || t < math.MinInt64 { - return 0, ErrIntOverflow + return 0, ExceptionalValueIntOverflow } return Integer(t), nil } @@ -1205,7 +1215,7 @@ func truncateFtoI(x Float) (Integer, error) { func roundFtoI(x Float) (Integer, error) { r := math.Round(float64(x)) if r > math.MaxInt64 || r < math.MinInt64 { - return 0, ErrIntOverflow + return 0, ExceptionalValueIntOverflow } return Integer(r), nil } @@ -1213,7 +1223,7 @@ func roundFtoI(x Float) (Integer, error) { func ceilingFtoI(x Float) (Integer, error) { c := math.Ceil(float64(x)) if c > math.MaxInt64 || c < math.MinInt64 { - return 0, ErrIntOverflow + return 0, ExceptionalValueIntOverflow } return Integer(c), nil } @@ -1223,9 +1233,9 @@ func ceilingFtoI(x Float) (Integer, error) { func addI(x, y Integer) (Integer, error) { switch { case y > 0 && x > math.MaxInt64-y: - return 0, ErrIntOverflow + return 0, ExceptionalValueIntOverflow case y < 0 && x < math.MinInt64-y: - return 0, ErrIntOverflow + return 0, ExceptionalValueIntOverflow default: return x + y, nil } @@ -1234,9 +1244,9 @@ func addI(x, y Integer) (Integer, error) { func subI(x, y Integer) (Integer, error) { switch { case y < 0 && x > math.MaxInt64+y: - return 0, ErrIntOverflow + return 0, ExceptionalValueIntOverflow case y > 0 && x < math.MinInt64+y: - return 0, ErrIntOverflow + return 0, ExceptionalValueIntOverflow default: return x - y, nil } @@ -1245,15 +1255,15 @@ func subI(x, y Integer) (Integer, error) { func mulI(x, y Integer) (Integer, error) { switch { case x == -1 && y == math.MinInt64: - return 0, ErrIntOverflow + return 0, ExceptionalValueIntOverflow case x == math.MinInt64 && y == -1: - return 0, ErrIntOverflow + return 0, ExceptionalValueIntOverflow case y == 0: return 0, nil default: r := x * y if r/y != x { - return 0, ErrIntOverflow + return 0, ExceptionalValueIntOverflow } return r, nil } @@ -1262,10 +1272,10 @@ func mulI(x, y Integer) (Integer, error) { func intDivI(x, y Integer) (Integer, error) { switch { case y == 0: - return 0, ErrZeroDivisor + return 0, ExceptionalValueZeroDivisor case x == math.MinInt64 && y == -1: // Two's complement special case - return 0, ErrIntOverflow + return 0, ExceptionalValueIntOverflow default: return x / y, nil } @@ -1273,14 +1283,14 @@ func intDivI(x, y Integer) (Integer, error) { func remI(x, y Integer) (Integer, error) { if y == 0 { - return 0, ErrZeroDivisor + return 0, ExceptionalValueZeroDivisor } return x - ((x / y) * y), nil } func modI(x, y Integer) (Integer, error) { if y == 0 { - return 0, ErrZeroDivisor + return 0, ExceptionalValueZeroDivisor } return x - (Integer(math.Floor(float64(x)/float64(y))) * y), nil } @@ -1288,7 +1298,7 @@ func modI(x, y Integer) (Integer, error) { func negI(x Integer) (Integer, error) { // Two's complement special case if x == math.MinInt64 { - return 0, ErrIntOverflow + return 0, ExceptionalValueIntOverflow } return -x, nil } @@ -1296,7 +1306,7 @@ func negI(x Integer) (Integer, error) { func absI(x Integer) (Integer, error) { switch { case x == math.MinInt64: - return 0, ErrIntOverflow + return 0, ExceptionalValueIntOverflow case x < 0: return -x, nil default: @@ -1322,9 +1332,9 @@ func posI(x Integer) (Integer, error) { func intFloorDivI(x, y Integer) (Integer, error) { switch { case x == math.MinInt64 && y == -1: - return 0, ErrIntOverflow + return 0, ExceptionalValueIntOverflow case y == 0: - return 0, ErrZeroDivisor + return 0, ExceptionalValueZeroDivisor default: return Integer(math.Floor(float64(x) / float64(y))), nil } @@ -1335,9 +1345,9 @@ func intFloorDivI(x, y Integer) (Integer, error) { func addF(x, y Float) (Float, error) { switch { case y > 0 && x > math.MaxFloat64-y: - return 0, ErrFloatOverflow + return 0, ExceptionalValueFloatOverflow case y < 0 && x < -math.MaxFloat64-y: - return 0, ErrFloatOverflow + return 0, ExceptionalValueFloatOverflow } return x + y, nil @@ -1350,16 +1360,16 @@ func subF(x, y Float) (Float, error) { func mulF(x, y Float) (Float, error) { switch { case y != 0 && x > math.MaxFloat64/y: - return 0, ErrFloatOverflow + return 0, ExceptionalValueFloatOverflow case y != 0 && x < -math.MaxFloat64/y: - return 0, ErrFloatOverflow + return 0, ExceptionalValueFloatOverflow } r := x * y // Underflow: x*y = 0 iff x = 0 or y = 0. if r == 0 && x != 0 && y != 0 { - return 0, ErrUnderflow + return 0, ExceptionalValueUnderflow } return r, nil @@ -1368,18 +1378,18 @@ func mulF(x, y Float) (Float, error) { func divF(x, y Float) (Float, error) { switch { case y == 0: - return 0, ErrZeroDivisor + return 0, ExceptionalValueZeroDivisor case x > math.MaxFloat64*y: - return 0, ErrFloatOverflow + return 0, ExceptionalValueFloatOverflow case x < -math.MaxFloat64*y: - return 0, ErrFloatOverflow + return 0, ExceptionalValueFloatOverflow } r := x / y // Underflow: x/y = 0 iff x = 0 and y != 0. if r == 0 && x != 0 { - return 0, ErrUnderflow + return 0, ExceptionalValueUnderflow } return r, nil diff --git a/engine/number_test.go b/engine/number_test.go index 6ffbb898..2f0974e2 100644 --- a/engine/number_test.go +++ b/engine/number_test.go @@ -18,6 +18,21 @@ func TestEvaluableFunctors_Is(t *testing.T) { "foo": func(_ Number) (Number, error) { return Integer(1), nil }, + "zero_divisor": func(_ Number) (Number, error) { + return nil, ExceptionalValueZeroDivisor + }, + "int_overflow": func(_ Number) (Number, error) { + return nil, ExceptionalValueIntOverflow + }, + "float_overflow": func(_ Number) (Number, error) { + return nil, ExceptionalValueFloatOverflow + }, + "underflow": func(_ Number) (Number, error) { + return nil, ExceptionalValueUnderflow + }, + "undefined": func(_ Number) (Number, error) { + return nil, ExceptionalValueUndefined + }, }, Binary: map[Atom]func(x Number, y Number) (Number, error){ "foo": func(_, _ Number) (Number, error) { @@ -55,6 +70,11 @@ func TestEvaluableFunctors_Is(t *testing.T) { _, err := efs.Is(Integer(1), Atom("foo").Apply(Variable("X")), Success, nil).Force(context.Background()) assert.Error(t, err) }) + + t.Run("exceptional value", func(t *testing.T) { + _, err := efs.Is(Integer(1), Atom("undefined").Apply(Integer(0)), Success, nil).Force(context.Background()) + assert.Error(t, err) + }) }) t.Run("binary", func(t *testing.T) { @@ -388,12 +408,12 @@ func TestAdd(t *testing.T) { t.Run("overflow", func(t *testing.T) { t.Run("positive", func(t *testing.T) { _, err := Add(Integer(math.MaxInt64), Integer(1)) - assert.Equal(t, ErrIntOverflow, err) + assert.Equal(t, ExceptionalValueIntOverflow, err) }) t.Run("negative", func(t *testing.T) { _, err := Add(Integer(math.MinInt64), Integer(-1)) - assert.Equal(t, ErrIntOverflow, err) + assert.Equal(t, ExceptionalValueIntOverflow, err) }) }) }) @@ -408,12 +428,12 @@ func TestAdd(t *testing.T) { t.Run("overflow", func(t *testing.T) { t.Run("positive", func(t *testing.T) { _, err := Add(Integer(1), Float(math.MaxFloat64)) - assert.Equal(t, ErrFloatOverflow, err) + assert.Equal(t, ExceptionalValueFloatOverflow, err) }) t.Run("negative", func(t *testing.T) { _, err := Add(Integer(-1), Float(-math.MaxFloat64)) - assert.Equal(t, ErrFloatOverflow, err) + assert.Equal(t, ExceptionalValueFloatOverflow, err) }) }) }) @@ -438,12 +458,12 @@ func TestAdd(t *testing.T) { t.Run("overflow", func(t *testing.T) { t.Run("positive", func(t *testing.T) { _, err := Add(Float(math.MaxFloat64), Float(math.MaxFloat64)) - assert.Equal(t, ErrFloatOverflow, err) + assert.Equal(t, ExceptionalValueFloatOverflow, err) }) t.Run("negative", func(t *testing.T) { _, err := Add(Float(-math.MaxFloat64), Float(-math.MaxFloat64)) - assert.Equal(t, ErrFloatOverflow, err) + assert.Equal(t, ExceptionalValueFloatOverflow, err) }) }) }) @@ -451,7 +471,7 @@ func TestAdd(t *testing.T) { t.Run("not a number", func(t *testing.T) { _, err := Add(&mockNumber{}, Integer(0)) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) } @@ -467,12 +487,12 @@ func TestSub(t *testing.T) { t.Run("overflow", func(t *testing.T) { t.Run("positive", func(t *testing.T) { _, err := Sub(Integer(math.MaxInt64), Integer(-1)) - assert.Equal(t, ErrIntOverflow, err) + assert.Equal(t, ExceptionalValueIntOverflow, err) }) t.Run("negative", func(t *testing.T) { _, err := Sub(Integer(math.MinInt64), Integer(1)) - assert.Equal(t, ErrIntOverflow, err) + assert.Equal(t, ExceptionalValueIntOverflow, err) }) }) }) @@ -487,12 +507,12 @@ func TestSub(t *testing.T) { t.Run("overflow", func(t *testing.T) { t.Run("positive", func(t *testing.T) { _, err := Sub(Integer(1), Float(-math.MaxFloat64)) - assert.Equal(t, ErrFloatOverflow, err) + assert.Equal(t, ExceptionalValueFloatOverflow, err) }) t.Run("negative", func(t *testing.T) { _, err := Sub(Integer(-1), Float(math.MaxFloat64)) - assert.Equal(t, ErrFloatOverflow, err) + assert.Equal(t, ExceptionalValueFloatOverflow, err) }) }) }) @@ -517,12 +537,12 @@ func TestSub(t *testing.T) { t.Run("overflow", func(t *testing.T) { t.Run("positive", func(t *testing.T) { _, err := Sub(Float(math.MaxFloat64), Float(-math.MaxFloat64)) - assert.Equal(t, ErrFloatOverflow, err) + assert.Equal(t, ExceptionalValueFloatOverflow, err) }) t.Run("negative", func(t *testing.T) { _, err := Sub(Float(-math.MaxFloat64), Float(math.MaxFloat64)) - assert.Equal(t, ErrFloatOverflow, err) + assert.Equal(t, ExceptionalValueFloatOverflow, err) }) }) }) @@ -530,7 +550,7 @@ func TestSub(t *testing.T) { t.Run("not a number", func(t *testing.T) { _, err := Sub(&mockNumber{}, Integer(0)) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) } @@ -552,19 +572,19 @@ func TestMul(t *testing.T) { t.Run("overflow", func(t *testing.T) { t.Run("positive", func(t *testing.T) { _, err := Mul(Integer(math.MaxInt64), Integer(2)) - assert.Equal(t, ErrIntOverflow, err) + assert.Equal(t, ExceptionalValueIntOverflow, err) }) t.Run("negative", func(t *testing.T) { _, err := Mul(Integer(math.MinInt64), Integer(2)) - assert.Equal(t, ErrIntOverflow, err) + assert.Equal(t, ExceptionalValueIntOverflow, err) }) t.Run("two's complement special case", func(t *testing.T) { _, err := Mul(Integer(-1), Integer(math.MinInt64)) - assert.Equal(t, ErrIntOverflow, err) + assert.Equal(t, ExceptionalValueIntOverflow, err) _, err = Mul(Integer(math.MinInt64), Integer(-1)) - assert.Equal(t, ErrIntOverflow, err) + assert.Equal(t, ExceptionalValueIntOverflow, err) }) }) }) @@ -579,12 +599,12 @@ func TestMul(t *testing.T) { t.Run("overflow", func(t *testing.T) { t.Run("positive", func(t *testing.T) { _, err := Mul(Integer(2), Float(math.MaxFloat64)) - assert.Equal(t, ErrFloatOverflow, err) + assert.Equal(t, ExceptionalValueFloatOverflow, err) }) t.Run("negative", func(t *testing.T) { _, err := Mul(Integer(2), Float(-math.MaxFloat64)) - assert.Equal(t, ErrFloatOverflow, err) + assert.Equal(t, ExceptionalValueFloatOverflow, err) }) }) }) @@ -601,12 +621,12 @@ func TestMul(t *testing.T) { t.Run("overflow", func(t *testing.T) { t.Run("positive", func(t *testing.T) { _, err := Mul(Float(math.MaxFloat64), Integer(2)) - assert.Equal(t, ErrFloatOverflow, err) + assert.Equal(t, ExceptionalValueFloatOverflow, err) }) t.Run("negative", func(t *testing.T) { _, err := Mul(Float(-math.MaxFloat64), Integer(2)) - assert.Equal(t, ErrFloatOverflow, err) + assert.Equal(t, ExceptionalValueFloatOverflow, err) }) }) }) @@ -621,25 +641,25 @@ func TestMul(t *testing.T) { t.Run("overflow", func(t *testing.T) { t.Run("positive", func(t *testing.T) { _, err := Mul(Float(2), Float(math.MaxFloat64)) - assert.Equal(t, ErrFloatOverflow, err) + assert.Equal(t, ExceptionalValueFloatOverflow, err) }) t.Run("negative", func(t *testing.T) { _, err := Mul(Float(-2), Float(math.MaxFloat64)) - assert.Equal(t, ErrFloatOverflow, err) + assert.Equal(t, ExceptionalValueFloatOverflow, err) }) }) t.Run("underflow", func(t *testing.T) { _, err := Mul(Float(0.5), Float(math.SmallestNonzeroFloat64)) - assert.Equal(t, ErrUnderflow, err) + assert.Equal(t, ExceptionalValueUnderflow, err) }) }) }) t.Run("not a number", func(t *testing.T) { _, err := Mul(&mockNumber{}, Integer(0)) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) } @@ -654,24 +674,24 @@ func TestIntDiv(t *testing.T) { t.Run("overflow", func(t *testing.T) { _, err := IntDiv(Integer(math.MinInt64), Integer(-1)) - assert.Equal(t, ErrIntOverflow, err) + assert.Equal(t, ExceptionalValueIntOverflow, err) }) t.Run("divided by zero", func(t *testing.T) { _, err := IntDiv(Integer(1), Integer(0)) - assert.Equal(t, ErrZeroDivisor, err) + assert.Equal(t, ExceptionalValueZeroDivisor, err) }) }) t.Run("not an integer", func(t *testing.T) { _, err := IntDiv(Integer(1), Float(1)) - assert.Equal(t, TypeErrorInteger(Float(1), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Float(1), nil), err) }) }) t.Run("not an integer", func(t *testing.T) { _, err := IntDiv(Float(1), Integer(1)) - assert.Equal(t, TypeErrorInteger(Float(1), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Float(1), nil), err) }) } @@ -686,7 +706,7 @@ func TestDiv(t *testing.T) { t.Run("divide by zero", func(t *testing.T) { _, err := Div(Integer(1), Integer(0)) - assert.Equal(t, ErrZeroDivisor, err) + assert.Equal(t, ExceptionalValueZeroDivisor, err) }) }) @@ -699,7 +719,7 @@ func TestDiv(t *testing.T) { t.Run("divide by zero", func(t *testing.T) { _, err := Div(Integer(1), Float(0)) - assert.Equal(t, ErrZeroDivisor, err) + assert.Equal(t, ExceptionalValueZeroDivisor, err) }) }) }) @@ -714,12 +734,12 @@ func TestDiv(t *testing.T) { t.Run("divide by zero", func(t *testing.T) { _, err := Div(Float(1), Integer(0)) - assert.Equal(t, ErrZeroDivisor, err) + assert.Equal(t, ExceptionalValueZeroDivisor, err) }) t.Run("underflow", func(t *testing.T) { _, err := Div(Float(math.SmallestNonzeroFloat64), Integer(2)) - assert.Equal(t, ErrUnderflow, err) + assert.Equal(t, ExceptionalValueUnderflow, err) }) }) @@ -732,31 +752,31 @@ func TestDiv(t *testing.T) { t.Run("divide by zero", func(t *testing.T) { _, err := Div(Float(1), Float(0)) - assert.Equal(t, ErrZeroDivisor, err) + assert.Equal(t, ExceptionalValueZeroDivisor, err) }) t.Run("overflow", func(t *testing.T) { t.Run("positive", func(t *testing.T) { _, err := Div(Float(math.MaxFloat64), Float(0.5)) - assert.Equal(t, ErrFloatOverflow, err) + assert.Equal(t, ExceptionalValueFloatOverflow, err) }) t.Run("negative", func(t *testing.T) { _, err := Div(Float(-math.MaxFloat64), Float(0.5)) - assert.Equal(t, ErrFloatOverflow, err) + assert.Equal(t, ExceptionalValueFloatOverflow, err) }) }) t.Run("underflow", func(t *testing.T) { _, err := Div(Float(math.SmallestNonzeroFloat64), Float(2)) - assert.Equal(t, ErrUnderflow, err) + assert.Equal(t, ExceptionalValueUnderflow, err) }) }) }) t.Run("not a number", func(t *testing.T) { _, err := Div(&mockNumber{}, Integer(1)) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) } @@ -771,19 +791,19 @@ func TestRem(t *testing.T) { t.Run("divided by zero", func(t *testing.T) { _, err := Rem(Integer(1), Integer(0)) - assert.Equal(t, ErrZeroDivisor, err) + assert.Equal(t, ExceptionalValueZeroDivisor, err) }) }) t.Run("not an integer", func(t *testing.T) { _, err := Rem(Integer(1), &mockNumber{}) - assert.Equal(t, TypeErrorInteger(&mockNumber{}, nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, &mockNumber{}, nil), err) }) }) t.Run("not an integer", func(t *testing.T) { _, err := Rem(&mockNumber{}, Integer(1)) - assert.Equal(t, TypeErrorInteger(&mockNumber{}, nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, &mockNumber{}, nil), err) }) } @@ -798,19 +818,19 @@ func TestMod(t *testing.T) { t.Run("divided by zero", func(t *testing.T) { _, err := Mod(Integer(1), Integer(0)) - assert.Equal(t, ErrZeroDivisor, err) + assert.Equal(t, ExceptionalValueZeroDivisor, err) }) }) t.Run("not an integer", func(t *testing.T) { _, err := Mod(Integer(1), &mockNumber{}) - assert.Equal(t, TypeErrorInteger(&mockNumber{}, nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, &mockNumber{}, nil), err) }) }) t.Run("not an integer", func(t *testing.T) { _, err := Mod(&mockNumber{}, Integer(1)) - assert.Equal(t, TypeErrorInteger(&mockNumber{}, nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, &mockNumber{}, nil), err) }) } @@ -829,7 +849,7 @@ func TestPos(t *testing.T) { t.Run("not a number", func(t *testing.T) { _, err := Pos(&mockNumber{}) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) } @@ -843,7 +863,7 @@ func TestNeg(t *testing.T) { t.Run("overflow", func(t *testing.T) { _, err := Neg(Integer(math.MinInt64)) - assert.Equal(t, ErrIntOverflow, err) + assert.Equal(t, ExceptionalValueIntOverflow, err) }) }) @@ -855,7 +875,7 @@ func TestNeg(t *testing.T) { t.Run("not a number", func(t *testing.T) { _, err := Neg(&mockNumber{}) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) } @@ -877,7 +897,7 @@ func TestAbs(t *testing.T) { t.Run("overflow", func(t *testing.T) { _, err := Abs(Integer(math.MinInt64)) - assert.Equal(t, ErrIntOverflow, err) + assert.Equal(t, ExceptionalValueIntOverflow, err) }) }) @@ -889,7 +909,7 @@ func TestAbs(t *testing.T) { t.Run("not a number", func(t *testing.T) { _, err := Abs(&mockNumber{}) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) } @@ -936,7 +956,7 @@ func TestSign(t *testing.T) { t.Run("not a number", func(t *testing.T) { _, err := Sign(&mockNumber{}) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) } @@ -949,7 +969,7 @@ func TestFloatIntegerPart(t *testing.T) { t.Run("not a float", func(t *testing.T) { _, err := FloatIntegerPart(Integer(1)) - assert.Equal(t, TypeErrorFloat(Integer(1), nil), err) + assert.Equal(t, TypeError(ValidTypeFloat, Integer(1), nil), err) }) } @@ -962,7 +982,7 @@ func TestFloatFractionalPart(t *testing.T) { t.Run("not a float", func(t *testing.T) { _, err := FloatFractionalPart(Integer(1)) - assert.Equal(t, TypeErrorFloat(Integer(1), nil), err) + assert.Equal(t, TypeError(ValidTypeFloat, Integer(1), nil), err) }) } @@ -981,7 +1001,7 @@ func TestAsFloat(t *testing.T) { t.Run("not a number", func(t *testing.T) { _, err := AsFloat(&mockNumber{}) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) } @@ -996,19 +1016,19 @@ func TestFloor(t *testing.T) { t.Run("overflow", func(t *testing.T) { t.Run("positive", func(t *testing.T) { _, err := Floor(2 * Float(math.MaxInt64)) - assert.Equal(t, ErrIntOverflow, err) + assert.Equal(t, ExceptionalValueIntOverflow, err) }) t.Run("negative", func(t *testing.T) { _, err := Floor(2 * Float(math.MinInt64)) - assert.Equal(t, ErrIntOverflow, err) + assert.Equal(t, ExceptionalValueIntOverflow, err) }) }) }) t.Run("not a float", func(t *testing.T) { _, err := Floor(Integer(1)) - assert.Equal(t, TypeErrorFloat(Integer(1), nil), err) + assert.Equal(t, TypeError(ValidTypeFloat, Integer(1), nil), err) }) } @@ -1023,19 +1043,19 @@ func TestTruncate(t *testing.T) { t.Run("overflow", func(t *testing.T) { t.Run("positive", func(t *testing.T) { _, err := Truncate(2 * Float(math.MaxInt64)) - assert.Equal(t, ErrIntOverflow, err) + assert.Equal(t, ExceptionalValueIntOverflow, err) }) t.Run("negative", func(t *testing.T) { _, err := Truncate(2 * Float(math.MinInt64)) - assert.Equal(t, ErrIntOverflow, err) + assert.Equal(t, ExceptionalValueIntOverflow, err) }) }) }) t.Run("not a float", func(t *testing.T) { _, err := Truncate(Integer(1)) - assert.Equal(t, TypeErrorFloat(Integer(1), nil), err) + assert.Equal(t, TypeError(ValidTypeFloat, Integer(1), nil), err) }) } @@ -1050,19 +1070,19 @@ func TestRound(t *testing.T) { t.Run("overflow", func(t *testing.T) { t.Run("positive", func(t *testing.T) { _, err := Round(2 * Float(math.MaxInt64)) - assert.Equal(t, ErrIntOverflow, err) + assert.Equal(t, ExceptionalValueIntOverflow, err) }) t.Run("negative", func(t *testing.T) { _, err := Round(2 * Float(math.MinInt64)) - assert.Equal(t, ErrIntOverflow, err) + assert.Equal(t, ExceptionalValueIntOverflow, err) }) }) }) t.Run("not a float", func(t *testing.T) { _, err := Round(Integer(1)) - assert.Equal(t, TypeErrorFloat(Integer(1), nil), err) + assert.Equal(t, TypeError(ValidTypeFloat, Integer(1), nil), err) }) } @@ -1077,19 +1097,19 @@ func TestCeiling(t *testing.T) { t.Run("overflow", func(t *testing.T) { t.Run("positive", func(t *testing.T) { _, err := Ceiling(2 * Float(math.MaxInt64)) - assert.Equal(t, ErrIntOverflow, err) + assert.Equal(t, ExceptionalValueIntOverflow, err) }) t.Run("negative", func(t *testing.T) { _, err := Ceiling(2 * Float(math.MinInt64)) - assert.Equal(t, ErrIntOverflow, err) + assert.Equal(t, ExceptionalValueIntOverflow, err) }) }) }) t.Run("not a float", func(t *testing.T) { _, err := Ceiling(Integer(1)) - assert.Equal(t, TypeErrorFloat(Integer(1), nil), err) + assert.Equal(t, TypeError(ValidTypeFloat, Integer(1), nil), err) }) } @@ -1109,7 +1129,7 @@ func TestPower(t *testing.T) { t.Run("not a number", func(t *testing.T) { _, err := Power(Integer(1), &mockNumber{}) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) }) @@ -1128,34 +1148,34 @@ func TestPower(t *testing.T) { t.Run("not a number", func(t *testing.T) { _, err := Power(Float(1), &mockNumber{}) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) }) t.Run("not a number", func(t *testing.T) { _, err := Power(&mockNumber{}, Float(1)) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) t.Run("overflow", func(t *testing.T) { _, err := Power(Float(math.MaxFloat64), Float(2)) - assert.Equal(t, ErrFloatOverflow, err) + assert.Equal(t, ExceptionalValueFloatOverflow, err) }) t.Run("underflow", func(t *testing.T) { _, err := Power(Float(math.SmallestNonzeroFloat64), Float(2)) - assert.Equal(t, ErrUnderflow, err) + assert.Equal(t, ExceptionalValueUnderflow, err) }) t.Run("undefined", func(t *testing.T) { t.Run("vx is negative and vy is not an integer", func(t *testing.T) { _, err := Power(Integer(-1), Float(1.1)) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) t.Run("vx is zero and vy is negative", func(t *testing.T) { _, err := Power(Integer(0), Float(-1)) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) }) } @@ -1175,7 +1195,7 @@ func TestSin(t *testing.T) { t.Run("not a number", func(t *testing.T) { _, err := Sin(&mockNumber{}) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) } @@ -1194,7 +1214,7 @@ func TestCos(t *testing.T) { t.Run("not a number", func(t *testing.T) { _, err := Cos(&mockNumber{}) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) } @@ -1213,7 +1233,7 @@ func TestAtan(t *testing.T) { t.Run("not a number", func(t *testing.T) { _, err := Atan(&mockNumber{}) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) } @@ -1232,17 +1252,17 @@ func TestExp(t *testing.T) { t.Run("not a number", func(t *testing.T) { _, err := Exp(&mockNumber{}) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) t.Run("overflow", func(t *testing.T) { _, err := Exp(Float(math.MaxFloat64)) - assert.Equal(t, ErrFloatOverflow, err) + assert.Equal(t, ExceptionalValueFloatOverflow, err) }) t.Run("underflow", func(t *testing.T) { _, err := Exp(Float(-math.MaxFloat64)) - assert.Equal(t, ErrUnderflow, err) + assert.Equal(t, ExceptionalValueUnderflow, err) }) } @@ -1261,12 +1281,12 @@ func TestLog(t *testing.T) { t.Run("not a number", func(t *testing.T) { _, err := Log(&mockNumber{}) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) t.Run("undefined", func(t *testing.T) { _, err := Log(Float(0)) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) } @@ -1285,12 +1305,12 @@ func TestSqrt(t *testing.T) { t.Run("not a number", func(t *testing.T) { _, err := Sqrt(&mockNumber{}) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) t.Run("undefined", func(t *testing.T) { _, err := Sqrt(Float(-1)) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) } @@ -1304,13 +1324,13 @@ func TestBitwiseRightShift(t *testing.T) { t.Run("not an integer", func(t *testing.T) { _, err := BitwiseRightShift(Integer(16), Float(2)) - assert.Equal(t, TypeErrorInteger(Float(2), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Float(2), nil), err) }) }) t.Run("not an integer", func(t *testing.T) { _, err := BitwiseRightShift(Float(16), Integer(2)) - assert.Equal(t, TypeErrorInteger(Float(16), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Float(16), nil), err) }) } @@ -1324,13 +1344,13 @@ func TestBitwiseLeftShift(t *testing.T) { t.Run("not an integer", func(t *testing.T) { _, err := BitwiseLeftShift(Integer(16), Float(2)) - assert.Equal(t, TypeErrorInteger(Float(2), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Float(2), nil), err) }) }) t.Run("not an integer", func(t *testing.T) { _, err := BitwiseLeftShift(Float(16), Integer(2)) - assert.Equal(t, TypeErrorInteger(Float(16), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Float(16), nil), err) }) } @@ -1344,13 +1364,13 @@ func TestBitwiseAnd(t *testing.T) { t.Run("not an integer", func(t *testing.T) { _, err := BitwiseAnd(Integer(10), Float(12)) - assert.Equal(t, TypeErrorInteger(Float(12), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Float(12), nil), err) }) }) t.Run("not an integer", func(t *testing.T) { _, err := BitwiseAnd(Float(10), Integer(12)) - assert.Equal(t, TypeErrorInteger(Float(10), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Float(10), nil), err) }) } @@ -1364,13 +1384,13 @@ func TestBitwiseOr(t *testing.T) { t.Run("not an integer", func(t *testing.T) { _, err := BitwiseOr(Integer(10), Float(12)) - assert.Equal(t, TypeErrorInteger(Float(12), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Float(12), nil), err) }) }) t.Run("not an integer", func(t *testing.T) { _, err := BitwiseOr(Float(10), Integer(12)) - assert.Equal(t, TypeErrorInteger(Float(10), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Float(10), nil), err) }) } @@ -1385,7 +1405,7 @@ func TestBitwiseComplement(t *testing.T) { t.Run("not an integer", func(t *testing.T) { _, err := BitwiseComplement(Float(10)) - assert.Equal(t, TypeErrorInteger(Float(10), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Float(10), nil), err) }) } @@ -1400,24 +1420,24 @@ func TestIntFloorDiv(t *testing.T) { t.Run("overflow", func(t *testing.T) { _, err := IntFloorDiv(Integer(math.MinInt64), Integer(-1)) - assert.Equal(t, ErrIntOverflow, err) + assert.Equal(t, ExceptionalValueIntOverflow, err) }) t.Run("divided by zero", func(t *testing.T) { _, err := IntFloorDiv(Integer(1), Integer(0)) - assert.Equal(t, ErrZeroDivisor, err) + assert.Equal(t, ExceptionalValueZeroDivisor, err) }) }) t.Run("not an integer", func(t *testing.T) { _, err := IntFloorDiv(Integer(1), Float(1)) - assert.Equal(t, TypeErrorInteger(Float(1), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Float(1), nil), err) }) }) t.Run("not an integer", func(t *testing.T) { _, err := IntFloorDiv(Float(1), Integer(1)) - assert.Equal(t, TypeErrorInteger(Float(1), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Float(1), nil), err) }) } @@ -1445,7 +1465,7 @@ func TestMax(t *testing.T) { t.Run("not a number", func(t *testing.T) { _, err := Max(Integer(1), &mockNumber{}) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) }) @@ -1472,13 +1492,13 @@ func TestMax(t *testing.T) { t.Run("not a number", func(t *testing.T) { _, err := Max(Float(1), &mockNumber{}) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) }) t.Run("not a number", func(t *testing.T) { _, err := Max(&mockNumber{}, Integer(1)) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) } @@ -1506,7 +1526,7 @@ func TestMin(t *testing.T) { t.Run("not a number", func(t *testing.T) { _, err := Min(Integer(1), &mockNumber{}) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) }) @@ -1533,13 +1553,13 @@ func TestMin(t *testing.T) { t.Run("not a number", func(t *testing.T) { _, err := Min(Float(1), &mockNumber{}) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) }) t.Run("not a number", func(t *testing.T) { _, err := Min(&mockNumber{}, Integer(1)) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) } @@ -1561,7 +1581,7 @@ func TestIntegerPower(t *testing.T) { t.Run("x is 0", func(t *testing.T) { _, err := IntegerPower(Integer(0), Integer(-1)) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) t.Run("x is -1", func(t *testing.T) { @@ -1573,13 +1593,13 @@ func TestIntegerPower(t *testing.T) { t.Run("y is math.MinInt64", func(t *testing.T) { _, err := IntegerPower(Integer(-1), Integer(math.MinInt64)) - assert.Equal(t, ErrIntOverflow, err) + assert.Equal(t, ExceptionalValueIntOverflow, err) }) }) t.Run("x is neither 1, 0, nor -1", func(t *testing.T) { _, err := IntegerPower(Integer(2), Integer(-2)) - assert.Equal(t, TypeErrorFloat(Integer(2), nil), err) + assert.Equal(t, TypeError(ValidTypeFloat, Integer(2), nil), err) }) }) }) @@ -1592,18 +1612,18 @@ func TestIntegerPower(t *testing.T) { t.Run("not a number", func(t *testing.T) { _, err := IntegerPower(Integer(1), &mockNumber{}) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) t.Run("overflow", func(t *testing.T) { t.Run("x is too large", func(t *testing.T) { _, err := IntegerPower(Integer(math.MaxInt64), Integer(2)) - assert.Equal(t, ErrIntOverflow, err) + assert.Equal(t, ExceptionalValueIntOverflow, err) }) t.Run("y is too large", func(t *testing.T) { _, err := IntegerPower(Integer(2), Integer(63)) - assert.Equal(t, ErrIntOverflow, err) + assert.Equal(t, ExceptionalValueIntOverflow, err) }) }) }) @@ -1623,34 +1643,34 @@ func TestIntegerPower(t *testing.T) { t.Run("not a number", func(t *testing.T) { _, err := IntegerPower(Float(1), &mockNumber{}) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) }) t.Run("not a number", func(t *testing.T) { _, err := IntegerPower(&mockNumber{}, Float(1)) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) t.Run("overflow", func(t *testing.T) { _, err := IntegerPower(Float(math.MaxFloat64), Float(2)) - assert.Equal(t, ErrFloatOverflow, err) + assert.Equal(t, ExceptionalValueFloatOverflow, err) }) t.Run("underflow", func(t *testing.T) { _, err := IntegerPower(Float(math.SmallestNonzeroFloat64), Float(2)) - assert.Equal(t, ErrUnderflow, err) + assert.Equal(t, ExceptionalValueUnderflow, err) }) t.Run("undefined", func(t *testing.T) { t.Run("vx is negative and vy is not an integer", func(t *testing.T) { _, err := IntegerPower(Integer(-1), Float(1.1)) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) t.Run("vx is zero and vy is negative", func(t *testing.T) { _, err := IntegerPower(Integer(0), Integer(-1)) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) }) } @@ -1670,17 +1690,17 @@ func TestAsin(t *testing.T) { t.Run("not a number", func(t *testing.T) { _, err := Asin(&mockNumber{}) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) t.Run("greater than 1", func(t *testing.T) { _, err := Asin(Float(1.1)) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) t.Run("less than -1", func(t *testing.T) { _, err := Asin(Float(-1.1)) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) } @@ -1699,17 +1719,17 @@ func TestAcos(t *testing.T) { t.Run("not a number", func(t *testing.T) { _, err := Acos(&mockNumber{}) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) t.Run("greater than 1", func(t *testing.T) { _, err := Acos(Float(1.1)) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) t.Run("less than -1", func(t *testing.T) { _, err := Acos(Float(-1.1)) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) } @@ -1729,7 +1749,7 @@ func TestAtan2(t *testing.T) { t.Run("not a number", func(t *testing.T) { _, err := Atan2(Integer(0), &mockNumber{}) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) }) @@ -1748,18 +1768,18 @@ func TestAtan2(t *testing.T) { t.Run("not a number", func(t *testing.T) { _, err := Atan2(Float(0), &mockNumber{}) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) }) t.Run("not a number", func(t *testing.T) { _, err := Atan2(&mockNumber{}, Integer(1)) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) t.Run("x and y both equal to 0", func(t *testing.T) { _, err := Atan2(Integer(0), Integer(0)) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) } @@ -1778,7 +1798,7 @@ func TestTan(t *testing.T) { t.Run("not a number", func(t *testing.T) { _, err := Tan(&mockNumber{}) - assert.Equal(t, ErrUndefined, err) + assert.Equal(t, ExceptionalValueUndefined, err) }) } @@ -1792,13 +1812,13 @@ func TestXor(t *testing.T) { t.Run("not an integer", func(t *testing.T) { _, err := Xor(Integer(10), Float(12)) - assert.Equal(t, TypeErrorInteger(Float(12), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Float(12), nil), err) }) }) t.Run("not an integer", func(t *testing.T) { _, err := Xor(Float(10), Integer(12)) - assert.Equal(t, TypeErrorInteger(Float(10), nil), err) + assert.Equal(t, TypeError(ValidTypeInteger, Float(10), nil), err) }) } diff --git a/engine/promise.go b/engine/promise.go index 2be08c9d..dd738e3a 100644 --- a/engine/promise.go +++ b/engine/promise.go @@ -5,6 +5,11 @@ import ( "errors" ) +var ( + truePromise = &Promise{ok: true} + falsePromise = &Promise{ok: false} +) + // Promise is a delayed execution that results in (bool, error). The zero value for Promise is equivalent to Bool(false). type Promise struct { // delayed execution with multiple choices @@ -27,7 +32,11 @@ func Delay(k ...func(context.Context) *Promise) *Promise { // Bool returns a promise that simply returns (ok, nil). func Bool(ok bool) *Promise { - return &Promise{ok: ok} + if ok { + return truePromise + } else { + return falsePromise + } } // Error returns a promise that simply returns (false, err). diff --git a/engine/stream.go b/engine/stream.go index ef2a045f..cde54c35 100644 --- a/engine/stream.go +++ b/engine/stream.go @@ -141,9 +141,9 @@ func Open(name Atom, mode StreamMode, opts ...StreamOption) (*Stream, error) { if err != nil { switch { case os.IsNotExist(err): - return nil, existenceErrorSourceSink(name, nil) + return nil, ExistenceError(ObjectTypeSourceSink, name, nil) case os.IsPermission(err): - return nil, PermissionError("open", "source_sink", name, nil) + return nil, PermissionError(OperationOpen, PermissionTypeSourceSink, name, nil) default: return nil, SystemError(err) } diff --git a/engine/stream_test.go b/engine/stream_test.go index 3044a678..a5cd7c5b 100644 --- a/engine/stream_test.go +++ b/engine/stream_test.go @@ -100,7 +100,7 @@ func TestOpen(t *testing.T) { }() s, err := Open("/this/file/does/not/exist", StreamModeRead) - assert.Equal(t, existenceErrorSourceSink(Atom("/this/file/does/not/exist"), nil), err) + assert.Equal(t, ExistenceError(ObjectTypeSourceSink, Atom("/this/file/does/not/exist"), nil), err) assert.Nil(t, s) }) @@ -113,7 +113,7 @@ func TestOpen(t *testing.T) { }() s, err := Open("/this/file/is/protected", StreamModeRead) - assert.Equal(t, PermissionError("open", "source_sink", Atom("/this/file/is/protected"), nil), err) + assert.Equal(t, PermissionError(OperationOpen, PermissionTypeSourceSink, Atom("/this/file/is/protected"), nil), err) assert.Nil(t, s) }) diff --git a/engine/vm.go b/engine/vm.go index bac9f950..9e32966f 100644 --- a/engine/vm.go +++ b/engine/vm.go @@ -167,7 +167,7 @@ func (vm *VM) Arrive(pi ProcedureIndicator, args []Term, k func(*Env) *Promise, if !ok { switch vm.unknown { case unknownError: - return Error(existenceErrorProcedure(pi.Term(), env)) + return Error(ExistenceError(ObjectTypeProcedure, pi.Term(), env)) case unknownWarning: vm.OnUnknown(pi, args, env) fallthrough @@ -178,9 +178,10 @@ func (vm *VM) Arrive(pi ProcedureIndicator, args []Term, k func(*Env) *Promise, } } - return Delay(func(context.Context) *Promise { - return p.Call(vm, args, k, env) - }) + // Bind the special variable to inform the predicate about the context. + env = env.Bind(varContext, pi.Term()) + + return p.Call(vm, args, k, env) } type registers struct { @@ -483,29 +484,29 @@ type ProcedureIndicator struct { func NewProcedureIndicator(pi Term, env *Env) (ProcedureIndicator, error) { switch p := env.Resolve(pi).(type) { case Variable: - return ProcedureIndicator{}, ErrInstantiation + return ProcedureIndicator{}, InstantiationError(env) case *Compound: if p.Functor != "/" || len(p.Args) != 2 { - return ProcedureIndicator{}, TypeErrorPredicateIndicator(pi, env) + return ProcedureIndicator{}, TypeError(ValidTypePredicateIndicator, pi, env) } switch f := env.Resolve(p.Args[0]).(type) { case Variable: - return ProcedureIndicator{}, ErrInstantiation + return ProcedureIndicator{}, InstantiationError(env) case Atom: switch a := env.Resolve(p.Args[1]).(type) { case Variable: - return ProcedureIndicator{}, ErrInstantiation + return ProcedureIndicator{}, InstantiationError(env) case Integer: pi := ProcedureIndicator{Name: f, Arity: a} return pi, nil default: - return ProcedureIndicator{}, TypeErrorPredicateIndicator(pi, env) + return ProcedureIndicator{}, TypeError(ValidTypePredicateIndicator, pi, env) } default: - return ProcedureIndicator{}, TypeErrorPredicateIndicator(pi, env) + return ProcedureIndicator{}, TypeError(ValidTypePredicateIndicator, pi, env) } default: - return ProcedureIndicator{}, TypeErrorPredicateIndicator(pi, env) + return ProcedureIndicator{}, TypeError(ValidTypePredicateIndicator, pi, env) } } @@ -538,13 +539,13 @@ func (p ProcedureIndicator) Apply(args ...Term) (Term, error) { func piArgs(t Term, env *Env) (ProcedureIndicator, []Term, error) { switch f := env.Resolve(t).(type) { case Variable: - return ProcedureIndicator{}, nil, ErrInstantiation + return ProcedureIndicator{}, nil, InstantiationError(env) case Atom: return ProcedureIndicator{Name: f, Arity: 0}, nil, nil case *Compound: return ProcedureIndicator{Name: f.Functor, Arity: Integer(len(f.Args))}, f.Args, nil default: - return ProcedureIndicator{}, nil, TypeErrorCallable(f, env) + return ProcedureIndicator{}, nil, TypeError(ValidTypeCallable, f, env) } } diff --git a/engine/vm_test.go b/engine/vm_test.go index d0fb9100..cead8273 100644 --- a/engine/vm_test.go +++ b/engine/vm_test.go @@ -209,7 +209,7 @@ func TestVM_Arrive(t *testing.T) { unknown: unknownError, } ok, err := vm.Arrive(ProcedureIndicator{Name: "foo", Arity: 1}, []Term{Atom("a")}, Success, nil).Force(context.Background()) - assert.Equal(t, existenceErrorProcedure(&Compound{ + assert.Equal(t, ExistenceError(ObjectTypeProcedure, &Compound{ Functor: "/", Args: []Term{Atom("foo"), Integer(1)}, }, nil), err) @@ -256,13 +256,13 @@ func TestNewProcedureIndicator(t *testing.T) { t.Run("variable", func(t *testing.T) { pi, err := NewProcedureIndicator(Variable("PI"), nil) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.Zero(t, pi) }) t.Run("atomic", func(t *testing.T) { pi, err := NewProcedureIndicator(Atom("foo"), nil) - assert.Equal(t, TypeErrorPredicateIndicator(Atom("foo"), nil), err) + assert.Equal(t, TypeError(ValidTypePredicateIndicator, Atom("foo"), nil), err) assert.Zero(t, pi) }) @@ -271,7 +271,7 @@ func TestNewProcedureIndicator(t *testing.T) { Functor: "foo", Args: []Term{Atom("a"), Atom("b")}, }, nil) - assert.Equal(t, TypeErrorPredicateIndicator(&Compound{ + assert.Equal(t, TypeError(ValidTypePredicateIndicator, &Compound{ Functor: "foo", Args: []Term{Atom("a"), Atom("b")}, }, nil), err) @@ -283,7 +283,7 @@ func TestNewProcedureIndicator(t *testing.T) { Functor: "/", Args: []Term{Variable("Functor"), Integer(2)}, }, nil) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.Zero(t, pi) }) @@ -292,7 +292,7 @@ func TestNewProcedureIndicator(t *testing.T) { Functor: "/", Args: []Term{Integer(0), Integer(2)}, }, nil) - assert.Equal(t, TypeErrorPredicateIndicator(&Compound{ + assert.Equal(t, TypeError(ValidTypePredicateIndicator, &Compound{ Functor: "/", Args: []Term{Integer(0), Integer(2)}, }, nil), err) @@ -304,7 +304,7 @@ func TestNewProcedureIndicator(t *testing.T) { Functor: "/", Args: []Term{Atom("foo"), Variable("Arity")}, }, nil) - assert.Equal(t, ErrInstantiation, err) + assert.Equal(t, InstantiationError(nil), err) assert.Zero(t, pi) }) @@ -313,7 +313,7 @@ func TestNewProcedureIndicator(t *testing.T) { Functor: "/", Args: []Term{Atom("foo"), Atom("arity")}, }, nil) - assert.Equal(t, TypeErrorPredicateIndicator(&Compound{ + assert.Equal(t, TypeError(ValidTypePredicateIndicator, &Compound{ Functor: "/", Args: []Term{Atom("foo"), Atom("arity")}, }, nil), err) diff --git a/interpreter.go b/interpreter.go index bd2dcb6c..19c05fda 100644 --- a/interpreter.go +++ b/interpreter.go @@ -234,7 +234,7 @@ func (i *Interpreter) QuerySolutionContext(ctx context.Context, query string, ar func (i *Interpreter) consult(files engine.Term, k func(*engine.Env) *engine.Promise, env *engine.Env) *engine.Promise { switch f := env.Resolve(files).(type) { case engine.Variable: - return engine.Error(engine.ErrInstantiation) + return engine.Error(engine.InstantiationError(env)) case engine.Atom: if f == "[]" { return k(env) @@ -246,7 +246,7 @@ func (i *Interpreter) consult(files engine.Term, k func(*engine.Env) *engine.Pro return k(env) case *engine.Compound: if f.Functor != "." || len(f.Args) != 2 { - return engine.Error(engine.TypeErrorList(f, env)) + return engine.Error(engine.TypeError(engine.ValidTypeList, f, env)) } iter := engine.ListIterator{List: f, Env: env} for iter.Next() { @@ -259,14 +259,14 @@ func (i *Interpreter) consult(files engine.Term, k func(*engine.Env) *engine.Pro } return k(env) default: - return engine.Error(engine.TypeErrorList(f, env)) + return engine.Error(engine.TypeError(engine.ValidTypeList, f, env)) } } func (i *Interpreter) consultOne(file engine.Term, env *engine.Env) error { switch f := env.Resolve(file).(type) { case engine.Variable: - return engine.ErrInstantiation + return engine.InstantiationError(env) case engine.Atom: for _, f := range []string{string(f), string(f) + ".pl"} { b, err := ioutil.ReadFile(f) @@ -280,8 +280,8 @@ func (i *Interpreter) consultOne(file engine.Term, env *engine.Env) error { return nil } - return engine.DomainError("source_sink", file, env) + return engine.DomainError(engine.ValidDomainSourceSink, file, env) default: - return engine.TypeError("atom", file, env) + return engine.TypeError(engine.ValidTypeAtom, file, env) } } diff --git a/interpreter_test.go b/interpreter_test.go index 3c006d17..8951018f 100644 --- a/interpreter_test.go +++ b/interpreter_test.go @@ -1014,8 +1014,8 @@ func ExampleNew_arg() { // false // false // false - // error(instantiation_error, 'Arguments are not sufficiently instantiated.') - // error(instantiation_error, 'Arguments are not sufficiently instantiated.') - // error(type_error(compound, atom), 'Expected compound, found engine.Atom.') - // error(type_error(compound, 3), 'Expected compound, found engine.Integer.') + // error(instantiation_error, arg/3) + // error(instantiation_error, arg/3) + // error(type_error(compound, atom), arg/3) + // error(type_error(compound, 3), arg/3) }