Skip to content

Commit

Permalink
feat(logic): add hex_bytes/2 predicate
Browse files Browse the repository at this point in the history
  • Loading branch information
bdeneux committed Feb 20, 2023
1 parent da067ba commit eb167ee
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 4 deletions.
1 change: 1 addition & 0 deletions x/logic/interpreter/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ var Registry = map[string]RegistryEntry{
"bank_locked_balances/2": {predicate.BankLockedBalances, 1},
"did_components/2": {predicate.DIDComponents, 1},
"sha_hash/2": {predicate.SHAHash, 1},
"hex_bytes/2": {predicate.HexBytes, 1},
}

// RegistryNames is the list of the predicate names in the Registry.
Expand Down
44 changes: 44 additions & 0 deletions x/logic/predicate/crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package predicate

import (
"context"
"encoding/hex"
"fmt"

"github.com/ichiban/prolog/engine"
"github.com/okp4/okp4d/x/logic/util"
"github.com/tendermint/tendermint/crypto"
)

Expand All @@ -20,3 +22,45 @@ func SHAHash(vm *engine.VM, data, hash engine.Term, cont engine.Cont, env *engin
}
})
}

func HexBytes(vm *engine.VM, hexa, bts engine.Term, cont engine.Cont, env *engine.Env) *engine.Promise {
return engine.Delay(func(ctx context.Context) *engine.Promise {
var result []byte

switch h := env.Resolve(hexa).(type) {
case engine.Variable:
case engine.Atom:
src := []byte(h.String())
result = make([]byte, hex.DecodedLen(len(src)))
_, err := hex.Decode(result, src)
if err != nil {
return engine.Error(fmt.Errorf("hex_bytes/2: failed decode hexadecimal %w", err))
}
default:
return engine.Error(fmt.Errorf("hex_bytes/2: invalid hex type: %T, should be Atom or Variable", h))
}

switch b := env.Resolve(bts).(type) {
case engine.Variable:
if result == nil {
return engine.Error(fmt.Errorf("hex_bytes/2: nil hexadecimal conversion in input"))
}
return engine.Unify(vm, bts, BytesToList(result), cont, env)
case engine.Compound:
if b.Arity() != 2 || b.Functor().String() != "." {
return engine.Error(fmt.Errorf("hex_bytes/2: bytes should be a List, give %T", b))
}
iter := engine.ListIterator{List: b, Env: env}

src, err := ListToBytes(iter, env)
if err != nil {
return engine.Error(fmt.Errorf("hex_bytes/2: failed convert list into bytes: %w", err))
}
dst := hex.EncodeToString(src)
return engine.Unify(vm, hexa, util.StringToTerm(dst), cont, env)
default:
return engine.Error(fmt.Errorf("hex_bytes/2: invalid hex type: %T, should be Variable or List", b))
}

})
}
4 changes: 0 additions & 4 deletions x/logic/predicate/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,6 @@ func ListToBytes(terms engine.ListIterator, env *engine.Env) ([]byte, error) {
term := env.Resolve(terms.Current())
switch t := term.(type) {
case engine.Integer:
//b, ok :=
//if !ok {
// return nil, fmt.Errorf("couldn't cast '%d' to byte", term)
//}
bt = append(bt, byte(t))
default:
return nil, fmt.Errorf("invalid term type in list %T, only integer allowed", term)
Expand Down

0 comments on commit eb167ee

Please sign in to comment.