marijnh / Eloquent-JavaScript

The sources for the Eloquent JavaScript book
https://eloquentjavascript.net
3.02k stars 796 forks source link

Chapter 12 (Project: A Programming Language): Plus operator performs concatenation rather than addition #522

Closed Wryhder closed 4 years ago

Wryhder commented 4 years ago

This test code under The Environment subsection of chapter 12 returns 01 instead of 55.

run(`
do(define(total, 0),
   define(count, 1),
   while(<(count, 11),
         do(define(total, +(total, count)),
            define(count, +(count, 1)))),
   print(total))
`);
// → 55

Since concatenation isn't the behaviour required of the plus operator, could I create a PR with the following change:

for (let op of ["-", "*", "/", "==", "<", ">"]) {
    topScope[op] = Function("a, b", `return a ${op} b;`);
}

topScope["+"] = (a, b) => {
    return parseInt(a) + parseInt(b);
}

instead of what is currently in the book...

for (let op of ["+", "-", "*", "/", "==", "<", ">"]) {
    topScope[op] = Function("a, b", `return a ${op} b;`);
}

Or did I miss something, seeing as no issue was previously created for this?

marijnh commented 4 years ago

That code returns 55 for me. + will only concatenate when one side is a string, and I don't see any way in which a string could be introduced in this code, so I suspect you redefined some part of the system (possibly the parser) in a way that is causing this.

Wryhder commented 4 years ago

My bad. It was the parser. I'd missed something in the else if block that tests for numbers. I'd typed...

...
} else if (match = /^\d+\b/.exec(program)) {
    expr = { type: "value", value: match[0] };
  } ...

instead of...

...
} else if (match = /^\d+\b/.exec(program)) {
    expr = { type: "value", value: Number(match[0]) };
  } ...

Thanks for your help and apologies for any inconvenience. I'll close the issue now.