Lisphp at Ning: Custom functions
In my previous post, I mentioned that we are experimenting with Lisphp at Ning, and we have some custom functions that seem to be helpful:
- import: imports a lisp file: (import 'foo/bar/baz.php')
- php: runs a PHP function without having to import it: (php :htmlentities 'foo')
- cons: prepends an item to an array: (cons 'strawberry' flavors)
- hash: creates an array of key-value pairs: (hash 'key1' 'value1' 'key2' 'value2')
- array-set: sets an item on a multidimensional array: $flavors['foo']['bar'] = 'baz' is (array-set flavors 'foo' 'bar' 'baz')
- array-get: gets an item from a multidimensional array: $flavors['foo']['bar'] is (array-get flavors 'foo' 'bar')
- arr: array_replace_recursive()
- environment: this is the Lisp environment itself added as a variable, to allow you to check if a function exists: (exists-at? environment 'my-function')
Here is the code that we use to call Lisphp. Note that you have a choice of runFile() or runCode(); also note the custom functions. You may need to make some modifications to get this to run in your own environment:
<?php
/**
* Parses Lisphp files.
*/
class XG_Lisp {
/**
* Executes a Lisp file using Lisphp.
*
* @param string $path the path to the lisp file
* @param array $env names and values to add to the environment;
* see Lisphp_Environment
* @return the result
* @see http://jona.ca/blog/lisphp-at-ning-introduction
*/
public function runFile($path, $env = []) {
return $this->run(Lisphp_Program::load(NF_APP_BASE . '/' . $path), $env);
}
/**
* Executes Lisp code using Lisphp.
*
* @param string $code the Lisp code
* @param array $env names and values to add to the environment;
* see Lisphp_Environment
* @return the result
*/
public function runCode($code, $env = []) {
return $this->run(new Lisphp_Program($code), $env);
}
/**
* Executes a Lisp program using Lisphp.
*
* @param Lisphp_Program $program a Lisp program object
* @param array $env names and values to add to the environment;
* see Lisphp_Environment
* @return the result
*/
protected function run($program, $env = []) {
$environment = Lisphp_Environment::full();
foreach ($env as $name => $value) {
$environment[$name] = $value;
}
$environment['B'] = B(); // XG_BaseService
// Import a PHP file: (import 'lib/components/activity/lib/foo.lisp')
$environment['import'] = new Lisphp_Runtime_PHPFunction(function ($path) use ($environment) {
$program = Lisphp_Program::load(NF_APP_BASE . '/' . $path);
return $program->execute($environment);
});
// Prepends an element to a list
$environment['cons'] = new Lisphp_Runtime_PHPFunction([$this, 'cons']);
$environment['->$'] = new XG_Lisp_GetField;
$environment['array-get'] = new Lisphp_Runtime_PHPFunction([$this, 'arrayGet']);
$environment['array-set'] = new Lisphp_Runtime_PHPFunction([$this, 'arraySet']);
$environment['hash'] = new Lisphp_Runtime_PHPFunction([$this, 'hash']);
$environment['var_dump'] = new Lisphp_Runtime_PHPFunction('var_dump');
$environment['arr'] = new Lisphp_Runtime_PHPFunction('array_replace_recursive');
$environment['environment'] = $environment;
return $program->execute($environment);
}
/**
* Prepends an element to a list.
*
* @param mixed $item the item to prepend
* @param array|Lisphp_List $list the list to prepend the item to
* @return array|Lisphp_List a new list
*/
public function cons($item, $list) {
if (is_array($list)) {
return array_merge([$item], $list);
}
return new Lisphp_List(array_merge([$item], $list->getArrayCopy()));
}
/**
* Retrieves an item from a multidimensional array
*
* @param array $array the array to read from
* @param string $key1 the first key
* @param string $key2 the second key, etc.
* @return mixed the value at the given keys
*/
public function arrayGet() {
$args = func_get_args();
$result = array_shift($args);
foreach ($args as $key) {
if (!is_array($result)) {
return null;
}
if (!array_key_exists($key, $result)) {
return null;
}
$result = $result[$key];
}
return $result;
}
/**
* Sets an item on a multidimensional array
*
* @param array $array the array to read from
* @param string $key1 the first key
* @param string $key2 the second key, etc.
* @param string $value the value to set
* @return mixed the new multidimensional array
*/
public function arraySet() {
$args = func_get_args();
$array = array_shift($args);
$subtree = &$array;
$value = array_pop($args);
$lastKey = array_pop($args);
foreach ($args as $key) {
if (!array_key_exists($key, $subtree)) {
$subtree[$key] = [];
}
$subtree = &$subtree[$key];
}
$subtree[$lastKey] = $value;
return $array;
}
/**
* Converts a list into an array of key-value pairs.
*
* @param string $key1 the first key
* @param string $value1 the first value
* @param string $key2 the second key
* @param string $value2 the second value, etc.
* @return array the key-value pairs
*/
public function hash() {
$args = func_get_args();
$hash = [];
for ($i = 0; $i < count($args); $i += 2) {
$hash[$args[$i]] = $args[$i+1];
}
return $hash;
}
}
0 Comments:
Post a Comment
<< Home