예제 #1
0
파일: statment.cpp 프로젝트: DTSCode/Cx
/** execute_statement   	Execute a Cx statement
 *
 * @param p_function_id : ptr to the routine symtab node
 */
void cx_executor::execute_statement(cx_symtab_node *p_function_id) {
    if (token != tc_left_bracket) {
        ++statement_count;
        trace_statement();
    }

    switch (token) {
        case tc_identifier:
        {
            if (p_node->defn.how == dc_function) {
                execute_function_call(p_node);
            } else {
                cx_symtab_node *p_var = p_node;
                get_token();
                if (token_in(token, tokenlist_assign_ops)) {
                    execute_assignment(p_var);
                } else {
                    execute_variable(p_var, false);
                    pop();
                }
            }
        }
            break;
        case tc_DO: execute_DO(p_function_id);
            break;
        case tc_WHILE: execute_WHILE(p_function_id);
            break;
        case tc_IF: execute_IF(p_function_id);
            break;
        case tc_FOR: execute_FOR(p_function_id);
            break;
        case tc_SWITCH: //parse_SWITCH();
            break;
        case tc_CASE:
        case tc_DEFAULT://parse_case_label();
            break;
        case tc_BREAK:
            get_token();
            break_loop = true;
            break;
        case tc_left_bracket: execute_compound(p_function_id);
            break;
        case tc_RETURN: execute_RETURN(p_function_id);
            break;
        default:
            break;
    }
}
예제 #2
0
파일: function.cpp 프로젝트: rackbone/Cx
/** execute_actual_parameters	Execute the actual parameters of
 *				a declared subroutine call.
 *
 * @param p_function_id : ptr to the subroutine name's symtab node
 */
void cx_executor::execute_actual_parameters (cx_symtab_node *p_function_id) {
    cx_symtab_node *p_formal_id; // ptr to formal parm's symtab node

    // Loop to execute each actual parameter.
    for (p_formal_id = p_function_id->defn.routine.locals.p_parms_ids;
            p_formal_id;
            p_formal_id = p_formal_id->next__) {

        cx_type *p_formal_type = p_formal_id->p_type;
        get_token();

        /* Reference parameter: execute_variable will leave the actual
         * parameter's address on top of the stack. */
        if (p_formal_id->defn.how == dc_reference) {

            const int size = p_node->p_type->size;
            p_formal_type->form = p_node->p_type->form;
            execute_variable(p_node, true);

            if (p_formal_type->form == fc_array) {

                p_formal_type->size = size;
                p_formal_type->array.element_count = size;
                p_formal_type->array.max_index = size;

                p_formal_id->runstack_item = top();

            } else {
                p_formal_id->runstack_item = top();
            }

            get_token();
        }// value parameter
        else {
            cx_type *p_actual_type = execute_expression();

            if ((p_formal_type == p_float_type) &&
                    (p_actual_type->base_type() == p_integer_type)) {

                // real formal := integer actual:
                // convert integer value to real.
                float ff = top()->basic_types.int__;
                pop();

                push(ff);
                p_formal_id->runstack_item = top();
            } else if (!p_formal_type->is_scalar_type()) {

                /* Formal parameter is an array or a record:
                 * Make a copy of the actual parameter's value. */

                const int size = p_actual_type->size;
                void *p_target_address = nullptr;
                const int num_of_elements = size / p_actual_type->base_type()->size;

                p_target_address = realloc(p_target_address, size);
                //memset(p_target_address, 0, size);

                if (p_target_address == nullptr) {
                    perror("realloc");
                    exit(0);
                }

                void *p_source = top()->basic_types.addr__;
                memcpy(p_target_address, p_source, size);

                pop();
                push(p_target_address);

                p_formal_type->array.element_count = num_of_elements;
                p_formal_type->array.max_index = num_of_elements;
                p_formal_type->size = size;
                p_formal_type->form = fc_array;
                p_formal_id->runstack_item = top();
            } else {

                // Range check an integer or enumeration
                // formal parameter.
                range_check(p_formal_type, top()->basic_types.int__);
                p_formal_id->runstack_item = top();
            }
        }
    }

    if (token == tc_left_paren) get_token();
}