@@ -11,7 +11,6 @@ const int BUSY_WAIT_FRAMECOUNTER = 2e7;
1111
1212const int WINDOW_HEIGHT = GRAPHICS_MAX_HEIGHT;
1313const int WINDOW_WIDTH = GRAPHICS_MAX_WIDTH;
14- const int INTERPRETER_HEIGHT = 16 *4 ;
1514
1615char message_buffer[320 ];
1716
@@ -52,6 +51,9 @@ class Display {
5251 double angle; // in radians
5352 bool pen_active; // true implies draw when pen moves
5453 bool turtle_visiblity;
54+
55+ // repeat command internals
56+ std::vector<std::pair<std::size_t , int > > repeat_stack; // (start, count)
5557public:
5658 Display (int height) : height(height),
5759 current (WINDOW_WIDTH / 2 , height / 2 ),
@@ -107,6 +109,35 @@ class Display {
107109 }
108110
109111 int command_handler (std::string &cmd, std::string &input, std::size_t &start) {
112+ if (cmd.empty ()) {
113+ // no more command left
114+ return 0 ;
115+ }
116+
117+ if (cmd == " repeat" ) {
118+ std::string arg0=parse_next_token (input, start);
119+ std::string arg1=parse_next_token (input, start);
120+ if (arg0.empty ()) return 2 ;
121+ if (arg1 != " [" ) return 3 ;
122+ int count = std::atoi (arg0.c_str ());
123+ if (count > 0 ) {
124+ repeat_stack.push_back (std::make_pair (start, count-1 ));
125+ }
126+ return 0 ;
127+ }
128+ if (cmd == " ]" ) {
129+ if (repeat_stack.empty ()) return 2 ;
130+ if (repeat_stack.back ().second == 0 ) {
131+ // repeat over
132+ repeat_stack.pop_back ();
133+ return 0 ;
134+ }
135+ repeat_stack.back ().second --;
136+ start = repeat_stack.back ().first ; // repeat again
137+ return 0 ;
138+ }
139+
140+
110141 if (cmd == " fd" || cmd == " forward" ) {
111142 std::string arg=parse_next_token (input, start);
112143 if (arg.empty ()) return 2 ;
@@ -163,7 +194,7 @@ class Display {
163194 if (cmd == " exit" ) {
164195 std::exit (0 );
165196 }
166- return 0 ;
197+ return 10 ;
167198 }
168199
169200 std::string parse_next_token (std::string &input, std::size_t &start) {
@@ -184,6 +215,7 @@ class Display {
184215
185216 int parse (std::string input) {
186217 std::size_t start = 0 ;
218+ repeat_stack.clear ();
187219 while (1 ) {
188220 std::string cmd = parse_next_token (input, start);
189221 if (cmd.empty ()) break ;
@@ -192,6 +224,9 @@ class Display {
192224 return err;
193225 }
194226 }
227+ if (!repeat_stack.empty ()) {
228+ return 1 ; // all repeat must be completed
229+ }
195230 return 0 ;
196231 }
197232
@@ -228,15 +263,20 @@ class Display {
228263};
229264
230265class Console {
231- const int line_count = 4 ;
232- std::vector<std::string> data;
266+ const int line_count = 3 ;
267+ const int LINE_STATUS = 0 ;
268+ std::string status_err;
269+ std::string status_loc;
270+ std::string input_line;
233271 int y_offset;
234272 int text_height;
273+ int text_width;
235274 const int border = 5 ;
236275
237276public:
238- Console (): data(line_count, " " ) {
277+ Console (): input_line( " " ) {
239278 text_height = std::graphics::textheight (" ." );
279+ text_width = std::graphics::textwidth (" ." );
240280 y_offset = WINDOW_HEIGHT-text_height*line_count-2 *border;
241281 }
242282
@@ -246,58 +286,75 @@ class Console {
246286
247287 std::string read () {
248288 int index = 0 ;
249- std::string &input = data[index];
250289 char ch;
251290 while (1 ) {
252291 ch = std::getch ();
253292 if (ch==' \n ' ) {
254- std::string out = input ; // copy
255- input .clear ();
293+ std::string out = input_line ; // copy
294+ input_line .clear ();
256295 draw ();
257296 return out;
258297 }
259- input +=ch;
298+ input_line +=ch;
260299 draw ();
261300 }
262301 }
263302
264303 void set_err (int err) {
265- int index = 1 ; // error line
266304 if (err==0 ) {
267- data[index] .clear ();
305+ status_err .clear ();
268306 } else {
269- data[index] = " error!" ;
307+ status_err = " error!" ;
270308 }
271309 draw ();
272310 }
273311
274- void update_log (Display &display) {
312+ void update_status (Display &display) {
275313 int current_x = display.get_x ();
276314 int current_y = display.get_y ();
277315 int angle_deg = std::round (display.get_angle ()*180 /M_PI);
278316
279- int index = 2 ; // current location
280- auto &log = data[index];
281- log = " loc: " ;
317+ status_loc = " loc: " ;
282318 char buffer[16 ];
283319 std::itoa (current_x, buffer, 10 );
284- log += buffer;
285- log += ' ,' ;
320+ status_loc += buffer;
321+ status_loc += ' ,' ;
286322 std::itoa (current_y, buffer, 10 );
287- log += buffer;
323+ status_loc += buffer;
288324
289325 std::itoa (angle_deg, buffer, 10 );
290- log += " dir: " ;
291- log += buffer;
292- log += " deg" ;
326+ status_loc += " dir: " ;
327+ status_loc += buffer;
328+ status_loc += " deg " ;
293329 }
294330
295331 void draw () {
296332 std::graphics::setcolor (YELLOW);
297333 std::graphics::bar (0 , y_offset, WINDOW_WIDTH-1 , WINDOW_HEIGHT-1 );
298334 std::graphics::setcolor (BLACK);
335+ {
336+ int line_number = 0 ; // loc, angle, err
337+ int _x = border;
338+ int _y = y_offset+line_number*text_height;
339+ _x += std::graphics::outtextxy (_x, _y, status_loc.c_str ());
340+ std::graphics::outtextxy (_x, _y, status_err.c_str ());
341+ }
342+ const int char_per_line = (WINDOW_WIDTH-2 *border)/text_width;
299343 for (std::size_t i = 0 ; i < line_count; i++) {
300- std::graphics::outtextxy (border, y_offset+i*text_height+border, data[i].c_str ());
344+ int _y = y_offset+(i+1 )*text_height;
345+ int _x = border;
346+ int str_start = char_per_line*i;
347+ int str_end = char_per_line*(i+1 ); // excluding
348+ if (str_start >= input_line.length ()) break ;
349+ char shelve_end = ' \0 ' ;
350+ if (str_end < input_line.length ()) {
351+ shelve_end = input_line[str_end];
352+ input_line[str_end] = ' \0 ' ;
353+ }
354+ std::graphics::outtextxy (_x, _y, input_line.c_str ()+str_start);
355+ if (shelve_end != ' \0 ' ) {
356+ input_line[str_end] = shelve_end; // rollback
357+ }
301358 }
302359 std::graphics::graphflush ();
303360 }
@@ -311,7 +368,7 @@ class Interpreter {
311368 }
312369 void execute () {
313370 while (1 ) {
314- console.update_log (display);
371+ console.update_status (display);
315372 display.draw ();
316373 console.draw ();
317374 std::string input = console.read ();
@@ -331,7 +388,7 @@ void start_logo() {
331388
332389void cleanup_graphics () {
333390 std::graphics::closegraph ();
334- std::cout << " graphics closed" << std::endl;
391+ std::cout << " logo graphics closed" << std::endl;
335392}
336393
337394int main (int argc,char *argv[]) {
0 commit comments