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;
}
ZEND_AST_ARRAY_ELEM,
ZEND_AST_ENCAPS_LIST,
+ ZEND_AST_EXPR_LIST,
ZEND_AST_STMT_LIST,
ZEND_AST_GLOBAL,
ZEND_AST_WHILE,
ZEND_AST_DO_WHILE,
+ ZEND_AST_FOR,
};
typedef unsigned short zend_ast_kind;
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);
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) {
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 */
{ $$.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)); }
';' { 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); }
;
for_statement:
- statement { AS($1); }
- | ':' inner_statement_list T_ENDFOR ';'
+ statement { $$.u.ast = $1.u.ast; }
+ | ':' inner_statement_list T_ENDFOR ';' { AN($$); }
;
;
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:
{ $$.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; }
{ $$.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:
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: