xxxxxxxxxx
167
function getTokens(code) {
code = code.replace(/[\s]/g, ' '); // replace all spaces characters to standard space
code = code.replace(/\[/g, ' [ '); // add space before
code = code.replace(/\]/g, ' ] '); // and after brackets
tokens = code.split(" ");
tokens = tokens.filter(e => e); // remove empty tokens
return tokens;
}
function execTokens(tokens, firstIndex, lastIndex) {
let index = firstIndex;
while (index < lastIndex) {
let token = tokens[index++];
//console.log(token);
if (commands[token]) {
index = commands[token](tokens, index);
}
}
}
function forward(tokens, index) {
turtle.move(tokens[index++]);
return index;
}
function backward(tokens, index) {
turtle.move(-tokens[index++]);
return index;
}
function right(tokens, index) {
turtle.turn(tokens[index++]);
return index;
}
function left(tokens, index) {
turtle.turn(-tokens[index++]);
return index;
}
function penup(tokens, index) {
turtle.pen = false;
return index;
}
function pendown(tokens, index) {
turtle.pen = true;
return index;
}
function repeat(tokens, index) {
let n = tokens[index++];
let bracket = 0;
let firstIndex = 0;
let lastIndex = 0;
while (index < tokens.length) {
let token = tokens[index++];
if (token == '[') {
if (bracket++ == 0) {
firstIndex = index;
}
}
else if (token == ']') {
if (--bracket == 0) {
lastIndex = index;
break;
}
}
}
if (firstIndex && lastIndex) {
for(let i = 0; i < n; i++) {
execTokens(tokens, firstIndex, lastIndex - 1);
}
return lastIndex;
}
return index;
}
function to(tokens, index) {
let name = tokens[index++];
let firstIndex = index;
console.log('to: ' + name);
while (index < tokens.length) {
let token = tokens[index++];
if (token == 'end') {
let lastIndex = index;
commands[name] = function(tokens, index) {
execTokens(tokens, firstIndex, lastIndex - 1);
return index;
}
break;
}
}
return index;
}
function setpencolor(tokens, index) {
if (tokens[index++] == '[') {
let r = tokens[index++];
let g = tokens[index++];
if (g == ']') {
stroke(parseInt(r)); // gray
} else {
let b = tokens[index++];
if (b == ']') {
stroke(parseInt(r), parseInt(g)); // gray + alpha
} else {
let a = tokens[index++];
if (a == ']') {
stroke(parseInt(r), parseInt(g), parseInt(b)); // rgb
}
else if (tokens[index++] == ']') {
stroke(parseInt(r), parseInt(g), parseInt(b), parseInt(a)); // rgba
}
}
}
}
return index;
}
const commands = {
"fd": forward,
"forward:": forward,
"bk": backward,
"backward": backward,
"rt": right,
"right": right,
"lt": left,
"left": left,
"pu": penup,
"penup": penup,
"pd": pendown,
"pendown": pendown,
"repeat": repeat,
"to": to,
"setpencolor": setpencolor,
"setpc": setpencolor
}
class Turtle {
constructor(x, y, angle) {
this.x = x;
this.y = y;
this.dir = angle;
}
reset() {
//console.log(this.x, this.y, this.dir);
translate(this.x, this.y);
rotate(this.dir);
stroke(255);
strokeWeight(2);
this.pen = true;
}
move(amt) {
amt = parseInt(amt);
if (this.pen) {
line(0, 0, amt, 0);
}
translate(amt, 0);
}
turn(angle) {
rotate(angle);
}
}