]> granicus.if.org Git - php/commitdiff
- Initial patch to support importing from class scopes (for Stig).
authorAndi Gutmans <andi@php.net>
Sat, 2 Mar 2002 20:38:52 +0000 (20:38 +0000)
committerAndi Gutmans <andi@php.net>
Sat, 2 Mar 2002 20:38:52 +0000 (20:38 +0000)
- It isn't complete yet but I want to work on it from another machine. It
- shouldn't break anything else so just don't try and use it.
- The following is a teaser of something that already works:
<?php

class MyClass
{
function hello()
{
print "Hello, World\n";
}
class MyClass2
{
function hello()
{
print "Hello, World in MyClass2\n";
}
}
}

import function hello, class MyClass2 from MyClass;

MyClass2::hello();
hello();
?>

Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_execute.c
Zend/zend_globals.h
Zend/zend_language_parser.y
Zend/zend_language_scanner.l

index 33216efa873873c682888289f6cab4c9511fd377..997848d350272beb8ceae4a2b05f9d3fe660bb1e 100644 (file)
@@ -552,6 +552,60 @@ zend_bool zend_is_function_or_method_call(znode *variable)
        return  ((type & ZEND_PARSED_METHOD_CALL) || (type == ZEND_PARSED_FUNCTION_CALL));
 }
 
