diff --git a/src/bindings/php/SConscript b/src/bindings/php/SConscript index fc4c1d1a5a780e592a45a73ff7b9745de8dce618..34728af238c9a1b3ad478737e997921e8a0ff0b8 100644 --- a/src/bindings/php/SConscript +++ b/src/bindings/php/SConscript @@ -23,7 +23,7 @@ phplib = phptestenv.Command(os.path.join(phpextprefix, "hammer.so"), libhammer_p AlwaysBuild(phplib) phpprefix = os.popen("php-config --prefix").read().rstrip() phpincl = phptestenv.Command(os.path.join(os.path.join(phpprefix, "etc/conf.d"), "hammer.ini"), "hammer.ini", Copy("$TARGET", "$SOURCE")) -phptestexec = phptestenv.Command(phptests, [phplib, phpincl], "phpenv exec phpunit -v --debug --include-path " + os.path.dirname(libhammer_php[0].path) +" src/bindings/php/Tests") +phptestexec = phptestenv.Command(phptests, [phplib, phpincl], "phpenv exec phpunit --include-path " + os.path.dirname(libhammer_php[0].path) +" src/bindings/php/Tests") phptest = Alias("testphp", [phptestexec], phptestexec) AlwaysBuild(phptest) testruns.append(phptest) diff --git a/src/bindings/php/Tests/PredicateTest.php b/src/bindings/php/Tests/PredicateTest.php new file mode 100644 index 0000000000000000000000000000000000000000..1df45e273ac1bed5fd8fc0b727e8c0a032c4ec58 --- /dev/null +++ b/src/bindings/php/Tests/PredicateTest.php @@ -0,0 +1,31 @@ +<?php +include_once 'hammer.php'; + +function predTest($token) +{ + return ($token[0] === $token[1]); +} + +class PredicateTest extends PHPUnit_Framework_TestCase +{ + protected $parser; + + protected function setUp() + { + $this->parser = predicate(h_many1(choice(ch('a'), ch('b'))), "predTest"); + } + public function testSuccess() + { + $result1 = h_parse($this->parser, "aa"); + $result2 = h_parse($this->parser, "bb"); + $this->assertEquals(["a", "a"], $result1); + $this->assertEquals(["b", "b"], $result2); + } + public function testFailure() + { + $result = h_parse($this->parser, "ab"); + $this->assertEquals(NULL, $result); + } +} + +?> \ No newline at end of file diff --git a/src/bindings/php/hammer.i b/src/bindings/php/hammer.i index 174cb9806c2f5fdfe0b86a0652f33d091331f425..c9753609b99604de7c04819bfa6e54f7e29c8693 100644 --- a/src/bindings/php/hammer.i +++ b/src/bindings/php/hammer.i @@ -4,15 +4,11 @@ %ignore HCountedArray_; %inline %{ -#define PHP_H_TT_PHP_DESCRIPTOR_RES_NAME "Hammer Token" static int h_tt_php; - static int le_h_tt_php_descriptor; %} %init %{ h_tt_php = h_allocate_token_type("com.upstandinghackers.hammer.php"); - // TODO: implement h_arena_free, register a token dtor here - le_h_tt_php_descriptor = zend_register_list_destructors_ex(NULL, NULL, PHP_H_TT_PHP_DESCRIPTOR_RES_NAME, module_number); %} %inline { @@ -146,9 +142,29 @@ return tok; } + static int call_predicate(HParseResult *p, void *user_data) { + zval *args[1]; + zval func; + zval *ret; + ALLOC_INIT_ZVAL(ret); + ZVAL_STRING(&func, (const char*)user_data, 0); + hpt_to_php(p->ast, args[0]); + int ok = call_user_function(EG(function_table), NULL, &func, ret, 1, args TSRMLS_CC); + if (ok != SUCCESS) { + printf("call_user_function failed\n"); + // FIXME throw some error + return 0; + } + return Z_LVAL_P(ret); + } + HParser* action(HParser *parser, const char *name) { return h_action(parser, call_action, (void*)name); } + + HParser* predicate(HParser *parser, const char *name) { + return h_attr_bool(parser, call_predicate, (void*)name); + } } %pragma(php) code="