refactor hpt_to_php to eliminate code duplication
This commit is contained in:
parent
aae140a420
commit
ab23a29b0e
2 changed files with 48 additions and 77 deletions
|
|
@ -11,21 +11,21 @@ class ActionTest extends PHPUnit_Framework_TestCase
|
||||||
}
|
}
|
||||||
protected function setUp()
|
protected function setUp()
|
||||||
{
|
{
|
||||||
//$this->parser = h_action(sequence(choice(ch("a"), ch("A")), choice(ch("b"), ch("B"))), "actTest");
|
$this->parser = h_action(sequence(choice(ch("a"), ch("A")), choice(ch("b"), ch("B"))), "actTest");
|
||||||
}
|
}
|
||||||
public function testSuccess()
|
public function testSuccess()
|
||||||
{
|
{
|
||||||
/* $result1 = h_parse($this->parser, "ab"); */
|
$result1 = h_parse($this->parser, "ab");
|
||||||
/* $result2 = h_parse($this->parser, "AB"); */
|
$result2 = h_parse($this->parser, "AB");
|
||||||
/* $result3 = h_parse($this->parser, "aB"); */
|
$result3 = h_parse($this->parser, "aB");
|
||||||
/* $this->assertEquals("AB", $result1); */
|
$this->assertEquals("AB", $result1);
|
||||||
/* $this->assertEquals("AB", $result2); */
|
$this->assertEquals("AB", $result2);
|
||||||
/* $this->assertEquals("AB", $result3); */
|
$this->assertEquals("AB", $result3);
|
||||||
}
|
}
|
||||||
public function testFailure()
|
public function testFailure()
|
||||||
{
|
{
|
||||||
//$result = h_parse($this->parser, "XX");
|
$result = h_parse($this->parser, "XX");
|
||||||
//$this->assertEquals(NULL, $result);
|
$this->assertEquals(NULL, $result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
%module hammer;
|
%module hammer;
|
||||||
|
%include "exception.i";
|
||||||
|
|
||||||
%ignore HCountedArray_;
|
%ignore HCountedArray_;
|
||||||
|
|
||||||
|
|
@ -13,7 +14,7 @@
|
||||||
%inline {
|
%inline {
|
||||||
struct HParsedToken_;
|
struct HParsedToken_;
|
||||||
struct HParseResult_;
|
struct HParseResult_;
|
||||||
static zval* hpt_to_php(const struct HParsedToken_ *token);
|
void hpt_to_php(zval *return_value, const struct HParsedToken_ *token);
|
||||||
|
|
||||||
static struct HParsedToken_* call_action(const struct HParseResult_ *p, void* user_data);
|
static struct HParsedToken_* call_action(const struct HParseResult_ *p, void* user_data);
|
||||||
}
|
}
|
||||||
|
|
@ -37,18 +38,17 @@
|
||||||
for (i=0; i<size; i++) {
|
for (i=0; i<size; i++) {
|
||||||
zval **data;
|
zval **data;
|
||||||
if (zend_hash_index_find(arr, i, (void**)&data) == FAILURE) {
|
if (zend_hash_index_find(arr, i, (void**)&data) == FAILURE) {
|
||||||
// FIXME raise some error
|
SWIG_exception(SWIG_IndexError, "index in parser array out of bounds");
|
||||||
arg1 = NULL;
|
$1 = NULL;
|
||||||
} else {
|
} else {
|
||||||
res = SWIG_ConvertPtr(*data, &($1[i]), SWIGTYPE_p_HParser_, 0 | 0);
|
res = SWIG_ConvertPtr(*data, &($1[i]), SWIGTYPE_p_HParser_, 0 | 0);
|
||||||
if (!SWIG_IsOK(res)) {
|
if (!SWIG_IsOK(res)) {
|
||||||
// TODO do we not *have* SWIG_TypeError?
|
SWIG_exception(SWIG_TypeError, "that wasn't an HParser");
|
||||||
SWIG_exception_fail(res, "that wasn't an HParser");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// FIXME raise some error
|
SWIG_exception(SWIG_TypeError, "that wasn't an array of HParsers");
|
||||||
$1 = NULL;
|
$1 = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -74,43 +74,11 @@
|
||||||
*/
|
*/
|
||||||
%typemap(out) struct HParseResult_* {
|
%typemap(out) struct HParseResult_* {
|
||||||
if ($1 == NULL) {
|
if ($1 == NULL) {
|
||||||
// TODO: raise parse failure
|
/* If we want parse errors to be exceptions, this is the place to do it */
|
||||||
|
//SWIG_exception(SWIG_TypeError, "typemap: should have been an HParseResult*, was NULL");
|
||||||
RETVAL_NULL();
|
RETVAL_NULL();
|
||||||
} else {
|
} else {
|
||||||
if ($1->ast == NULL) {
|
hpt_to_php($result, $1->ast);
|
||||||
RETVAL_NULL();
|
|
||||||
} else {
|
|
||||||
switch($1->ast->token_type) {
|
|
||||||
case TT_NONE:
|
|
||||||
RETVAL_NULL();
|
|
||||||
break;
|
|
||||||
case TT_BYTES:
|
|
||||||
RETVAL_STRINGL((char*)$1->ast->token_data.bytes.token, $1->ast->token_data.bytes.len, 1);
|
|
||||||
break;
|
|
||||||
case TT_SINT:
|
|
||||||
RETVAL_LONG($1->ast->token_data.sint);
|
|
||||||
break;
|
|
||||||
case TT_UINT:
|
|
||||||
RETVAL_LONG($1->ast->token_data.uint);
|
|
||||||
break;
|
|
||||||
case TT_SEQUENCE:
|
|
||||||
array_init($result);
|
|
||||||
for (int i=0; i < $1->ast->token_data.seq->used; i++) {
|
|
||||||
add_next_index_zval($result, hpt_to_php($1->ast->token_data.seq->elements[i]));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* if (token->token_type == h_tt_php) { */
|
|
||||||
/* ZEND_REGISTER_RESOURCE(return_value, token->token_data.user, le_swig__p_void); // it's a void*, what else could I do with it? */
|
|
||||||
/* return return_value; */
|
|
||||||
/* } else { */
|
|
||||||
/* // I guess that's a python thing */
|
|
||||||
/* //return (zval*)SWIG_NewPointerObj((void*)token, SWIGTYPE_p_HParsedToken_, 0 | 0); */
|
|
||||||
/* // TODO: support registry */
|
|
||||||
/* } */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|
@ -126,41 +94,44 @@
|
||||||
%include "../swig/hammer.i";
|
%include "../swig/hammer.i";
|
||||||
|
|
||||||
%inline {
|
%inline {
|
||||||
static zval* hpt_to_php(const HParsedToken *token) {
|
void hpt_to_php(zval *return_value, const HParsedToken *token) {
|
||||||
zval *ret;
|
if (!token) {
|
||||||
ALLOC_INIT_ZVAL(ret);
|
RETVAL_NULL();
|
||||||
if (token == NULL) {
|
return;
|
||||||
ZVAL_NULL(ret);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
switch (token->token_type) {
|
switch (token->token_type) {
|
||||||
case TT_NONE:
|
case TT_NONE:
|
||||||
ZVAL_NULL(ret);
|
RETVAL_NULL();
|
||||||
return ret;
|
break;
|
||||||
case TT_BYTES:
|
case TT_BYTES:
|
||||||
ZVAL_STRINGL(ret, (char*)token->token_data.bytes.token, token->token_data.bytes.len, 1);
|
RETVAL_STRINGL((char*)token->token_data.bytes.token, token->token_data.bytes.len, 1);
|
||||||
return ret;
|
break;
|
||||||
case TT_SINT:
|
case TT_SINT:
|
||||||
ZVAL_LONG(ret, token->token_data.sint);
|
RETVAL_LONG(token->token_data.sint);
|
||||||
return ret;
|
break;
|
||||||
case TT_UINT:
|
case TT_UINT:
|
||||||
ZVAL_LONG(ret, token->token_data.uint);
|
RETVAL_LONG(token->token_data.uint);
|
||||||
return ret;
|
break;
|
||||||
case TT_SEQUENCE:
|
case TT_SEQUENCE:
|
||||||
array_init(ret);
|
array_init(return_value);
|
||||||
for (int i=0; i < token->token_data.seq->used; i++) {
|
for (int i=0; i < token->token_data.seq->used; i++) {
|
||||||
add_next_index_zval(ret, hpt_to_php(token->token_data.seq->elements[i]));
|
zval *tmp;
|
||||||
|
ALLOC_INIT_ZVAL(tmp);
|
||||||
|
hpt_to_php(tmp, token->token_data.seq->elements[i]);
|
||||||
|
add_next_index_zval(return_value, tmp);
|
||||||
}
|
}
|
||||||
return ret;
|
break;
|
||||||
default:
|
default:
|
||||||
/* if (token->token_type == h_tt_php) { */
|
if (token->token_type == h_tt_php) {
|
||||||
/* ZEND_REGISTER_RESOURCE(return_value, token->token_data.user, le_swig__p_void); // it's a void*, wh
|
RETVAL_RESOURCE(token->token_data.user);
|
||||||
/* return return_value; */
|
} else {
|
||||||
/* } else { */
|
int res = 0;
|
||||||
/* // I guess that's a python thing */
|
res = SWIG_ConvertPtr(return_value, (void*)token, SWIGTYPE_p_HParsedToken_, 0 | 0);
|
||||||
/* //return (zval*)SWIG_NewPointerObj((void*)token, SWIGTYPE_p_HParsedToken_, 0 | 0); */
|
if (!SWIG_IsOK(res)) {
|
||||||
/* // TODO: support registry */
|
SWIG_exception(SWIG_TypeError, "hpt_to_php: that wasn't an HParsedToken");
|
||||||
/* } */
|
}
|
||||||
|
// TODO: support registry
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -170,13 +141,13 @@
|
||||||
zval ret;
|
zval ret;
|
||||||
// in PHP land, the HAction is passed by its name as a string
|
// in PHP land, the HAction is passed by its name as a string
|
||||||
if (IS_STRING != Z_TYPE_P((zval*)user_data)) {
|
if (IS_STRING != Z_TYPE_P((zval*)user_data)) {
|
||||||
printf("user_data wasn't a string");
|
printf("user_data wasn't a string\n");
|
||||||
// FIXME throw some error
|
// FIXME throw some error
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
zval *callable;
|
zval *callable;
|
||||||
callable = user_data;
|
callable = user_data;
|
||||||
args[0] = hpt_to_php(p->ast);
|
hpt_to_php(args[0], p->ast);
|
||||||
int ok = call_user_function(EG(function_table), NULL, callable, &ret, 1, args TSRMLS_CC);
|
int ok = call_user_function(EG(function_table), NULL, callable, &ret, 1, args TSRMLS_CC);
|
||||||
if (ok != SUCCESS) {
|
if (ok != SUCCESS) {
|
||||||
printf("call_user_function failed");
|
printf("call_user_function failed");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue