From e43010d6869204e21b392ce54a7be362c359e522 Mon Sep 17 00:00:00 2001 From: Benjamin DENEUX Date: Wed, 26 Apr 2023 14:23:39 +0200 Subject: [PATCH] feat(logic): convert json string to terms --- x/logic/predicate/json.go | 52 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 x/logic/predicate/json.go diff --git a/x/logic/predicate/json.go b/x/logic/predicate/json.go new file mode 100644 index 00000000..7028f62c --- /dev/null +++ b/x/logic/predicate/json.go @@ -0,0 +1,52 @@ +package predicate + +import ( + "encoding/json" + "fmt" + + "github.com/ichiban/prolog/engine" + "github.com/okp4/okp4d/x/logic/util" +) + +// AtomJSON is a term which represents a json as a compound term `json([Pair])`. +var AtomJSON = engine.NewAtom("json") + +// JsonProlog is a predicate that will unify a JSON string into prolog terms and vice versa. +// +// json_prolog(?Json, ?Term) is det +// TODO: +func JsonProlog(vm *engine.VM, j, term engine.Term, cont engine.Cont, env *engine.Env) *engine.Promise { + switch t1 := env.Resolve(j).(type) { + case engine.Variable: + case engine.Atom: + terms, err := jsonStringToTerms(t1.String()) + if err != nil { + return engine.Error(fmt.Errorf("json_prolog/2: %w", err)) + } + + return engine.Unify(vm, term, terms, cont, env) + default: + return engine.Error(fmt.Errorf("did_components/2: cannot unify json with %T", t1)) + } + + switch env.Resolve(term).(type) { + default: + return engine.Error(fmt.Errorf("json_prolog/2: not implemented")) + } +} + +func jsonStringToTerms(j string) (engine.Term, error) { + var values any + json.Unmarshal([]byte(j), &values) + + return jsonToTerms(values) +} + +func jsonToTerms(value any) (engine.Term, error) { + switch v := value.(type) { + case string: + return util.StringToTerm(v), nil + default: + return nil, fmt.Errorf("could not convert %s (%T) to a prolog term", v, v) + } +}