JS is so meh to write in, why learn it here. Instead, learn DRUL, the assembler made for solving Rudy The Red Dot:

code = compile(".:dddddrruuuul@.");

var colors = [];

var acc = 0;

function run(instructions) {
var pc = 0;

while (pc < instructions.length) {
var line = instructions[pc];
var op = line[0];
var args = line[1];
switch (op) {
case "a": // set accumulator (set to remainingDots() if no arg)
a(args[0]);
break;
case "+": // add to accumulator (+1 if no arg)
add(args[0]);
break;
case "-": // subtract from accumulator (-1 if no arg)
sub(args[0]);
break;
case "u": // up n squares (1 if no arg)
u(args[0]);
break;
case "d": // down n squares (1 if no arg)
d(args[0]);
break;
case "l": // left n squares (1 if no arg)
l(args[0]);
break;
case "r": // right n squares (1 if no arg)
r(args[0]);
break;
case "g": // get current square color: color index n, unshift if -1, or push if no arg
g(args[0]);
break;
case "s": // set current square color: color index n, pop if -1, or shift if no arg
s(args[0]);
break;
case "=": // if current square color is literal (b / r / g / y / w) or color index n then jump to label
if (eq(args[0])) {
pc = args[1];
continue;
}
break;
case "!": // if current square color is not literal (b / r / g / y / w) or color index n then jump to label
if (!eq(args[0])) {
pc = args[1];
continue;
}
break;
case "@": // jump to label
pc = args[0];
continue;
case "0": // if accumulator is 0 then jump to label
if (acc == 0) {
pc = args[0]
continue;
}
break;
case "~": // if accumulator is not 0 then jump to label
if (acc != 0) {
pc = args[0]
continue;
}
break;
}
pc++;
}
}

run(code);

function compile(code) {
var instructions = [];
var waiting_for_op = true;
var max_args = 0;
var skip_if_non_number = false;
var op = "";
var label = "";
code += " ";

var i = 0;
var line = [];
var args = [];

while (i < code.length) {
var c = code[i];
if (!waiting_for_op && skip_if_non_number && c != "-" && isNaN(parseInt(c))) {
line.push(args);
instructions.push(line);
line = [];
waiting_for_op = true;
}
if (waiting_for_op) {
if (c == " ") {
i++
continue;
}
if (code[i+1] == ":") {
label = c;
i += 2;
op = code[i];
}
else {
label = "";
op = c;
}
waiting_for_op = false;
line = [label, op];
args = [];
skip_if_non_number = (op == "u" || op == "d" || op == "l" || op == "r");
if (op == "=" || op == "!")
max_args = 2;
else
max_args = 1;
}
else {
if (c == " ") {
line.push(args);
instructions.push(line);
line = [];
waiting_for_op = true;
}
else {
var negate = false;
if (c == "-") {
negate = true;
i += 1;
c = code[i];
}
var num = parseInt(c);
if (isNaN(num)) {
if (c == "b")
args.push("blue");
else if (c == "r")
args.push("red");
else if (c == "y")
args.push("yellow");
else if (c == "g")
args.push("green");
else if (c == "w")
args.push("white");
else
args.push(c);
}
else {
c = "";
while (!isNaN(num)) {
c += code[i];
i++;
num = parseInt(code[i]);
}
num = parseInt(c);
if (negate) num = -num;
i--;
args.push(num);
}
if (max_args > 0 && args.length >= max_args) {
line.push(args);
instructions.push(line);
line = [];
waiting_for_op = true;
}
}
}

i++;
}

for (i = 0; i < instructions.length; i++) {
line = instructions[i];
op = line[1];
if (op == "=" || op == "!")
instructions[i][2][1] = get_label(instructions, instructions[i][2][1]);
else if (op == "@" || op == "0" || op == "~")
instructions[i][2][0] = get_label(instructions, instructions[i][2][0]);

}

for (i = 0; i < instructions.length; i++)
instructions[i].shift();

return instructions;
}

function get_label(lines, label) {
for (var i = 0; i < lines.length; i++) {
if (lines[i][0] == label)
return i;
}
return -1;
}

function repeat(fn, n) {
if (n == undefined)
fn();
else
for (var i = 0; i < n; i++)
fn();
}

function eq(color) {
if (typeof(color) == "number")
color = colors[color];
if (color == "white")
color = false;
return color == getColor();
}

function g(c) {
color = getColor();
if (!color)
color = "white";

if (c == undefined)
colors.push(getColor());
else if (c == -1)
colors.unshift(getColor());
else
colors[c] = getColor();
}

function s(c) {
if (c == undefined)
color = colors.shift();
else if (c == -1)
color = colors.pop();
else
color = colors[c];

if (color == "white")
color = false;
setColor(color);
}

function u(n) {
repeat(up, n);
}

function d(n) {
repeat(down, n);
}

function r(n) {
repeat(right, n);
}

function l(n) {
repeat(left, n);
}

function a(n) {
if (n == undefined)
acc = remainingDots();
else
acc = n;
}

function add(n) {
if (n == undefined)
acc++;
else
acc += n;
}

function sub(n) {
if (n == undefined)
acc--;
else
acc -= n;
}

// level 1 d7r5u2r2
// level 2 d6r3u2r2d3
// level 3 d2 g d3r2 s r2u
// level 4 d4r1g ds r2urg ds r2
// level 5 .:r2 =bB =rR r B:d @. R:u @.
// level 6 r =bB u4 =b> lu >:ru B:d4 =b< rd <:ld
// level 7 .:=r> d @. >:r2 u9 @.
// level 8 d8 r2 u7 r2 d7 r2 u7 r2 d7 r1
// level 9 .:r100 d100 @.
// level 10 a8 .:d g - ~. dr a8 #:s ru - ~# u
// level 11 .:=gG=yY=bB=rR G:r=wG@. Y:d=wY@. B:u=wB@. R:l=wR@.