xtlsoft / pisp
PHP的Lisp-like语言。
This package is auto-updated.
Last update: 2024-09-25 17:43:57 UTC
README
PHP的Lisp-like语言。
概述
这是它的Hello World示例代码。
PHP代码
<?php require_once "vendor/autoload.php"; $pisp = new \Pisp\Pisp; $code = file_get_contents("code.pisp"); $pisp->define("print", function ($args, $vm) { foreach ($args as $v) { if (is_string($v) || method_exists($v, "__toString")) { echo $v; } else { var_dump($v); } } }); $pisp->execute($code);
code.pisp代码内容
(print "Hello World" "\n")
结果
Hello World
安装
composer require xtlsoft/pisp
文档
基本PHP API
\Pisp\Pisp
我们为您构建了一个门面。您可以轻松使用它。
<?php $pisp = new \Pisp\Pisp();
是的,\Pisp\Pisp类是门面。
它扩展了\Pisp\VM\VM类,并有一个execute方法可以直接执行代码。
例如
<?php $code = '(print ["Hello World"] ["\n"])'; $pisp->execute($code);
\Pisp\VM\VM
这是主要的VM类。
我们有一个define和delete方法,用于定义和删除函数。
是的!在Pisp中,变量也是函数,因为它完全是函数式的。
<?php $vm = new \Pisp\Pisp; // Also can be $vm = new \Pisp\VM\VM; $vm->define("abc", 123); $vm->define("+", function ($args, $vm) { return $args[0] + $args[1]; }); $vm->delete("abc"); echo $vm->execute("(+ 1 2)"); // 3
您注意到吗?当定义一个函数时,它必须是一个有效的回调,带有两个参数。第一个是实际参数的数组,第二个是\Pisp\VM\VM类的实例。
您可以动态添加函数。
\Pisp\Parser\Parser
这是用于解析代码的。
<?php $parser = new \Pisp\Parser\Parser; $rslt = $parser->parse('(print ["Hello World\n"])'); var_export($rslt instanceof \Pisp\Parser\AST\Root); // true
\Pisp\Parser\ASTWalker
这是用于遍历AST的。
<?php $walker = new \Pisp\Parser\ASTWalker($rslt); $walker->walk(function (\Pisp\Parser\AST\Node $node) { echo $node->name, PHP_EOL; });
语法和语言规范
基本语法
函数调用以(
开始,以)
结束。函数名和参数由任何空白字符分隔。
参数是可选的。
例如
(+ 1 2) (+ 1 2 ) ( + 1 2 ) (a_function_call_without_arguments)
现在字面量不被[
和]
包围。
例如
(+ 1 2) (print "a string") (+ 1.2 1.4)
此外,Pisp支持延迟调用。
只需在函数名前加上@
,参数将是它们的AST。
(@print (undefined_function))
这将输出\Pisp\Parser\AST\CallingNode类的var_dump结果。
默认函数
Pisp默认不包含任何函数。这意味着,如果您运行上面的示例,您将得到一个NoFunctionException
。您必须自己定义它们。
然而,有一个有用的StdLib,只需
\Pisp\StdLib\StandardLibrary::register($vm);
注释
Pisp只支持从#|
开始并以|#
结束的块注释。
#| This is the function comment |# (do_something (some_function) ["literal"]) #| ok too |#
Pisp支持嵌套注释。
示例
#| comment some code (print "Hello World") #| This prints "Hello World" |# |#
您也可以使用一个小技巧来让它支持它
<?php $pisp = new \Pisp\Pisp; $pisp->define("rem", function ($args, $vm) { return; });
然后,您只需使用
(@rem "This is a comment")
并且这将不会被执行。
字面量
Pisp现在支持许多字面量。
字面量现在不被[
和]
包围。
目前有三种类型的字面量:数字、字符串和列表。
数字
数字是一个整数或浮点数。
示例
(print 123 123.456 1e10 0x3f3f3f3f)
字符串
字符串由引号包围。支持多引号。
\n
或其他内容目前不支持。
示例
(print "Hello World" 'Another \'test\' Hello World')
列表
列表是一组值。
它用[
和]
包围,每个值用逗号分隔。
示例
(print [1, 2, [3, 4]] ["Hello", 234, "World", 'you'])