//: Helper for the repl. :(before "End Primitive Recipe Declarations") RUN_INTERACTIVE, :(before "End Primitive Recipe Numbers") Recipe_number["run-interactive"] = RUN_INTERACTIVE; //? cerr << "run-interactive: " << RUN_INTERACTIVE << '\n'; //? 1 :(before "End Primitive Recipe Implementations") case RUN_INTERACTIVE: { assert(scalar(ingredients.at(0))); //? cerr << "AAA 0\n"; //? 1 run_interactive(ingredients.at(0).at(0)); //? cerr << "ZZZ\n"; //? 1 continue; // not done with caller; don't increment current_step_index() } :(code) // manual tests: // empty string (excluding whitespace and comments) does nothing // ctrl-d // just an integer (excluding whitespace and comments) prints value of that location in memory // instruction executes // backspace at start begins new attempt void run_interactive(long long int address) { //? tb_shutdown(); //? 1 long long int size = Memory[address]; if (size == 0) { ++current_step_index(); return; } ostringstream tmp; for (long long int curr = address+1; curr < address+size; ++curr) { // todo: unicode tmp << (char)(int)Memory[curr]; } //? cerr << size << ' ' << Memory[address+size] << '\n'; //? 1 assert(Memory[address+size] == 10); // skip the newline if (Recipe_number.find("interactive") == Recipe_number.end()) Recipe_number["interactive"] = Next_recipe_number++; string command = trim(strip_comments(tmp.str())); if (command.empty()) { ++current_step_index(); return; } if (is_integer(command)) { print_value_of_location_as_response(to_integer(command)); ++current_step_index(); return; } //? exit(0); //? 1 if (Name[Recipe_number["interactive"]].find(command) != Name[Recipe_number["interactive"]].end()) { print_value_of_location_as_response(Name[Recipe_number["interactive"]][command]); ++current_step_index(); return; } //? tb_shutdown(); //? 1 //? cerr << command; //? 1 //? exit(0); //? 1 //? cerr << "AAA 1\n"; //? 1 Recipe.erase(Recipe_number["interactive"]); // call run(string) but without the scheduling //? cerr << ("recipe interactive [\n"+command+"\n]\n"); //? 1 load("recipe interactive [\n"+command+"\n]\n"); transform_all(); //? cerr << "names: " << Name[Recipe_number["interactive"]].size() << "; "; //? 1 //? cerr << "steps: " << Recipe[Recipe_number["interactive"]].steps.size() << "; "; //? 1 //? cerr << "interactive transformed_until: " << Recipe[Recipe_number["interactive"]].transformed_until << '\n'; //? 1 Current_routine->calls.push_front(call(Recipe_number["interactive"])); } string strip_comments(string in) { ostringstream result; //? cerr << in; //? 1 for (long long int i = 0; i < SIZE(in); ++i) { if (in.at(i) != '#') { result << in.at(i); } else { while (i < SIZE(in) && in.at(i) != '\n') ++i; if (i < SIZE(in) && in.at(i) == '\n') ++i; } } //? cerr << "ZZZ"; //? 1 return result.str(); } void print_value_of_location_as_response(long long int address) { // convert to string ostringstream out; out << "=> " << Memory[address]; string result = out.str(); // handle regular I/O if (!tb_is_active()) { cerr << result << '\n'; return; } // raw I/O; use termbox to print long long int bound = SIZE(result); if (bound > tb_width()) bound = tb_width(); for (long long int i = 0; i < bound; ++i) { tb_change_cell(i, Display_row, result.at(i), /*computer's color*/245, TB_BLACK); } // newline if (Display_row < tb_height()-1) ++Display_row; Display_column = 0; tb_set_cursor(Display_column, Display_row); tb_present(); } //:: debugging tool :(before "End Primitive Recipe Declarations") _RUN_DEPTH, :(before "End Primitive Recipe Numbers") Recipe_number["$run-depth"] = _RUN_DEPTH; :(before "End Primitive Recipe Implementations") case _RUN_DEPTH: { cerr << Current_routine->calls.size(); break; }