* Theoretically speaking this function must run on generated code. On the * practical side - I need it to debug syntax tree generation. Later, it can * be changes to generate code for some kind of bytecode for stack machine */
| 1808 | * be changes to generate code for some kind of bytecode for stack machine |
| 1809 | */ |
| 1810 | int php_execute(PHP_SYN_NODE *node, PHP_VALUE_NODE *result) |
| 1811 | { |
| 1812 | if ( !node ) { |
| 1813 | return 0; |
| 1814 | } |
| 1815 | while ( node ) { |
| 1816 | int curr_exec_result = 0; |
| 1817 | PHP_VALUE_NODE cond_result; |
| 1818 | cond_result.type = PHP_VAL_NONE; |
| 1819 | switch (node->type) { |
| 1820 | case PHP_ST_EXPR: |
| 1821 | php_expr_eval(node->node_expr, 0); |
| 1822 | break; |
| 1823 | case PHP_ST_IF: |
| 1824 | php_expr_eval(node->node_if.cond, &cond_result); |
| 1825 | cast_value_bool(&cond_result); |
| 1826 | if ( cond_result.int_val ) { |
| 1827 | if ( node->node_if.code_if ) { |
| 1828 | curr_exec_result = php_execute(node->node_if.code_if, result); |
| 1829 | } |
| 1830 | } else { |
| 1831 | if ( node->node_if.code_else ) { |
| 1832 | curr_exec_result = php_execute(node->node_if.code_else, result); |
| 1833 | } |
| 1834 | } |
| 1835 | break; |
| 1836 | case PHP_ST_RET: |
| 1837 | if ( node->node_expr ) { |
| 1838 | php_expr_eval(node->node_expr, result); |
| 1839 | } |
| 1840 | if ( node->next_node ) { |
| 1841 | // |
| 1842 | // Warning: code after "return" statement |
| 1843 | // |
| 1844 | php_report_error(PHP_WARNING, "code after 'return'"); |
| 1845 | } |
| 1846 | // "return" is ultimate "break" |
| 1847 | curr_exec_result = -0xffff; |
| 1848 | break; |
| 1849 | case PHP_ST_ECHO: { |
| 1850 | PHP_EXP_NODE *curr = node->node_expr; |
| 1851 | while (curr) { |
| 1852 | php_expr_eval(curr->exp_node, &cond_result); |
| 1853 | cast_value_str(&cond_result); |
| 1854 | CPhPLibContext::Print(cond_result.str_val); |
| 1855 | value_value_free(&cond_result); |
| 1856 | curr = curr->next; |
| 1857 | } |
| 1858 | } |
| 1859 | break; |
| 1860 | case PHP_ST_CONTINUE: |
| 1861 | case PHP_ST_BREAK: |
| 1862 | if ( node->node_expr ) { |
| 1863 | // 'break' or 'continue' used with an argument |
| 1864 | php_expr_eval(node->node_expr, &cond_result); |
| 1865 | } else { |
| 1866 | // without an argument break or continue just 1 loop |
| 1867 | cond_result.type = PHP_VAL_INT; |
no test coverage detected