xtlsoft/pisp

PHP的Lisp-like语言。

dev-master 2018-12-31 08:05 UTC

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'])