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); }
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; }