diff --git a/go.mod b/go.mod index 9be12320..376eeae3 100644 --- a/go.mod +++ b/go.mod @@ -54,6 +54,7 @@ require ( github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.19.0 github.com/stretchr/testify v1.9.0 + github.com/wk8/go-ordered-map/v2 v2.1.8 golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 golang.org/x/net v0.24.0 google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 @@ -96,6 +97,7 @@ require ( github.com/VictoriaMetrics/fastcache v1.5.7 // indirect github.com/VividCortex/ewma v1.2.0 // indirect github.com/aws/aws-sdk-go v1.44.224 // indirect + github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect @@ -103,6 +105,7 @@ require ( github.com/btcsuite/btcd v0.22.0-beta // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce // indirect + github.com/buger/jsonparser v1.1.1 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect @@ -216,6 +219,7 @@ require ( github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/linxGnu/grocksdb v1.8.14 // indirect github.com/magiconair/properties v1.8.7 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/manifoldco/promptui v0.9.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect diff --git a/go.sum b/go.sum index 7169140e..77885ad4 100644 --- a/go.sum +++ b/go.sum @@ -294,6 +294,8 @@ github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX github.com/aws/aws-sdk-go v1.44.224 h1:09CiaaF35nRmxrzWZ2uRq5v6Ghg/d2RiPjZnSgtt+RQ= github.com/aws/aws-sdk-go v1.44.224/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= +github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -326,6 +328,8 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtE github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/bufbuild/protocompile v0.6.0 h1:Uu7WiSQ6Yj9DbkdnOe7U4mNKp58y9WDMKDn28/ZlunY= github.com/bufbuild/protocompile v0.6.0/go.mod h1:YNP35qEYoYGme7QMtz5SBCoN4kL4g12jTtjuzRNdjpE= +github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.8.0 h1:ea0Xadu+sHlu7x5O3gKhRpQ1IKiMrSiHttPF0ybECuA= @@ -861,6 +865,7 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfC github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= @@ -931,6 +936,8 @@ github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0Q github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/matryer/is v1.3.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= @@ -1269,6 +1276,8 @@ github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= +github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= diff --git a/x/logic/interpreter/registry.go b/x/logic/interpreter/registry.go index 50af563a..45b88747 100644 --- a/x/logic/interpreter/registry.go +++ b/x/logic/interpreter/registry.go @@ -2,130 +2,133 @@ package interpreter import ( "fmt" + orderedmap "github.com/wk8/go-ordered-map/v2" "strconv" "strings" "github.com/ichiban/prolog" - "github.com/ichiban/prolog/engine" + engine "github.com/ichiban/prolog/engine" "github.com/axone-protocol/axoned/v8/x/logic/predicate" ) // registry is a map from predicate names (in the form of "atom/arity") to predicates functions. -var registry = map[string]any{ - "call/1": engine.Call, - "catch/3": engine.Catch, - "throw/1": engine.Throw, - "=/2": engine.Unify, - "unify_with_occurs_check/2": engine.UnifyWithOccursCheck, - "subsumes_term/2": engine.SubsumesTerm, - "var/1": engine.TypeVar, - "atom/1": engine.TypeAtom, - "integer/1": engine.TypeInteger, - "float/1": engine.TypeFloat, - "compound/1": engine.TypeCompound, - "acyclic_term/1": engine.AcyclicTerm, - "compare/3": engine.Compare, - "sort/2": engine.Sort, - "keysort/2": engine.KeySort, - "functor/3": engine.Functor, - "arg/3": engine.Arg, - "=../2": engine.Univ, - "copy_term/2": engine.CopyTerm, - "term_variables/2": engine.TermVariables, - "is/2": engine.Is, - "=:=/2": engine.Equal, - "=\\=/2": engine.NotEqual, - "/2": engine.GreaterThan, - ">=/2": engine.GreaterThanOrEqual, - "clause/2": engine.Clause, - "current_predicate/1": engine.CurrentPredicate, - "asserta/1": engine.Asserta, - "assertz/1": engine.Assertz, - "retract/1": engine.Retract, - "abolish/1": engine.Abolish, - "findall/3": engine.FindAll, - "bagof/3": engine.BagOf, - "setof/3": engine.SetOf, - "current_input/1": engine.CurrentInput, - "current_output/1": predicate.CurrentOutput, - "set_input/1": engine.SetInput, - "set_output/1": engine.SetOutput, - "open/4": predicate.Open, - "open/3": predicate.Open3, - "close/2": engine.Close, - "flush_output/1": engine.FlushOutput, - "stream_property/2": engine.StreamProperty, - "set_stream_position/2": engine.SetStreamPosition, - "get_char/2": engine.GetChar, - "peek_char/2": engine.PeekChar, - "put_char/2": engine.PutChar, - "get_byte/2": engine.GetByte, - "peek_byte/2": engine.PeekByte, - "put_byte/2": engine.PutByte, - "read_term/3": engine.ReadTerm, - "write_term/3": engine.WriteTerm, - "op/3": engine.Op, - "current_op/3": engine.CurrentOp, - "char_conversion/2": engine.CharConversion, - "current_char_conversion/2": engine.CurrentCharConversion, - `\+/1`: engine.Negate, - "repeat/0": engine.Repeat, - "call/2": engine.Call1, - "call/3": engine.Call2, - "call/4": engine.Call3, - "call/5": engine.Call4, - "call/6": engine.Call5, - "call/7": engine.Call6, - "call/8": engine.Call7, - "atom_length/2": engine.AtomLength, - "atom_concat/3": engine.AtomConcat, - "sub_atom/5": engine.SubAtom, - "atom_chars/2": engine.AtomChars, - "atom_codes/2": engine.AtomCodes, - "char_code/2": engine.CharCode, - "number_chars/2": engine.NumberChars, - "number_codes/2": engine.NumberCodes, - "set_prolog_flag/2": engine.SetPrologFlag, - "current_prolog_flag/2": engine.CurrentPrologFlag, - "halt/1": engine.Halt, - "consult/1": predicate.Consult, - "phrase/3": engine.Phrase, - "expand_term/2": engine.ExpandTerm, - "append/3": engine.Append, - "length/2": engine.Length, - "between/3": engine.Between, - "succ/2": engine.Succ, - "nth0/3": engine.Nth0, - "nth1/3": engine.Nth1, - "call_nth/2": engine.CallNth, - "chain_id/1": predicate.ChainID, - "block_height/1": predicate.BlockHeight, - "block_time/1": predicate.BlockTime, - "bank_balances/2": predicate.BankBalances, - "bank_spendable_balances/2": predicate.BankSpendableBalances, - "bank_locked_balances/2": predicate.BankLockedBalances, - "did_components/2": predicate.DIDComponents, - "crypto_data_hash/3": predicate.CryptoDataHash, - "hex_bytes/2": predicate.HexBytes, - "bech32_address/2": predicate.Bech32Address, - "source_file/1": predicate.SourceFile, - "json_prolog/2": predicate.JSONProlog, - "uri_encoded/3": predicate.URIEncoded, - "read_string/3": predicate.ReadString, - "eddsa_verify/4": predicate.EDDSAVerify, - "ecdsa_verify/4": predicate.ECDSAVerify, - "string_bytes/3": predicate.StringBytes, -} +var registry = orderedmap.New[string, any]( + orderedmap.WithInitialData[string, any]([]orderedmap.Pair[string, any]{ + {Key: "call/1", Value: engine.Call}, + {Key: "catch/3", Value: engine.Catch}, + {Key: "throw/1", Value: engine.Throw}, + {Key: "=/2", Value: engine.Unify}, + {Key: "unify_with_occurs_check/2", Value: engine.UnifyWithOccursCheck}, + {Key: "subsumes_term/2", Value: engine.SubsumesTerm}, + {Key: "var/1", Value: engine.TypeVar}, + {Key: "atom/1", Value: engine.TypeAtom}, + {Key: "integer/1", Value: engine.TypeInteger}, + {Key: "float/1", Value: engine.TypeFloat}, + {Key: "compound/1", Value: engine.TypeCompound}, + {Key: "acyclic_term/1", Value: engine.AcyclicTerm}, + {Key: "compare/3", Value: engine.Compare}, + {Key: "sort/2", Value: engine.Sort}, + {Key: "keysort/2", Value: engine.KeySort}, + {Key: "functor/3", Value: engine.Functor}, + {Key: "arg/3", Value: engine.Arg}, + {Key: "=../2", Value: engine.Univ}, + {Key: "copy_term/2", Value: engine.CopyTerm}, + {Key: "term_variables/2", Value: engine.TermVariables}, + {Key: "is/2", Value: engine.Is}, + {Key: "=:=/2", Value: engine.Equal}, + {Key: "=\\=/2", Value: engine.NotEqual}, + {Key: "/2", Value: engine.GreaterThan}, + {Key: ">=/2", Value: engine.GreaterThanOrEqual}, + {Key: "clause/2", Value: engine.Clause}, + {Key: "current_predicate/1", Value: engine.CurrentPredicate}, + {Key: "asserta/1", Value: engine.Asserta}, + {Key: "assertz/1", Value: engine.Assertz}, + {Key: "retract/1", Value: engine.Retract}, + {Key: "abolish/1", Value: engine.Abolish}, + {Key: "findall/3", Value: engine.FindAll}, + {Key: "bagof/3", Value: engine.BagOf}, + {Key: "setof/3", Value: engine.SetOf}, + {Key: "current_input/1", Value: engine.CurrentInput}, + {Key: "current_output/1", Value: predicate.CurrentOutput}, + {Key: "set_input/1", Value: engine.SetInput}, + {Key: "set_output/1", Value: engine.SetOutput}, + {Key: "open/4", Value: predicate.Open}, + {Key: "open/3", Value: predicate.Open3}, + {Key: "close/2", Value: engine.Close}, + {Key: "flush_output/1", Value: engine.FlushOutput}, + {Key: "stream_property/2", Value: engine.StreamProperty}, + {Key: "set_stream_position/2", Value: engine.SetStreamPosition}, + {Key: "get_char/2", Value: engine.GetChar}, + {Key: "peek_char/2", Value: engine.PeekChar}, + {Key: "put_char/2", Value: engine.PutChar}, + {Key: "get_byte/2", Value: engine.GetByte}, + {Key: "peek_byte/2", Value: engine.PeekByte}, + {Key: "put_byte/2", Value: engine.PutByte}, + {Key: "read_term/3", Value: engine.ReadTerm}, + {Key: "write_term/3", Value: engine.WriteTerm}, + {Key: "op/3", Value: engine.Op}, + {Key: "current_op/3", Value: engine.CurrentOp}, + {Key: "char_conversion/2", Value: engine.CharConversion}, + {Key: "current_char_conversion/2", Value: engine.CurrentCharConversion}, + {Key: "\\+/1", Value: engine.Negate}, + {Key: "repeat/0", Value: engine.Repeat}, + {Key: "call/2", Value: engine.Call1}, + {Key: "call/3", Value: engine.Call2}, + {Key: "call/4", Value: engine.Call3}, + {Key: "call/5", Value: engine.Call4}, + {Key: "call/6", Value: engine.Call5}, + {Key: "call/7", Value: engine.Call6}, + {Key: "call/8", Value: engine.Call7}, + {Key: "atom_length/2", Value: engine.AtomLength}, + {Key: "atom_concat/3", Value: engine.AtomConcat}, + {Key: "sub_atom/5", Value: engine.SubAtom}, + {Key: "atom_chars/2", Value: engine.AtomChars}, + {Key: "atom_codes/2", Value: engine.AtomCodes}, + {Key: "char_code/2", Value: engine.CharCode}, + {Key: "number_chars/2", Value: engine.NumberChars}, + {Key: "number_codes/2", Value: engine.NumberCodes}, + {Key: "set_prolog_flag/2", Value: engine.SetPrologFlag}, + {Key: "current_prolog_flag/2", Value: engine.CurrentPrologFlag}, + {Key: "halt/1", Value: engine.Halt}, + {Key: "consult/1", Value: predicate.Consult}, + {Key: "phrase/3", Value: engine.Phrase}, + {Key: "expand_term/2", Value: engine.ExpandTerm}, + {Key: "append/3", Value: engine.Append}, + {Key: "length/2", Value: engine.Length}, + {Key: "between/3", Value: engine.Between}, + {Key: "succ/2", Value: engine.Succ}, + {Key: "nth0/3", Value: engine.Nth0}, + {Key: "nth1/3", Value: engine.Nth1}, + {Key: "call_nth/2", Value: engine.CallNth}, + {Key: "chain_id/1", Value: predicate.ChainID}, + {Key: "block_height/1", Value: predicate.BlockHeight}, + {Key: "block_time/1", Value: predicate.BlockTime}, + {Key: "bank_balances/2", Value: predicate.BankBalances}, + {Key: "bank_spendable_balances/2", Value: predicate.BankSpendableBalances}, + {Key: "bank_locked_balances/2", Value: predicate.BankLockedBalances}, + {Key: "did_components/2", Value: predicate.DIDComponents}, + {Key: "crypto_data_hash/3", Value: predicate.CryptoDataHash}, + {Key: "hex_bytes/2", Value: predicate.HexBytes}, + {Key: "bech32_address/2", Value: predicate.Bech32Address}, + {Key: "source_file/1", Value: predicate.SourceFile}, + {Key: "json_prolog/2", Value: predicate.JSONProlog}, + {Key: "uri_encoded/3", Value: predicate.URIEncoded}, + {Key: "read_string/3", Value: predicate.ReadString}, + {Key: "eddsa_verify/4", Value: predicate.EDDSAVerify}, + {Key: "ecdsa_verify/4", Value: predicate.ECDSAVerify}, + {Key: "string_bytes/3", Value: predicate.StringBytes}, + }...), +) // RegistryNames is the list of the predicate names in the Registry. var RegistryNames = func() []string { - names := make([]string, 0, len(registry)) + names := make([]string, 0, registry.Len()) - for name := range registry { - names = append(names, name) + for name := registry.Oldest(); name != nil; name = name.Next() { + names = append(names, name.Key) } return names }() @@ -140,7 +143,7 @@ type Hook = func(functor string) func(env *engine.Env) error // //nolint:lll func Register(i *prolog.Interpreter, name string, hook Hook) error { - if p, ok := registry[name]; ok { + if p, ok := registry.Get(name); ok { parts := strings.Split(name, "/") if len(parts) == 2 { atom := engine.NewAtom(parts[0])