Clarify division behavior in tests
This commit is contained in:
parent
ce991fd12a
commit
7e21e71a07
2 changed files with 37 additions and 14 deletions
|
@ -10,12 +10,24 @@ describe("expr", () => {
|
||||||
["1 - 2", "-1"],
|
["1 - 2", "-1"],
|
||||||
["1 * 2", "2"],
|
["1 * 2", "2"],
|
||||||
["1 / 2", "0.5"],
|
["1 / 2", "0.5"],
|
||||||
["1 // 2", "0"],
|
// floored division
|
||||||
["1 % 2", "1"],
|
["1 // 5", "0"],
|
||||||
["3 % 2", "1"],
|
["6 // 5", "1"],
|
||||||
["-1 % 2", "1"],
|
["-1 // 5", "-1"],
|
||||||
// TODO: might change this! negative dividend is weird no matter what, but positive modulo is arguably the better call?
|
["-6 // 5", "-2"],
|
||||||
["1 % -2", "-1"],
|
["1 // -5", "-1"],
|
||||||
|
["6 // -5", "-2"],
|
||||||
|
["-1 // -5", "0"],
|
||||||
|
["-6 // -5", "1"],
|
||||||
|
// floored modulo
|
||||||
|
["1 % 5", "1"],
|
||||||
|
["6 % 5", "1"],
|
||||||
|
["-6 % 5", "4"],
|
||||||
|
["-1 % 5", "4"],
|
||||||
|
["1 % -5", "-4"],
|
||||||
|
["6 % -5", "-4"],
|
||||||
|
["-6 % -5", "-1"],
|
||||||
|
["-1 % -5", "-1"],
|
||||||
// TODO: operator precedence
|
// TODO: operator precedence
|
||||||
// TODO: parentheses
|
// TODO: parentheses
|
||||||
])("%s", (expression, result) => {
|
])("%s", (expression, result) => {
|
||||||
|
|
|
@ -12,8 +12,8 @@ export function Expr({}, argv: TextPiece[]): ProcResult {
|
||||||
const parser = new ExpressionParser(expression);
|
const parser = new ExpressionParser(expression);
|
||||||
const result = parser.parseSubExpression(0);
|
const result = parser.parseSubExpression(0);
|
||||||
|
|
||||||
if(parser.pos != expression.length) {
|
if (parser.pos != expression.length) {
|
||||||
return {error: "Couldn't parse full expression"}
|
return { error: "Couldn't parse full expression" };
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("value" in result) {
|
if ("value" in result) {
|
||||||
|
@ -59,13 +59,20 @@ function map(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeInfixOp(token:RegExp, leftBindingPower: number,rightBindingPower: number, op: (left: number, right: number) => Value | ErrorResult):TokenHandler {
|
function makeInfixOp(
|
||||||
|
token: RegExp,
|
||||||
|
leftBindingPower: number,
|
||||||
|
rightBindingPower: number,
|
||||||
|
op: (left: number, right: number) => Value | ErrorResult
|
||||||
|
): TokenHandler {
|
||||||
return {
|
return {
|
||||||
leftBindingPower,
|
leftBindingPower,
|
||||||
token,
|
token,
|
||||||
parse: ({ value: left }, matched, parser) =>
|
parse: ({ value: left }, matched, parser) =>
|
||||||
map(parser.parseSubExpression(rightBindingPower), (right) => op(left, right)),
|
map(parser.parseSubExpression(rightBindingPower), (right) =>
|
||||||
}
|
op(left, right)
|
||||||
|
),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const Operators: TokenHandler[] = [
|
const Operators: TokenHandler[] = [
|
||||||
|
@ -78,14 +85,18 @@ const Operators: TokenHandler[] = [
|
||||||
leftBindingPower: -1,
|
leftBindingPower: -1,
|
||||||
token: MINUS_TOKEN,
|
token: MINUS_TOKEN,
|
||||||
parse: (left, matched, parser) =>
|
parse: (left, matched, parser) =>
|
||||||
map(parser.parseSubExpression(99), (right) => ({value: -right})),
|
map(parser.parseSubExpression(99), (right) => ({ value: -right })),
|
||||||
},
|
},
|
||||||
makeInfixOp(PLUS_TOKEN, 10, 11, (left, right) => ({ value: left + right })),
|
makeInfixOp(PLUS_TOKEN, 10, 11, (left, right) => ({ value: left + right })),
|
||||||
makeInfixOp(MINUS_TOKEN, 10, 11, (left, right) => ({ value: left - right })),
|
makeInfixOp(MINUS_TOKEN, 10, 11, (left, right) => ({ value: left - right })),
|
||||||
makeInfixOp(TIMES_TOKEN, 20, 21, (left, right) => ({ value: left * right })),
|
makeInfixOp(TIMES_TOKEN, 20, 21, (left, right) => ({ value: left * right })),
|
||||||
makeInfixOp(FLOOR_TOKEN, 20, 21, (left, right) => ({ value: Math.floor(left / right) })),
|
makeInfixOp(FLOOR_TOKEN, 20, 21, (left, right) => ({
|
||||||
|
value: Math.floor(left / right),
|
||||||
|
})),
|
||||||
makeInfixOp(DIV_TOKEN, 20, 21, (left, right) => ({ value: left / right })),
|
makeInfixOp(DIV_TOKEN, 20, 21, (left, right) => ({ value: left / right })),
|
||||||
makeInfixOp(MOD_TOKEN, 20, 21, (left, right) => ({ value: ((left % right) + right) % right })),
|
makeInfixOp(MOD_TOKEN, 20, 21, (left, right) => ({
|
||||||
|
value: ((left % right) + right) % right,
|
||||||
|
})),
|
||||||
];
|
];
|
||||||
|
|
||||||
const ZERO = { value: 0 };
|
const ZERO = { value: 0 };
|
||||||
|
|
Loading…
Reference in a new issue