]> granicus.if.org Git - php/commitdiff
Support creating of ast nodes with >3 children
authorNikita Popov <nikic@php.net>
Thu, 10 Jul 2014 13:18:08 +0000 (15:18 +0200)
committerNikita Popov <nikic@php.net>
Thu, 10 Jul 2014 13:18:08 +0000 (15:18 +0200)
Zend/zend_ast.c
Zend/zend_ast.h
Zend/zend_language_parser.y

index 59b82e81e20c0f33d54f20b919484e2ab63c5258..c07d4355295dad96e11e6b5e77a2c926c3c39f9f 100644 (file)
@@ -41,38 +41,46 @@ ZEND_API zend_ast *zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr)
        return (zend_ast *) ast;
 }
 
-ZEND_API zend_ast* zend_ast_create_unary_ex(zend_ast_kind kind, zend_ast_attr attr, zend_ast *op0)
-{
-       zend_ast *ast = emalloc(sizeof(zend_ast));
+static zend_ast *zend_ast_create_from_va_list(
+       zend_uint children, zend_ast_kind kind, zend_ast_attr attr, va_list va
+) {
+       zend_uint i;
+
+       zend_ast *ast = emalloc(sizeof(zend_ast) + (children - 1) * sizeof(zend_ast *));
        ast->kind = kind;
        ast->attr = attr;
-       ast->children = 1;
-       ast->child[0] = op0;
+       ast->children = children;
+
+       for (i = 0; i < children; ++i) {
+               ast->child[i] = va_arg(va, zend_ast *);
+       }
+
        return ast;
 }
 
-ZEND_API zend_ast* zend_ast_create_binary_ex(
-       zend_ast_kind kind, zend_ast_attr attr, zend_ast *op0, zend_ast *op1
+ZEND_API zend_ast *zend_ast_create_ex(
+       zend_uint children, zend_ast_kind kind, zend_ast_attr attr, ...
 ) {
-       zend_ast *ast = emalloc(sizeof(zend_ast) + sizeof(zend_ast *));
-       ast->kind = kind;
-       ast->attr = attr;
-       ast->children = 2;
-       ast->child[0] = op0;
-       ast->child[1] = op1;
+       va_list va;
+       zend_ast *ast;
+
+       va_start(va, attr);
+       ast = zend_ast_create_from_va_list(children, kind, attr, va);
+       va_end(va);
+
        return ast;
 }
 
-ZEND_API zend_ast* zend_ast_create_ternary_ex(
-       zend_ast_kind kind, zend_ast_attr attr, zend_ast *op0, zend_ast *op1, zend_ast *op2
+ZEND_API zend_ast *zend_ast_create(
+       zend_uint children, zend_ast_kind kind, ...
 ) {
-       zend_ast *ast = emalloc(sizeof(zend_ast) + sizeof(zend_ast *) * 2);
-       ast->kind = kind;
-       ast->attr = attr;
-       ast->children = 3;
-       ast->child[0] = op0;
-       ast->child[1] = op1;
-       ast->child[2] = op2;
+       va_list va;
+       zend_ast *ast;
+
+       va_start(va, kind);
+       ast = zend_ast_create_from_va_list(children, kind, 0, va);
+       va_end(va);
+
        return ast;
 }
 
index 99d81578759743321f02e111f60d23ff0cadb24d..0f07b8983f2d456147edcd9a747e673c4b4a171d 100644 (file)
@@ -69,6 +69,7 @@ enum _zend_ast_kind {
        ZEND_AST_ARRAY_ELEM,
        ZEND_AST_ENCAPS_LIST,
 
+       ZEND_AST_EXPR_LIST,
        ZEND_AST_STMT_LIST,
 
        ZEND_AST_GLOBAL,
@@ -78,6 +79,7 @@ enum _zend_ast_kind {
 
        ZEND_AST_WHILE,
        ZEND_AST_DO_WHILE,
+       ZEND_AST_FOR,
 };
 
 typedef unsigned short zend_ast_kind;
@@ -102,12 +104,10 @@ static inline zval *zend_ast_get_zval(zend_ast *ast) {
 
 ZEND_API zend_ast *zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr);
 
-ZEND_API zend_ast *zend_ast_create_unary_ex(
-       zend_ast_kind kind, zend_ast_attr attr, zend_ast *op0);
-ZEND_API zend_ast *zend_ast_create_binary_ex(
-       zend_ast_kind kind, zend_ast_attr attr, zend_ast *op0, zend_ast *op1);
-ZEND_API zend_ast *zend_ast_create_ternary_ex(
-       zend_ast_kind kind, zend_ast_attr attr, zend_ast *op0, zend_ast *op1, zend_ast *op2);
+ZEND_API zend_ast *zend_ast_create_ex(
+       zend_uint children, zend_ast_kind kind, zend_ast_attr attr, ...);
+ZEND_API zend_ast *zend_ast_create(
+       zend_uint children, zend_ast_kind kind, ...);
 
 ZEND_API zend_ast *zend_ast_create_dynamic(zend_ast_kind kind);
 ZEND_API zend_ast *zend_ast_dynamic_add(zend_ast *ast, zend_ast *op);
@@ -123,16 +123,17 @@ ZEND_API void zend_ast_destroy(zend_ast *ast);
 static inline zend_ast *zend_ast_create_zval(zval *zv) {
        return zend_ast_create_zval_ex(zv, 0);
 }
+
 static inline zend_ast *zend_ast_create_unary(zend_ast_kind kind, zend_ast *op0) {
-       return zend_ast_create_unary_ex(kind, 0, op0);
+       return zend_ast_create(1, kind, op0);
 }
 static inline zend_ast *zend_ast_create_binary(zend_ast_kind kind, zend_ast *op0, zend_ast *op1) {
-       return zend_ast_create_binary_ex(kind, 0, op0, op1);
+       return zend_ast_create(2, kind, op0, op1);
 }
 static inline zend_ast *zend_ast_create_ternary(
        zend_ast_kind kind, zend_ast *op0, zend_ast *op1, zend_ast *op2
 ) {
-       return zend_ast_create_ternary_ex(kind, 0, op0, op1, op2);
+       return zend_ast_create(3, kind, op0, op1, op2);
 }
 
 static inline zend_ast *zend_ast_create_dynamic_and_add(zend_ast_kind kind, zend_ast *op) {
@@ -143,10 +144,13 @@ static inline zend_ast *zend_ast_create_var(zval *name) {
        return zend_ast_create_unary(ZEND_AST_VAR, zend_ast_create_zval(name));
 }
 static inline zend_ast *zend_ast_create_binary_op(zend_uint opcode, zend_ast *op0, zend_ast *op1) {
-       return zend_ast_create_binary_ex(ZEND_AST_BINARY_OP, opcode, op0, op1);
+       return zend_ast_create_ex(2, ZEND_AST_BINARY_OP, opcode, op0, op1);
 }
 static inline zend_ast *zend_ast_create_assign_op(zend_uint opcode, zend_ast *op0, zend_ast *op1) {
-       return zend_ast_create_binary_ex(ZEND_AST_ASSIGN_OP, opcode, op0, op1);
+       return zend_ast_create_ex(2, ZEND_AST_ASSIGN_OP, opcode, op0, op1);
+}
+static inline zend_ast *zend_ast_create_cast(zend_uint type, zend_ast *op0) {
+       return zend_ast_create_ex(1, ZEND_AST_CAST, type, op0);
 }
 
 /* Temporary, for porting */
index a7c03439f76b3858a16393a1a98ebda879c17f52..687999328262dbd6b85b818ab70e51b9763b141b 100644 (file)
@@ -329,7 +329,9 @@ unticked_statement:
                        { $$.u.ast = zend_ast_create_binary(ZEND_AST_WHILE, $2.u.ast, $3.u.ast); }
        |       T_DO statement T_WHILE parenthesis_expr ';'
                        { $$.u.ast = zend_ast_create_binary(ZEND_AST_DO_WHILE, $2.u.ast, $4.u.ast); }
-       |       T_FOR
+       |       T_FOR '(' for_expr ';' for_expr ';' for_expr ')' for_statement
+                       { $$.u.ast = NULL; }
+       /*|     T_FOR
                        '('
                                for_expr
                        ';' { zend_do_free(&$3 TSRMLS_CC); $4.u.op.opline_num = get_next_op_number(CG(active_op_array)); }
@@ -337,7 +339,7 @@ unticked_statement:
                        ';' { zend_do_extended_info(TSRMLS_C); zend_do_for_cond(&$6, &$7 TSRMLS_CC); }
                                for_expr
                        ')' { zend_do_free(&$9 TSRMLS_CC); zend_do_for_before_statement(&$4, &$7 TSRMLS_CC); }
-                       for_statement { zend_do_for_end(&$7 TSRMLS_CC); AN($$); }
+                       for_statement { zend_do_for_end(&$7 TSRMLS_CC); AN($$); }*/
        |       T_SWITCH parenthesis_expr       { AC($2); zend_do_switch_cond(&$2 TSRMLS_CC); } switch_case_list { zend_do_switch_end(&$4 TSRMLS_CC); AN($$); }
        |       T_BREAK ';'                     { $$.u.ast = zend_ast_create_unary(ZEND_BRK, NULL); }
        |       T_BREAK expr ';'        { $$.u.ast = zend_ast_create_unary(ZEND_BRK, $2.u.ast); }
@@ -489,8 +491,8 @@ foreach_variable:
 ;
 
 for_statement:
-               statement { AS($1); }
-       |       ':' inner_statement_list T_ENDFOR ';'
+               statement { $$.u.ast = $1.u.ast; }
+       |       ':' inner_statement_list T_ENDFOR ';' { AN($$); }
 ;
 
 
@@ -751,13 +753,13 @@ echo_expr:
 ;
 
 for_expr:
-               /* empty */                     { $$.op_type = IS_CONST;  ZVAL_BOOL(&$$.u.constant, 1); }
-       |       non_empty_for_expr      { $$ = $1; }
+               /* empty */                     { $$.u.ast = NULL; }
+       |       non_empty_for_expr      { $$.u.ast = $1.u.ast; }
 ;
 
 non_empty_for_expr:
-               non_empty_for_expr ','  { zend_do_free(&$1 TSRMLS_CC); } expr { AC($4); $$ = $4; }
-       |       expr                                    { AC($1); $$ = $1; }
+               non_empty_for_expr ',' expr { $$.u.ast = zend_ast_dynamic_add($1.u.ast, $3.u.ast); }
+       |       expr { $$.u.ast = zend_ast_create_dynamic_and_add(ZEND_AST_EXPR_LIST, $1.u.ast); }
 ;
 
 new_expr:
@@ -858,19 +860,19 @@ expr_without_variable:
                        { $$.u.ast = zend_ast_create_ternary(ZEND_AST_CONDITIONAL, $1.u.ast, NULL, $4.u.ast); }
        |       internal_functions_in_yacc { $$.u.ast = $1.u.ast; }
        |       T_INT_CAST expr
-                       { $$.u.ast = zend_ast_create_unary_ex(ZEND_AST_CAST, IS_LONG, $2.u.ast); }
+                       { $$.u.ast = zend_ast_create_cast(IS_LONG, $2.u.ast); }
        |       T_DOUBLE_CAST expr
-                       { $$.u.ast = zend_ast_create_unary_ex(ZEND_AST_CAST, IS_DOUBLE, $2.u.ast); }
+                       { $$.u.ast = zend_ast_create_cast(IS_DOUBLE, $2.u.ast); }
        |       T_STRING_CAST expr
-                       { $$.u.ast = zend_ast_create_unary_ex(ZEND_AST_CAST, IS_STRING, $2.u.ast); }
+                       { $$.u.ast = zend_ast_create_cast(IS_STRING, $2.u.ast); }
        |       T_ARRAY_CAST expr
-                       { $$.u.ast = zend_ast_create_unary_ex(ZEND_AST_CAST, IS_ARRAY, $2.u.ast); }
+                       { $$.u.ast = zend_ast_create_cast(IS_ARRAY, $2.u.ast); }
        |       T_OBJECT_CAST expr
-                       { $$.u.ast = zend_ast_create_unary_ex(ZEND_AST_CAST, IS_OBJECT, $2.u.ast); }
+                       { $$.u.ast = zend_ast_create_cast(IS_OBJECT, $2.u.ast); }
        |       T_BOOL_CAST expr
-                       { $$.u.ast = zend_ast_create_unary_ex(ZEND_AST_CAST, _IS_BOOL, $2.u.ast); }
+                       { $$.u.ast = zend_ast_create_cast(_IS_BOOL, $2.u.ast); }
        |       T_UNSET_CAST expr
-                       { $$.u.ast = zend_ast_create_unary_ex(ZEND_AST_CAST, IS_NULL, $2.u.ast); }
+                       { $$.u.ast = zend_ast_create_cast(IS_NULL, $2.u.ast); }
        |       T_EXIT exit_expr { $$.u.ast = zend_ast_create_unary(ZEND_EXIT, $2.u.ast); }
        |       '@' expr { $$.u.ast = zend_ast_create_unary(ZEND_AST_SILENCE, $2.u.ast); }
        |       scalar { $$.u.ast = $1.u.ast; }
@@ -1123,9 +1125,9 @@ array_pair:
                        { $$.u.ast = zend_ast_create_binary(ZEND_AST_ARRAY_ELEM, $3.u.ast, $1.u.ast); }
        |       expr { $$.u.ast = zend_ast_create_binary(ZEND_AST_ARRAY_ELEM, $1.u.ast, NULL); }
        |       expr T_DOUBLE_ARROW '&' variable
-                       { $$.u.ast = zend_ast_create_binary_ex(ZEND_AST_ARRAY_ELEM, 1, $4.u.ast, $1.u.ast); }
+                       { $$.u.ast = zend_ast_create_ex(2, ZEND_AST_ARRAY_ELEM, 1, $4.u.ast, $1.u.ast); }
        |       '&' variable
-                       { $$.u.ast = zend_ast_create_binary_ex(ZEND_AST_ARRAY_ELEM, 1, $2.u.ast, NULL); }
+                       { $$.u.ast = zend_ast_create_ex(2, ZEND_AST_ARRAY_ELEM, 1, $2.u.ast, NULL); }
 ;
 
 encaps_list:
@@ -1170,17 +1172,15 @@ internal_functions_in_yacc:
                T_ISSET '(' isset_variables ')' { $$.u.ast  = $3.u.ast; }
        |       T_EMPTY '(' expr ')' { $$.u.ast = zend_ast_create_unary(ZEND_AST_EMPTY, $3.u.ast); }
        |       T_INCLUDE expr
-                       { $$.u.ast = zend_ast_create_unary_ex(ZEND_INCLUDE_OR_EVAL, ZEND_INCLUDE, $2.u.ast); }
+                       { $$.u.ast = zend_ast_create_ex(1, ZEND_INCLUDE_OR_EVAL, ZEND_INCLUDE, $2.u.ast); }
        |       T_INCLUDE_ONCE expr
-                       { $$.u.ast = zend_ast_create_unary_ex(
-                             ZEND_INCLUDE_OR_EVAL, ZEND_INCLUDE_ONCE, $2.u.ast); }
+                       { $$.u.ast = zend_ast_create_ex(1, ZEND_INCLUDE_OR_EVAL, ZEND_INCLUDE_ONCE, $2.u.ast); }
        |       T_EVAL '(' expr ')'
-                       { $$.u.ast = zend_ast_create_unary_ex(ZEND_INCLUDE_OR_EVAL, ZEND_EVAL, $3.u.ast); }
+                       { $$.u.ast = zend_ast_create_ex(1, ZEND_INCLUDE_OR_EVAL, ZEND_EVAL, $3.u.ast); }
        |       T_REQUIRE expr
-                       { $$.u.ast = zend_ast_create_unary_ex(ZEND_INCLUDE_OR_EVAL, ZEND_REQUIRE, $2.u.ast); }
+                       { $$.u.ast = zend_ast_create_ex(1, ZEND_INCLUDE_OR_EVAL, ZEND_REQUIRE, $2.u.ast); }
        |       T_REQUIRE_ONCE expr
-                       { $$.u.ast = zend_ast_create_unary_ex(
-                             ZEND_INCLUDE_OR_EVAL, ZEND_REQUIRE_ONCE, $2.u.ast); }
+                       { $$.u.ast = zend_ast_create_ex(1, ZEND_INCLUDE_OR_EVAL, ZEND_REQUIRE_ONCE, $2.u.ast); }
 ;
 
 isset_variables: