📄 php_syntree.cpp
字号:
value_value_free(&call_params[i]->value); delete call_params[i]; }}PHP_SCOPE_TABLE make_scope_table(){ PHP_SCOPE_TABLE_TYPE *scope_map = new PHP_SCOPE_TABLE_TYPE; return scope_map;}void switch_push_scope_table(PHP_SCOPE_TABLE new_table){ PHP_SCOPE_STACK_TYPE *scope_stack = (PHP_SCOPE_STACK_TYPE *)g_scope_stack; scope_stack->push_back((PHP_SCOPE_TABLE_TYPE *)g_current_scope); g_current_scope = new_table;}void switch_pop_scope_table(int old_free){ PHP_SCOPE_STACK_TYPE *scope_stack = (PHP_SCOPE_STACK_TYPE *)g_scope_stack; if ( old_free ) { delete_scope_table(g_current_scope); } if ( scope_stack->size() == 0 ) { php_report_error(PHP_INTERNAL_ERROR, "Stack underrun - no valid scope"); } g_current_scope = scope_stack->back(); scope_stack->pop_back();}void delete_scope_table(PHP_SCOPE_TABLE scope){ PHP_SCOPE_TABLE_TYPE *scope_map = (PHP_SCOPE_TABLE_TYPE *)scope; for(PHP_SCOPE_TABLE_TYPE::iterator i = scope_map->begin(); i != scope_map->end();i++) { switch ( i->second->type ) { case PHP_SCOPE_PARAM: //break; case PHP_SCOPE_VAR: { //printf("removing %s\n", i->first.c_str()); PHP_VAR_NODE *var = i->second->var; var_node_free(var); } break; case PHP_SCOPE_FUNC: { PHP_SYN_NODE *func = i->second->func; php_syn_tree_free(func); } break; case PHP_SCOPE_CLASS: { PHP_SYN_NODE *class_decl = i->second->class_decl; php_syn_tree_free(class_decl); } break; case PHP_SCOPE_NONE: php_report_error(PHP_INTERNAL_ERROR, "Scope table can not have such items"); break; } delete i->second; } delete scope_map;} void add_func_2_scope(PHP_SCOPE_TABLE scope, PHP_SYN_NODE *func){ PHP_SCOPE_TABLE_TYPE *scope_map = (PHP_SCOPE_TABLE_TYPE *)scope; PHP_SCOPE_ITEM *it = new PHP_SCOPE_ITEM; it->type = PHP_SCOPE_FUNC; it->func = func; std::string key(func->func_decl->name); if ( scope_map->count(key) ) { // error - function already defined php_report_error(PHP_ERROR, "Can not add function to scope table - already present"); } else { (*scope_map)[key] = it; }}void add_class_2_scope(PHP_SCOPE_TABLE scope, PHP_SYN_NODE *class_node){ PHP_SCOPE_TABLE_TYPE *scope_map = (PHP_SCOPE_TABLE_TYPE *)scope; PHP_SCOPE_ITEM *it = new PHP_SCOPE_ITEM; it->type = PHP_SCOPE_CLASS; it->class_decl = class_node; std::string key(class_node->class_decl->name); if ( scope_map->count(key) ) { // error - function already defined php_report_error(PHP_ERROR, "Can not add function to scope table - already present"); } else { (*scope_map)[key] = it; }}PHP_SCOPE_ITEM *make_named_scope_item(PHP_SCOPE_TABLE scope, const char *name){ PHP_SCOPE_TABLE_TYPE *scope_map = (PHP_SCOPE_TABLE_TYPE *)scope; PHP_SCOPE_ITEM *it = new PHP_SCOPE_ITEM; memset(it, 0, sizeof(PHP_SCOPE_ITEM)); std::string key(name); (*scope_map)[key] = it; return it;}PHP_SCOPE_ITEM *add_var_2_scope(PHP_SCOPE_TABLE scope, PHP_VAR_NODE *var, const char *name){ PHP_SCOPE_ITEM *it = make_named_scope_item(scope, name); it->type = PHP_SCOPE_VAR; it->var = var; var->ref_count++; return it;}PHP_SCOPE_ITEM_TYPE get_scope_item_type(PHP_SCOPE_TABLE scope, const char *name){ PHP_SCOPE_TABLE_TYPE *scope_map = (PHP_SCOPE_TABLE_TYPE *)scope; std::string key(name); if ( scope_map->count(key) ) { PHP_SCOPE_ITEM *it = (*scope_map)[key]; return it->type; } return PHP_SCOPE_NONE;}PHP_SCOPE_ITEM *get_scope_item(PHP_SCOPE_TABLE scope, const char *name){ assert(name); PHP_SCOPE_TABLE_TYPE *scope_map = (PHP_SCOPE_TABLE_TYPE *)scope; std::string key(name); if ( scope_map->count(key) ) { PHP_SCOPE_ITEM *it = (*scope_map)[key]; return it; } return 0;}const char *get_scope_var_name(PHP_SCOPE_TABLE scope, PHP_VAR_NODE *var){ PHP_SCOPE_TABLE_TYPE *scope_map = (PHP_SCOPE_TABLE_TYPE *)scope; for(PHP_SCOPE_TABLE_TYPE::iterator i = scope_map->begin(); i != scope_map->end();i++) { if ( i->second->type == PHP_SCOPE_VAR ) { PHP_VAR_NODE *curr_var = i->second->var; if ( curr_var == var ) { return i->first.c_str(); } } } return 0;}/* array operations */const std::string &array_get_ith_key(PHP_VALUE_NODE *array, int i){ PHP_ARRAY_TYPE *arr_ptr = (PHP_ARRAY_TYPE *)array->ptr_val; PHP_ARRAY_ITER_TYPE it = arr_ptr->array.begin(); while(i--) it++; return it->first;}PHP_VAR_NODE *array_get_by_str_key(PHP_VALUE_NODE *array, std::string key){ if ( array->type != PHP_VAL_ARRAY ) { return 0; } PHP_ARRAY_TYPE *arr_ptr = (PHP_ARRAY_TYPE *)array->ptr_val; if ( arr_ptr->array.count(key) ) { return (arr_ptr->array)[key]; } else { PHP_VAR_NODE *add_node = make_var_node(); add_node->value.type = PHP_VAL_NONE; add_node->ref_count++; (arr_ptr->array)[key] = add_node; arr_ptr->sorted_keys.push_back(key); return add_node; } }PHP_VAR_NODE *array_get_by_int_key(PHP_VALUE_NODE *array, int key){ if ( array->type != PHP_VAL_ARRAY ) { return 0; } char s_key[32]; snprintf(s_key, sizeof(s_key), "%d", key); return array_get_by_str_key(array, s_key);}PHP_VAR_NODE *array_get_by_key(PHP_VALUE_NODE *array, PHP_VALUE_NODE *key){ if ( array->type != PHP_VAL_ARRAY ) { return 0; } PHP_VALUE_NODE s_key = *key; cast_value_str(&s_key); return array_get_by_str_key(array, s_key.str_val);}void array_set_by_key(PHP_VALUE_NODE *array, PHP_VALUE_NODE *key, PHP_VAR_NODE *node){ if ( array->type != PHP_VAL_ARRAY ) { return; } PHP_VALUE_NODE s_key = *key; cast_value_str(&s_key); array_remove_at_str_key(array, s_key.str_val); array_add_to_str_key(array, s_key.str_val, node); value_value_free(&s_key);}void array_add_to_str_key(PHP_VALUE_NODE *array, std::string key, PHP_VAR_NODE *node){ if ( array->type != PHP_VAL_ARRAY ) { return ; } PHP_ARRAY_TYPE *arr_ptr = (PHP_ARRAY_TYPE *)array->ptr_val; if ( !arr_ptr->array.count(key) ) { node->ref_count++; (arr_ptr->array)[key] = node; arr_ptr->sorted_keys.push_back(key); }}void array_remove_at_str_key(PHP_VALUE_NODE *array, std::string key){ if ( array->type != PHP_VAL_ARRAY ) { return ; } PHP_ARRAY_TYPE *arr_ptr = (PHP_ARRAY_TYPE *)array->ptr_val; if ( arr_ptr->array.count(key) ) { PHP_VAR_NODE *node = (arr_ptr->array)[key]; var_node_free(node); arr_ptr->array.erase(key); for(PHP_ARRAY_KEY_ITER_TYPE i = arr_ptr->sorted_keys.begin(); i != arr_ptr->sorted_keys.end(); i++) { if ( *i == key ) { arr_ptr->sorted_keys.erase(i); break; } } }}void array_add_to_int_key(PHP_VALUE_NODE *array, int key, PHP_VAR_NODE *node){ char s_key[32]; snprintf(s_key, sizeof(s_key), "%d", key); array_add_to_str_key(array, s_key, node);}int array_is_key_here(PHP_VALUE_NODE *array, PHP_VALUE_NODE *key){ if ( array->type != PHP_VAL_ARRAY ) { return 0; } PHP_ARRAY_TYPE *arr_ptr = (PHP_ARRAY_TYPE *)array->ptr_val; PHP_VALUE_NODE s_key = *key; cast_value_str(&s_key); std::string arr_key(s_key.str_val); return arr_ptr->array.count(arr_key);}int array_get_size(PHP_VALUE_NODE *array){ if ( array->type != PHP_VAL_ARRAY ) { return 0; } PHP_ARRAY_TYPE *arr_ptr = (PHP_ARRAY_TYPE *)array->ptr_val; return arr_ptr->array.size();}PHP_VAR_NODE *array_push_back(PHP_VALUE_NODE *array){ for(int i = 0; i < 0xffff;i++) { PHP_VAR_NODE *arr_var_node = array_get_by_int_key(array, i); if ( arr_var_node->value.type == PHP_VAL_NONE ) { return arr_var_node; } } // array size reached 64K ?! return 0;}/* value manipulation - assignment and disposal */void value_value_assign(PHP_VALUE_NODE *dst, PHP_VALUE_NODE *src){ // first, free old value value_value_free(dst); dst->type = src->type; switch(src->type) { // scalars are copied. Objects are copied too, since // interpreter doesn't allocate them. case PHP_VAL_NONE: case PHP_VAL_BOOL: case PHP_VAL_INT: case PHP_VAL_FLOAT: case PHP_VAL_OBJECT: // assign biggest in union dst->obj_val = src->obj_val; break; // string is duplicated case PHP_VAL_STRING: { dst->str_val = strdup(src->str_val); break; } // array must duplicate all it's values case PHP_VAL_ARRAY: { dst->ptr_val = new PHP_ARRAY_TYPE; PHP_ARRAY_TYPE *src_array = (PHP_ARRAY_TYPE *)src->ptr_val; for(PHP_ARRAY_KEY_ITER_TYPE i = src_array->sorted_keys.begin(); i != src_array->sorted_keys.end(); i++) { PHP_VAR_NODE *added = array_get_by_str_key(dst, *i); value_value_assign(&added->value, &src_array->array[*i]->value); } break; } case PHP_VAL_VAR_NODE: case PHP_VAL_INT_DATA: break; }}void var_node_free(PHP_VAR_NODE *var){ assert(var && var->ref_count); var->ref_count--; if ( var->ref_count == 0 ) { value_value_free(&var->value); delete var; }}void value_value_free(PHP_VALUE_NODE *val){ switch(val->type) { case PHP_VAL_NONE: case PHP_VAL_BOOL: case PHP_VAL_INT: case PHP_VAL_FLOAT: break; case PHP_VAL_STRING: { free(val->str_val); val->str_val = 0; break; } case PHP_VAL_ARRAY: { for(PHP_ARRAY_ITER_TYPE i = ((PHP_ARRAY_TYPE *)val->ptr_val)->array.begin(); i != ((PHP_ARRAY_TYPE *)val->ptr_val)->array.end(); i++) { PHP_VAR_NODE *var_i = i->second; var_node_free(var_i); } delete ((PHP_ARRAY_TYPE *)val->ptr_val); break; } case PHP_VAL_OBJECT: break; case PHP_VAL_VAR_NODE: case PHP_VAL_INT_DATA: break; } val->type = PHP_VAL_NONE;}/* casting functions */void cast_value_dnum(PHP_VALUE_NODE *val){ switch(val->type) { case PHP_VAL_NONE: val->int_val = 0; break; case PHP_VAL_BOOL: case PHP_VAL_INT: break; case PHP_VAL_FLOAT: val->int_val = (int)val->float_val; break; case PHP_VAL_STRING: { char *str = val->str_val; val->int_val = atoll(val->str_val); free(str); break; } case PHP_VAL_ARRAY: case PHP_VAL_OBJECT: val->int_val = 0; break; case PHP_VAL_VAR_NODE: case PHP_VAL_INT_DATA: assert(0); break; } val->type = PHP_VAL_INT;}void cast_value_bool(PHP_VALUE_NODE *val){ cast_value_dnum(val); val->type = PHP_VAL_BOOL;}void cast_value_fnum(PHP_VALUE_NODE *val){ switch(val->type) { case PHP_VAL_NONE: val->float_val = 0; break; case PHP_VAL_BOOL: case PHP_VAL_INT: val->float_val = val->int_val; break; case PHP_VAL_FLOAT: break; case PHP_VAL_STRING: { char *str = val->str_val; val->float_val = atof(val->str_val); free(str); break; } case PHP_VAL_ARRAY: case PHP_VAL_OBJECT: val->float_val = 0; break; case PHP_VAL_VAR_NODE: case PHP_VAL_INT_DATA: assert(0); break; } val->type = PHP_VAL_FLOAT;}void cast_value_str(PHP_VALUE_NODE *val){ char buff[256]; switch(val->type) { case PHP_VAL_NONE: buff[0] = 0; break; case PHP_VAL_BOOL: case PHP_VAL_INT: snprintf(buff, sizeof(buff), "%"PRIu64, val->int_val); break; case PHP_VAL_FLOAT: snprintf(buff, sizeof(buff), "%.02f", val->float_val); break; case PHP_VAL_STRING: return; case PHP_VAL_ARRAY: { delete ((PHP_ARRAY_TYPE *)val->ptr_val); strcpy(buff, "Array"); break; } case PHP_VAL_OBJECT: strcpy(buff, "Object"); break; case PHP_VAL_VAR_NODE: case PHP_VAL_INT_DATA: assert(0); break; } val->str_val = strdup(buff); val->type = PHP_VAL_STRING;}void cast_value_array(PHP_VALUE_NODE *val){ switch(val->type) { case PHP_VAL_NONE: case PHP_VAL_BOOL: case PHP_VAL_INT: case PHP_VAL_FLOAT: break; case PHP_VAL_STRING: free(val->str_val); case PHP_VAL_ARRAY: return; case PHP_VAL_OBJECT: ;/* must call to free_obj() */ case PHP_VAL_VAR_NODE: case PHP_VAL_INT_DATA: assert(0); break; } val->ptr_val = new PHP_ARRAY_TYPE; val->type = PHP_VAL_ARRAY;}/* * Function calls */PHP_EXP_NODE *make_func_call_exp(char *func_name, PHP_EXP_NODE *args){ PHP_EXP_NODE *call_node = make_zero_exp_node(); call_node->op = PHP_OP_FUNC_CALL; // copy function name call_node->tree_node.left = make_zero_exp_node(); call_node->tree_node.left->op = PHP_OP_VAL; call_node->tree_node.left->val_node.type = PHP_VAL_STRING; call_node->tree_node.left->val_node.str_val = strdup(func_name); // set params call_node->tree_node.right = args; return call_node;}PHP_EXP_NODE *make_func_call_param_list(){ PHP_VAR_NODE *params = make_array_var(); PHP_EXP_NODE *exp_node = make_zero_exp_node(); exp_node->op = PHP_OP_VAR; exp_node->var_node = params; return exp_node;}void func_call_add_expr(PHP_VAR_NODE *paramlist, PHP_EXP_NODE *arg, int byref){ PHP_VAR_NODE *node = array_push_back(¶mlist->value); node->value.type = PHP_VAL_INT_DATA; node->value.ptr_val = arg; if ( byref ) { node->flags |= PHP_VARFLAG_BYREF; }}void php_add_native_func(PHP_BLTIN_FUNC_DEF *def){ if ( get_scope_item_type(g_global_scope, def->name) != PHP_SCOPE_NONE ) { // // Error: something already defined by this name // php_report_error(PHP_ERROR, "Can't add scope item: symbol already defined"); return; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -