]> granicus.if.org Git - php/commitdiff
Port class const decl
authorNikita Popov <nikic@php.net>
Sat, 19 Jul 2014 13:13:50 +0000 (15:13 +0200)
committerNikita Popov <nikic@php.net>
Sat, 19 Jul 2014 13:13:50 +0000 (15:13 +0200)
Zend/zend_ast.h
Zend/zend_compile.c
Zend/zend_language_parser.y

index 01f83d6694da5383dfc96ec12e9e51e68bd2f999..bb184cd9a8b6d6a97cab8de0aa56e500f2acbd5d 100644 (file)
@@ -106,6 +106,9 @@ enum _zend_ast_kind {
 
        ZEND_AST_PROP_DECL,
        ZEND_AST_PROP_ELEM,
+
+       ZEND_AST_CLASS_CONST_DECL,
+       ZEND_AST_CONST_ELEM,
 };
 
 typedef unsigned short zend_ast_kind;
index 4697a4255d84ea93f76e0745363f27f03ba61397..66eb47010061746c5abf0145d6e48fc91d530829 100644 (file)
@@ -6512,6 +6512,44 @@ void zend_compile_prop_decl(zend_ast *ast TSRMLS_DC) {
        }
 }
 
+void zend_compile_class_const_decl(zend_ast *ast TSRMLS_DC) {
+       zend_class_entry *ce = CG(active_class_entry);
+       zend_uint i;
+
+       for (i = 0; i < ast->children; ++i) {
+               zend_ast *const_ast = ast->child[i];
+               zend_ast *name_ast = const_ast->child[0];
+               zend_ast *value_ast = const_ast->child[1];
+               zend_string *name = Z_STR_P(zend_ast_get_zval(name_ast));
+               zval value_zv;
+
+               if (ce->ce_flags & ZEND_ACC_TRAIT) {
+                       zend_error_noreturn(E_COMPILE_ERROR, "Traits cannot have constants");
+                       return;
+               }
+
+               if (value_ast) {
+                       _tmp_compile_const_expr(&value_zv, value_ast TSRMLS_CC);
+               } else {
+                       ZVAL_NULL(&value_zv);
+               }
+
+               if (Z_TYPE(value_zv) == IS_ARRAY
+                       || (Z_TYPE(value_zv) == IS_CONSTANT_AST && Z_ASTVAL(value_zv)->kind == ZEND_AST_ARRAY)
+               ) {
+                       zend_error_noreturn(E_COMPILE_ERROR, "Arrays are not allowed in class constants");
+               }
+
+               name = zend_new_interned_string(name TSRMLS_CC);
+               if (zend_hash_add(&ce->constants_table, name, &value_zv) == NULL) {
+                       zend_error_noreturn(E_COMPILE_ERROR, "Cannot redefine class constant %s::%s",
+                               ce->name->val, name);
+               }
+
+               // TODO.AST doc comment
+       }
+}
+
 void zend_compile_binary_op(znode *result, zend_ast *ast TSRMLS_DC) {
        zend_ast *left_ast = ast->child[0];
        zend_ast *right_ast = ast->child[1];
@@ -7352,6 +7390,9 @@ void zend_compile_stmt(zend_ast *ast TSRMLS_DC) {
                case ZEND_AST_PROP_DECL:
                        zend_compile_prop_decl(ast TSRMLS_CC);
                        break;
+               case ZEND_AST_CLASS_CONST_DECL:
+                       zend_compile_class_const_decl(ast TSRMLS_CC);
+                       break;
                default:
                {
                        znode result;
index 9febbc52a8acf2afb657ebb12d8ebc39b3b56818..e2018e517ada9e1824780a152832aa4f3c17159b 100644 (file)
@@ -628,7 +628,7 @@ class_statement_list:
 class_statement:
                variable_modifiers property_list ';'
                        { $$.u.ast = $2.u.ast; $$.u.ast->attr = Z_LVAL($1.u.constant); AS($$); }
-       |       class_constant_declaration ';'
+       |       class_const_list ';' { $$.u.ast = $1.u.ast; AS($$); }
        |       trait_use_statement
        |       method_modifiers function returns_ref T_STRING '(' parameter_list ')' method_body
                        { $$.u.ast = zend_ast_create_func_decl(ZEND_AST_METHOD, $3.EA | Z_LVAL($1.u.constant),
@@ -733,9 +733,15 @@ property:
                        { $$.u.ast = zend_ast_create_binary(ZEND_AST_PROP_ELEM, AST_ZVAL(&$1), $3.u.ast); }
 ;
 
-class_constant_declaration:
-               class_constant_declaration ',' T_STRING '=' static_scalar       { zend_do_declare_class_constant(&$3, &$5 TSRMLS_CC); }
-       |       T_CONST T_STRING '=' static_scalar      { zend_do_declare_class_constant(&$2, &$4 TSRMLS_CC); }
+class_const_list:
+               class_const_list ',' class_const { $$.u.ast = zend_ast_dynamic_add($1.u.ast, $3.u.ast); }
+       |       class_const
+                       { $$.u.ast = zend_ast_create_dynamic_and_add(ZEND_AST_CLASS_CONST_DECL, $1.u.ast); }
+;
+
+class_const:
+       T_CONST T_STRING '=' expr
+               { $$.u.ast = zend_ast_create_binary(ZEND_AST_CONST_ELEM, AST_ZVAL(&$2), $4.u.ast); }
 ;
 
 echo_expr_list: