Irobeth
unread,Jul 27, 2009, 3:19:17 PM7/27/09Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to PHP Hacks
Modifying the Compiler
Postby irobeth on Sat Jul 25, 2009 6:55 pm
I'm trying to modify the compiler/tokenizer/language parser to allow
support for new keywords like unless / until
a) Is this even supported? There isn't documentation that I can find
anywhere official about how the compiler works or how to extend it, to
my knowledge.
b) I'm hitting a roadblock with a test for unless following the guide
at this website using 5.3.0, I have checked over and over to make sure
my code is like the examples but am being presented with:
Code: Select all
---- EXPECTED OUTPUT
unless FALSE is TRUE, this is printed
---- ACTUAL OUTPUT
Parse error: syntax error, unexpected '{' in {my path}php-5.3.0/
Zend/tests/unless.php on line 2
---- FAILED
for the test
Code: Select all
--TEST--
unless statement
--FILE--
<?php
unless(FALSE) {
print 'unless FALSE is TRUE, this is printed';
}
unless(TRUE) {
print 'unless TRUE is TRUE, this is printed';
}
?>
--EXPECT--
unless FALSE is TRUE, this is printed
Below are snippets relevant to this test:
===========================================================
zend_language_scanner.l :
<ST_IN_SCRIPTING>"if" {
return T_IF;
}
<ST_IN_SCRIPTING>"unless" {
return T_UNLESS;
}
<ST_IN_SCRIPTING>"elseif" {
return T_ELSEIF;
}
===========================================================
===========================================================
zend_language_parser.y :
%token T_DIR
%token T_NS_SEPARATOR
%token T_UNLESS
snip...
unticked_statement:
'{' inner_statement_list '}'
| T_IF '(' expr ')' { zend_do_if_cond(&$3, &$4
TSRMLS_CC); } statement { zend_do_if_after_statement(&$4, 1
TSRMLS_CC); } elseif_list else_single { zend_do_if_end(TSRMLS_C); }
| T_UNLESS '(' expr ')' { zend_do_unless_cond(&$3, &
$4 TSRMLS_CC); } statement { zend_do_if_after_statement(&$4, 1
TSRMLS_CC); } { zend_do_if_end(TSRMLS_C); }
===========================================================
===========================================================
zend_compile.h
void zend_do_if_cond(const znode *cond, znode
*closing_bracket_token TSRMLS_DC);
void zend_do_unless_cond(const znode *cond, znode
*closing_bracket_token TSRMLS_DC);
void zend_do_if_after_statement(const znode
*closing_bracket_token, unsigned char initialize TSRMLS_DC);
void zend_do_if_end(TSRMLS_D);
===========================================================
===========================================================
zend_compile.c
void zend_do_unless_cond(const znode *cond, znode
*closing_bracket_token TSRMLS_DC)
{
int unless_cond_op_number = get_next_op_number(CG
(active_op_array));
zend_op *opline = get_next_op(CG(active_op_array)
TSRMLS_CC);
opline->opcode = ZEND_JMPNZ;
opline->op1 = *cond;
closing_bracket_token->u.opline_num =
unless_cond_op_number;
SET_UNUSED(opline->op2);
INC_BPC(CG(active_op_array));
}
===========================================================
After making these changes and running make test, the output is:
=====================================================================
Running selected tests.
FAIL unless statement [Zend/tests/unless.phpt]
=====================================================================
Number of tests : 1 1
Tests skipped : 0 ( 0.0%) --------
Tests warned : 0 ( 0.0%) ( 0.0%)
Tests failed : 1 (100.0%) (100.0%)
Expected fail : 0 ( 0.0%) ( 0.0%)
Tests passed : 0 ( 0.0%) ( 0.0%)
---------------------------------------------------------------------
Time taken : 0 seconds
=====================================================================
=====================================================================
FAILED TEST SUMMARY
---------------------------------------------------------------------
unless statement [Zend/tests/unless.phpt]
=====================================================================
So clearly something is wrong, but what? Is modification of the
compiler just not something that's meant to be?