Introduction to Logo Turtle
LogoTurtle is currently the FIRST and only one Chrome Extension for Turtle Graphics. I have also written a PHP version of Logo Interpreter in 2006 but that runs only on the server.
Previous Contributions
- v0.0.6: Turtle Programming v0.0.6: Adding Circle, MoveTo, Turn and Screen!
- v0.0.5: Turtle Programming v0.0.5: Adding IF/ELSE and STOP!
- v0.0.4: LogoTurtle: Make Variables and Comments
- v0.0.3: Turtle Graphics Programming Update: Adding text, jump, dot, fontsize, download as png
- v0.0.2: LogoTurtle v0.0.2: ShowTurtle, HideTurtle, Color, Width and Help.
- v0.0.1: Teach Your Kids Programming – The First Logo Interpreter (Turtle Graphics) in Chrome Extension!
Turtle Graphics v0.0.7 New Features
Along with bug fixes and code tweaks, This Commit has added the support of function declaration and function invoke with parameters. This is the most useful, important and most difficult feature of the LOGO parser!
Logo Programming Screenshots
The following LOGO source code has a two recursive functional call. I have spent quite some time and came across the same problem that I had years ago when writing the PHP Logo Parser. The fix is to copy the variables before recursive calls and restore them once the function calls return so the variables value update do not affect globally.
ht cs to tree :size if (:size<10) [stop] fd :size lt 30 tree :size*0.7 ; left branch, recursive rt 60 tree :size*0.7 ; right branch, recursive lt 30 bk :size end pu fd -120 pd tree 100
Version 0.0.7 supports single-line comments that are denoted using ; or # or //
How to Parse To/End LOGO function in Javascript?
The following Javascript parses the TO/END LOGO function pairs and stores it in class attribute this.funs dictionary. The content of the dictionary value is an array of [function parameters, function body].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | case "to": // define a function let next_word; let funs_name = y.word.trim(); if (!isValidVarName(funs_name)) { this.pushErr(word, LOGO_ERR_INVALID_FUN_NAME, funs_name); return false; } i = y.next; let start_fun_idx = i; let end_fun_idx = -1; for (;;) { let prev = i; next_word = getNextWord(s, i, U); i = next_word.next; if (next_word.word.toLowerCase() == 'end') { end_fun_idx = prev; break; } if ((next_word.word == '' || next_word.next >= U)) { this.pushErr(word, LOGO_ERR_MISSING_END, next_word); return false; } } if (end_fun_idx == -1) { this.pushErr(word, LOGO_ERR_MISSING_END, ''); return false; } let funs_s = s.substring(start_fun_idx, end_fun_idx).trim(); if (funs_s && y) { let ii = 0; let UU = s.length; let funs_params = []; // funs parameter let j = ii; while (ii < U) { j = ii; let to_word = getNextWord(funs_s, ii, UU); ii = to_word.next; if (to_word.word.startsWith(':')) { let to_word_param = to_word.word.substring(1); if (!isValidVarName(to_word_param)) { this.pushErr(word, LOGO_ERR_INVALID_VAR_NAME, to_word_param); return false; } funs_params.push(to_word_param); } else { break; } } let funs_body = funs_s.substring(j, UU).trim(); // declare the function this.funs[funs_name] = [funs_params, funs_body]; } break; |
case "to": // define a function let next_word; let funs_name = y.word.trim(); if (!isValidVarName(funs_name)) { this.pushErr(word, LOGO_ERR_INVALID_FUN_NAME, funs_name); return false; } i = y.next; let start_fun_idx = i; let end_fun_idx = -1; for (;;) { let prev = i; next_word = getNextWord(s, i, U); i = next_word.next; if (next_word.word.toLowerCase() == 'end') { end_fun_idx = prev; break; } if ((next_word.word == '' || next_word.next >= U)) { this.pushErr(word, LOGO_ERR_MISSING_END, next_word); return false; } } if (end_fun_idx == -1) { this.pushErr(word, LOGO_ERR_MISSING_END, ''); return false; } let funs_s = s.substring(start_fun_idx, end_fun_idx).trim(); if (funs_s && y) { let ii = 0; let UU = s.length; let funs_params = []; // funs parameter let j = ii; while (ii < U) { j = ii; let to_word = getNextWord(funs_s, ii, UU); ii = to_word.next; if (to_word.word.startsWith(':')) { let to_word_param = to_word.word.substring(1); if (!isValidVarName(to_word_param)) { this.pushErr(word, LOGO_ERR_INVALID_VAR_NAME, to_word_param); return false; } funs_params.push(to_word_param); } else { break; } } let funs_body = funs_s.substring(j, UU).trim(); // declare the function this.funs[funs_name] = [funs_params, funs_body]; } break;
Roadmap of Chrome Extension: Logo Turtle
- Add Functions
- Add IF/THEN/ELSE
- Add Variables
- Add Colors
- Add MoveTo
- Add PrintText
- Add Circle
- Add Arc
- Add Eraser
- Add Fill
- Save As Picture
- Save As Program
- Comments
- Add Recursion Support
- Add Global/Local Scopes
- etc. etc.
Technology Stack
If an App can be written in Javascript, eventually it will be written in Javascript.
Chrome Webstore
Install the Turtle Programming for Kids Now!
Contribution Welcome
Github: https://github.com/DoctorLai/LogoTurtle
- Fork it!
- Create your feature branch: git checkout -b my-new-feature
- Commit your changes: git commit -am ‘Add some feature’
- Push to the branch: git push origin my-new-feature
- Submit a pull request.
–EOF (The Ultimate Computing & Technology Blog) —
loading...
Last Post: The SteemIt Discord Bot Upgrade and API
Next Post: Turtle Programming v0.0.8: /* */ comments, dotxy, and javascript!