Exemplo n.º 1
0
void repl_evaluate_line(Stack* context, std::string const& input, std::ostream& output)
{
    Branch* branch = top_branch(context);
    int previousHead = branch->length();
    parser::compile(branch, parser::statement_list, input);
    int newHead = branch->length();

    bool anyErrors = false;

    int resultIndex = -1;

    for (int i=previousHead; i < newHead; i++) {
        Term* result = branch->get(i);

        if (has_static_error(result)) {
            output << "error: ";
            print_static_error(result, output);
            output << std::endl;
            anyErrors = true;
            break;
        }

        Frame* frame = top_frame(context);
        frame->pc = i;
        frame->endPc = i + 1;
        run_interpreter(context);

        if (error_occurred(context)) {
            output << "error: ";
            print_error_stack(context, std::cout);
            anyErrors = true;
            break;
        }

        resultIndex = i;
    }

    // Print results of the last expression
    if (!anyErrors && resultIndex != -1) {
        Term* result = branch->get(resultIndex);
        if (result->type != as_type(VOID_TYPE)) {
            output << find_stack_value_for_term(context, result, 0)->toString() << std::endl;
        }
    }

    clear_error(context);
}
Exemplo n.º 2
0
void for_loop_finish_iteration(Stack* stack, bool enableLoopOutput)
{
    INCREMENT_STAT(LoopFinishIteration);

    Frame* frame = top_frame(stack);
    Branch* contents = frame->branch;

    // Find list length
    caValue* listInput = get_frame_register(frame, 0);

    // Increment the loop index
    caValue* index = get_top_register(stack, for_loop_find_index(contents));
    set_int(index, as_int(index) + 1);

    // Preserve list output
    if (enableLoopOutput && frame->exitType != name_Discard) {
        caValue* outputIndex = get_frame_register(frame, for_loop_find_output_index(contents));

        Term* outputPlaceholder = get_output_placeholder(contents, 0);
        caValue* outputList = get_frame_register(frame, outputPlaceholder);
        caValue* outputValue = find_stack_value_for_term(stack, outputPlaceholder->input(0), 0);

        if (!is_list(outputList))
            set_list(outputList);
        list_touch(outputList);
        copy(outputValue, list_get(outputList, as_int(outputIndex)));

        INCREMENT_STAT(LoopWriteOutput);

        // Advance output index
        set_int(outputIndex, as_int(outputIndex) + 1);
    }

    // Check if we are finished
    if (as_int(index) >= list_length(listInput)
            || frame->exitType == name_Break
            || frame->exitType == name_Return) {

        // Possibly truncate output list, in case any elements were discarded.
        if (enableLoopOutput) {
            caValue* outputIndex = get_frame_register(frame, for_loop_find_output_index(contents));
            Term* outputPlaceholder = get_output_placeholder(contents, 0);
            caValue* outputList = get_frame_register(frame, outputPlaceholder);
            list_resize(outputList, as_int(outputIndex));
        } else {
            Term* outputPlaceholder = get_output_placeholder(contents, 0);
            caValue* outputList = get_frame_register(frame, outputPlaceholder);
            set_list(outputList, 0);
        }
        
        finish_frame(stack);
        return;
    }

    // If we're not finished yet, copy rebound outputs back to inputs.
    for (int i=1;; i++) {
        Term* input = get_input_placeholder(contents, i);
        if (input == NULL)
            break;
        Term* output = get_output_placeholder(contents, i);
        copy(get_frame_register(frame, output),
            get_frame_register(frame, input));

        INCREMENT_STAT(Copy_LoopCopyRebound);
    }

    // Return to start of loop body
    frame->pc = 0;
    frame->nextPc = 0;
    frame->exitType = name_None;
}