+void zend_do_begin_import(TSRMLS_D)
+{
+       zend_llist_init(&CG(import_commands), sizeof(zend_op), NULL, 0);
+}
+
+void zend_do_import(int type, znode *what TSRMLS_DC)
+{
+       zend_op opline;
+
+       init_op(&opline TSRMLS_CC);
+
+       switch (type) {
+               case T_FUNCTION:
+                       opline.opcode = ZEND_IMPORT_FUNCTION;
+                       break;
+               case T_CLASS:
+                       opline.opcode = ZEND_IMPORT_CLASS;
+                       break;
+               case T_CONST:
+                       opline.opcode = ZEND_IMPORT_CONST;
+                       break;
+       }
+
+       if (what) {
+               if (type == T_FUNCTION || type == T_CLASS) {
+                       zend_str_tolower(what->u.constant.value.str.val, what->u.constant.value.str.len);
+               }
+               opline.op2 = *what;
+       } else {
+               SET_UNUSED(opline.op2);
+       }
+       
+       zend_llist_add_element(&CG(import_commands), &opline);
+}
+
+void zend_do_end_import(znode *import_from TSRMLS_DC)
+{
+       zend_llist_element *le;
+       zend_op *opline, *opline_ptr;
+
+       
+       le = CG(import_commands).head;
+
+       while (le) {
+               opline_ptr = (zend_op *)le->data;
+               opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+               memcpy(opline, opline_ptr, sizeof(zend_op));
+               opline->op1 = *import_from;
+               le = le->next;
+       }
+       zend_llist_destroy(&CG(import_commands));
+}
+
+
 
 void zend_do_begin_variable_parse(TSRMLS_D)
 {
index aa2043a938f124d228b53539c96a66a7ed8d3282..4b00f5727bf6278a153a1f0a560b7b5c53e6add8 100644 (file)
@@ -366,6 +366,10 @@ void zend_do_extended_fcall_end(TSRMLS_D);
 
 void zend_do_ticks(TSRMLS_D);
 
+void zend_do_begin_import(TSRMLS_D);
+void zend_do_import(int type, znode *what TSRMLS_DC);
+void zend_do_end_import(znode *import_from TSRMLS_DC);
+
 ZEND_API void function_add_ref(zend_function *function);
 
 #define INITIAL_OP_ARRAY_SIZE 64
@@ -540,16 +544,20 @@ int zendlex(znode *zendlval TSRMLS_DC);
 #define ZEND_CATCH                                     107
 #define ZEND_THROW                                     108
 
-#define ZEND_FETCH_CLASS                       110
+#define ZEND_FETCH_CLASS                       109
+
+#define ZEND_CLONE                                     110
 
-#define ZEND_CLONE                                     111
+#define ZEND_INIT_CTOR_CALL                    111
+#define ZEND_INIT_METHOD_CALL          112
+#define ZEND_INIT_STATIC_METHOD_CALL 113
 
-#define ZEND_INIT_CTOR_CALL                    112
-#define ZEND_INIT_METHOD_CALL          113
-#define ZEND_INIT_STATIC_METHOD_CALL 114
+#define ZEND_ISSET_ISEMPTY_VAR         114
+#define ZEND_ISSET_ISEMPTY_DIM_OBJ     115
 
-#define ZEND_ISSET_ISEMPTY_VAR         115
-#define ZEND_ISSET_ISEMPTY_DIM_OBJ     116
+#define        ZEND_IMPORT_FUNCTION            116
+#define        ZEND_IMPORT_CLASS                       117
+#define        ZEND_IMPORT_CONST                       118
 
 /* end of block */
 
index a45781a2ba180f816e4381600dcea50f83b2ff27..b9d91e06c3f7ec86719648f9ac185de18b20070b 100644 (file)
@@ -1402,6 +1402,67 @@ binary_assign_op_addr: {
                                        FREE_OP(EX(Ts), &EX(opline)->op2, EG(free_op2));
                                }
                                NEXT_OPCODE();
+                       case ZEND_IMPORT_FUNCTION:
+                               {
+                                       zend_class_entry *ce;
+                                       zend_function *function;
+                                       
+                                       ce = EX(Ts)[EX(opline)->op1.u.var].EA.class_entry;
+
+                                       if (EX(opline)->op2.op_type != IS_UNUSED) {
+                                               char *function_name_strval;
+                                               int function_name_strlen;
+
+                                               function_name_strval = EX(opline)->op2.u.constant.value.str.val;
+                                               function_name_strlen = EX(opline)->op2.u.constant.value.str.len;
+
+                                               if (zend_hash_find(&ce->function_table, function_name_strval, function_name_strlen + 1, (void **) &function)==FAILURE) {
+                                                       zend_error(E_ERROR, "Import: function %s() not found", function_name_strval);
+                                               }
+                                               if (zend_hash_add(EG(function_table), function_name_strval, function_name_strlen + 1, function, sizeof(zend_function), NULL) == FAILURE) {
+                                                       zend_error(E_ERROR, "Import: function %s() already exists in current scope", function_name_strval);
+                                               }
+                                               function_add_ref(function);
+                                       } else {
+                                               //zend_hash_apply(&ce->function_table, (apply_func_t) zend_import_function, (void *) 1 TSRMLS_CC);
+                                       }
+                                       NEXT_OPCODE();
+                               }
+                       case ZEND_IMPORT_CLASS:
+                               {
+                                       zend_class_entry *ce;
+                                       zend_class_entry *import_ce;
+                                       
+                                       ce = EX(Ts)[EX(opline)->op1.u.var].EA.class_entry;
+
+                                       if (EX(opline)->op2.op_type != IS_UNUSED) {
+                                               char *class_name_strval;
+                                               int class_name_strlen;
+                                               
+                                               class_name_strval = EX(opline)->op2.u.constant.value.str.val;
+                                               class_name_strlen = EX(opline)->op2.u.constant.value.str.len;
+                                               
+                                               if (zend_hash_find(&ce->class_table, class_name_strval, class_name_strlen + 1, (void **) &import_ce)==FAILURE) {
+                                                       zend_error(E_ERROR, "Import: class %s not found", class_name_strval);
+                                               }
+                                               if (zend_hash_add(EG(class_table), class_name_strval, class_name_strlen + 1, import_ce, sizeof(zend_class_entry), NULL) == FAILURE) {
+                                                       zend_error(E_ERROR, "Import: class %s already exists in current scope", class_name_strval);
+                                               }
+                                               zend_class_add_ref(import_ce);
+                                       } else {
+                                               //zend_hash_apply(&ce->function_table, (apply_func_t) zend_import_function, (void *) 1 TSRMLS_CC);
+                                       }
+
+                                       NEXT_OPCODE();
+                               }
+                       case ZEND_IMPORT_CONST:
+                               {
+                                       zend_class_entry *ce;
+                                       
+                                       ce = EX(Ts)[EX(opline)->op1.u.var].EA.class_entry;
+
+                                       NEXT_OPCODE();
+                               }
                        case ZEND_FETCH_CLASS:
                                {
                                        if (EX(opline)->op1.op_type == IS_UNUSED) {
index 2139e54fcf832411742bd6e9af88455569d469c3..7b029b0e316491f5f9d73cd80ba77a7d9be162f2 100644 (file)
@@ -119,6 +119,8 @@ struct _zend_compiler_globals {
        int interactive;
 
        zend_bool increment_lineno;
+
+       zend_llist import_commands;
 };
 
 
index accea627e65f5690f1695e3acb24e843cce24468..0e36bc02a51a69c18969463aedf5021660288434 100644 (file)
 %token T_DOLLAR_OPEN_CURLY_BRACES
 %token T_CURLY_OPEN
 %token T_PAAMAYIM_NEKUDOTAYIM
+%token T_IMPORT T_FROM
 
 %% /* Rules */
 
@@ -206,10 +207,31 @@ unticked_statement:
        |       T_DECLARE { zend_do_declare_begin(TSRMLS_C); } '(' declare_list ')' declare_statement { zend_do_declare_end(TSRMLS_C); }
        |       ';'             /* empty statement */
        |       T_TRY { zend_do_try(&$1 TSRMLS_CC); } '{' inner_statement_list '}'
-               T_CATCH '(' catch_class_entry T_VARIABLE ')' { zend_do_begin_catch(&$1, &$8, &$9, 1 TSRMLS_CC); } '{' inner_statement_list '}' { zend_do_end_catch(&$1 TSRMLS_CC); }
+               T_CATCH '(' catch_or_import_class_entry T_VARIABLE ')' { zend_do_begin_catch(&$1, &$8, &$9, 1 TSRMLS_CC); } '{' inner_statement_list '}' { zend_do_end_catch(&$1 TSRMLS_CC); }
                additional_catches
        |       T_THROW expr ';' { zend_do_throw(&$2 TSRMLS_CC); }
        |       T_DELETE  cvar  ';' { zend_do_end_variable_parse(BP_VAR_UNSET, 0 TSRMLS_CC); zend_do_unset(&$1, ZEND_UNSET_OBJ TSRMLS_CC); }
+       |       T_IMPORT { zend_do_begin_import(TSRMLS_C); } import_rule T_FROM catch_or_import_class_entry { zend_do_end_import(&$5 TSRMLS_CC); } ';'
+;
+
+
+import_rule:
+               '*'     { zend_do_import(T_FUNCTION, NULL TSRMLS_CC); zend_do_import(T_CLASS, NULL TSRMLS_CC); zend_do_import(T_CONST, NULL TSRMLS_CC); }
+       |       import_commands
+;
+
+import_commands:
+               import_commands ',' import_command
+       |       import_command
+;
+
+import_command:
+               T_FUNCTION T_STRING { zend_do_import(T_FUNCTION, &$2 TSRMLS_CC); }
+       |       T_CLASS T_STRING        { zend_do_import(T_CLASS, &$2 TSRMLS_CC); }
+       |       T_CONST T_STRING        { zend_do_import(T_CONST, &$2 TSRMLS_CC); }
+       |       T_FUNCTION '*'          { zend_do_import(T_FUNCTION, NULL TSRMLS_CC); }
+       |       T_CLASS '*'                     { zend_do_import(T_CLASS, NULL TSRMLS_CC); }
+       |       T_CONST '*'                     { zend_do_import(T_CONST, NULL TSRMLS_CC); }
 ;
 
 additional_catches:
@@ -218,8 +240,8 @@ additional_catches:
 ;
 
 non_empty_additional_catches:
-               non_empty_additional_catches T_CATCH '(' catch_class_entry T_VARIABLE ')' { zend_do_begin_catch(&$2, &$4, &$5, 0 TSRMLS_CC); } '{' inner_statement_list '}' { zend_do_end_catch(&$2 TSRMLS_CC); }
-       |       T_CATCH '(' catch_class_entry T_VARIABLE ')' { zend_do_begin_catch(&$1, &$3, &$4, 0 TSRMLS_CC); } '{' inner_statement_list '}' { zend_do_end_catch(&$1 TSRMLS_CC); }
+               non_empty_additional_catches T_CATCH '(' catch_or_import_class_entry T_VARIABLE ')' { zend_do_begin_catch(&$2, &$4, &$5, 0 TSRMLS_CC); } '{' inner_statement_list '}' { zend_do_end_catch(&$2 TSRMLS_CC); }
+       |       T_CATCH '(' catch_or_import_class_entry T_VARIABLE ')' { zend_do_begin_catch(&$1, &$3, &$4, 0 TSRMLS_CC); } '{' inner_statement_list '}' { zend_do_end_catch(&$1 TSRMLS_CC); }
 ;
 
 
@@ -542,7 +564,7 @@ parse_class_name_entry:
        |       T_STRING T_PAAMAYIM_NEKUDOTAYIM { $$ = $1; zend_str_tolower($$.u.constant.value.str.val, $$.u.constant.value.str.len); }
 ;
 
-catch_class_entry:
+catch_or_import_class_entry:
                parse_class_entry T_STRING { do_fetch_class(&$$, &$1, &$2 TSRMLS_CC); }
        |       T_STRING { do_fetch_class(&$$, NULL, &$1 TSRMLS_CC); }
 ;
index 16ad7d8c825f7c9f8e5de1ef1a00eea76652eed4..d3b2f03c4ed44f7b6fbcb9cee32c9c8a4e5bb7b5 100644 (file)
@@ -669,6 +669,14 @@ NEWLINE ("\r"|"\n"|"\r\n")
        return T_INCLUDE;
 }
 
+<ST_IN_SCRIPTING>"import" {
+       return T_IMPORT;
+}
+
+<ST_IN_SCRIPTING>"from" {
+       return T_FROM;
+}
+
 <ST_IN_SCRIPTING>"include_once" {
        return T_INCLUDE_ONCE;
 }