From 599ebd303f20cc54dbf159aa87bb3247fcff7075 Mon Sep 17 00:00:00 2001 From: Pekka Laiho Date: Fri, 19 Jun 2020 10:50:44 +0700 Subject: [PATCH] added Json serialization --- README.md | 9 +++++++- src/Lib/Json.php | 51 +++++++++++++++++++++++++++++++++++++++++++++ src/LispFactory.php | 1 + 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 src/Lib/Json.php diff --git a/README.md b/README.md index 471ad83..119f0fa 100644 --- a/README.md +++ b/README.md @@ -203,6 +203,13 @@ file? | `(file? "test.txt")` | `true` | Return true if the file exists. fread | `(fread "test.txt")` | `"content"` | Read the contents of a file. fwrite | `(fwrite "test.txt" "content")` | `true` | Write string to file. Give optional third parameter as `true` to append. +### Json functions + +Name | Example | Example result | Description +------- | ------- | -------------- | ----------- +to-json | `(to-json { "a" [1 2 3] "b" [4 5 6] })` | `"{\"a\":[1,2,3],\"b\":[4,5,6]}"` | Encode the argument as a JSON string. +from-json | `(from-json "{\"a\":[1,2,3],\"b\":[4,5,6]}")` | `{"a":[1 2 3] "b":[4 5 6]}` | Decode the JSON string given as argument. + ### Math functions Name | Example | Example result | Description @@ -293,7 +300,7 @@ pi | M_PI ## Extending -The project is easy to extend because it is trivial to add new functions whether the implementation is defined on the PHP or Lisp side. If the language ends up being used in the future, first plans are to add support for JSON serialization and a HTTP client. +The project is easy to extend because it is trivial to add new functions whether the implementation is defined on the PHP or Lisp side. ## License diff --git a/src/Lib/Json.php b/src/Lib/Json.php new file mode 100644 index 0000000..ea653a2 --- /dev/null +++ b/src/Lib/Json.php @@ -0,0 +1,51 @@ +set('to-json', new CoreFunc('to-json', 'Encode the argument as a JSON string.', 1, 1, + fn ($a) => json_encode($this->getJsonData($a)) + )); + + $env->set('from-json', new CoreFunc('from-json', 'Decode the JSON string given as argument.', 1, 1, + fn ($a) => $this->parseJsonData(json_decode($a)) + )); + } + + private function getJsonData($a) + { + if ($a instanceof Func) { + throw new MadLispException("unable to encode function as json"); + } elseif ($a instanceof Collection) { + return array_map([$this, 'getJsonData'], $a->getData()); + } elseif ($a instanceof Symbol) { + // Does this make sense, as we cannot reverse this operation? + return $a->getName(); + } else { + return $a; + } + } + + private function parseJsonData($a) + { + if (is_object($a)) { + return new Hash(array_map([$this, 'parseJsonData'], (array) $a)); + } elseif (is_array($a)) { + // We have to choose between a List and a Vector... + return new Vector(array_map([$this, 'parseJsonData'], $a)); + } else { + return $a; + } + } +} diff --git a/src/LispFactory.php b/src/LispFactory.php index fef1ddf..111dd7a 100644 --- a/src/LispFactory.php +++ b/src/LispFactory.php @@ -45,6 +45,7 @@ class LispFactory (new Lib\Collections())->register($env); (new Lib\Compare())->register($env); (new Lib\IO())->register($env); + (new Lib\Json())->register($env); (new Lib\Math())->register($env); (new Lib\Strings())->register($env); (new Lib\Time())->register($env);