From 26bf8684ad35bee79945516603553be041bad33d Mon Sep 17 00:00:00 2001 From: Dmytro Brahinets Date: Wed, 4 Dec 2024 00:29:33 +0200 Subject: [PATCH 1/5] fix(Expressions): OperationExpression interpret method I kept only one return from this function. Solution with conditional check if the operator's length is 1 disable the ability to provide addition, subtraction, multiplication and division with multiple arguments (more than two). --- lib/expressions.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/expressions.js b/lib/expressions.js index 24243a4..be85ff6 100644 --- a/lib/expressions.js +++ b/lib/expressions.js @@ -36,8 +36,7 @@ class OperationExpression { const args = this.operands.map((x) => toValues(x)); const operator = OPERATORS[this.operator]; if (!operator) throw new Error(`Unknown operator: ${operator}`); - if (this.operator.length > 1) return operator(...args); - return args.reduce(operator); + return operator(...args); } } From 9a74a1295962ceb3a870bf160809c515aad52c78 Mon Sep 17 00:00:00 2001 From: Dmytro Brahinets Date: Wed, 4 Dec 2024 00:36:54 +0200 Subject: [PATCH 2/5] feat(Arithmetic): add arithmetic operators --- lib/operators.js | 6 +- lib/operators/arithmetic.js | 72 ++++++++++ test/arithmetic.js | 280 ++++++++++++++++++++++++++++++++++++ 3 files changed, 354 insertions(+), 4 deletions(-) create mode 100644 lib/operators/arithmetic.js create mode 100644 test/arithmetic.js diff --git a/lib/operators.js b/lib/operators.js index 1cdca12..8878a03 100644 --- a/lib/operators.js +++ b/lib/operators.js @@ -1,14 +1,12 @@ 'use strict'; const { listp, head, tail } = require('./utils.js'); +const arithmetic = require('./operators/arithmetic.js'); module.exports = { - '+': (a, b) => a + b, - '-': (a, b) => a - b, - '*': (a, b) => a * b, - '/': (a, b) => a / b, eq: (a, b) => a === b, list: (...list) => (listp(list) ? list : null), car: (list) => (listp(list) ? head(list) : null), cdr: (list) => (listp(list) ? tail(list) : null), + ...arithmetic, }; diff --git a/lib/operators/arithmetic.js b/lib/operators/arithmetic.js new file mode 100644 index 0000000..c5b0866 --- /dev/null +++ b/lib/operators/arithmetic.js @@ -0,0 +1,72 @@ +'use strict'; + +const gcdPair = (a, b) => { + const r = a % b; + if (r === 0) return b; + return gcdPair(b, r); +}; + +const gcd = (...list) => { + if (list.length === 0) return 0; + if (list.length === 1) return Math.abs(list[0]); + return list.reduce(gcdPair); +}; + +//TODO replace Math.abs with a custom "Lisp" implementation +const lcmPair = (a, b) => Math.abs(a * b) / gcdPair(a, b); + +const lcm = (...list) => { + if (list.length === 0) return 1; + if (list.length === 1) return Math.abs(list[0]); + return list.reduce(lcmPair); +}; + +const additionPair = (a, b, ...list) => { + return a + b; +}; + +const addition = (...list) => { + if (list.length === 0) return 0; + return list.reduce(additionPair); +}; + +const subtractionPair = (a, b) => a - b; + +const subtraction = (...list) => { + if (list.length === 0) return 0; + if (list.length === 1) return -list[0]; + return list.reduce(subtractionPair); +}; + +const multiplicationPair = (a, b) => a * b; + +const multiplication = (...list) => { + if (list.length === 0) return 1; + return list.reduce(multiplicationPair); +}; + +const division = (...list) => { + if (list.length === 0) throw new Error('Division by zero'); + const isZero = (element) => element === 0; + const hasZero = list.some(isZero); + if (hasZero) throw new Error('Division by zero'); + if (list.length === 1) return list[0]; + if (list.length === 2) return list[0] / list[1]; + const [first, ...rest] = list; + return first / multiplication(...rest); +}; + +module.exports = { + '+': addition, + '-': subtraction, + '*': multiplication, + '/': division, + mod: (a, b) => ((a % b) + b) % b, + rem: (a, b) => a % b, + incf: (a, b = 1) => a + b, + decf: (a, b = 1) => a - b, + '1+': (a) => a + 1, + '1-': (a) => a - 1, + gcd, + lcm, +}; diff --git a/test/arithmetic.js b/test/arithmetic.js new file mode 100644 index 0000000..4e88dec --- /dev/null +++ b/test/arithmetic.js @@ -0,0 +1,280 @@ +'use strict'; +const assert = require('node:assert'); +const { describe, it } = require('node:test'); +const { evaluate } = require('..'); + +describe('Arithmetic operators', () => { + it.only('Evaluate addition', () => { + const program = '(+ x y)'; + const context = { x: 1, y: 2 }; + const result = evaluate(program, context); + const expected = 1 + 2; + assert.strictEqual(result, expected, 'Addition operator failed'); + }); +}); +// describe('Arithmetic operators', () => { +// describe('Addition', () => { +// it.only('Evaluate addition', () => { +// const program = '(+ x y)'; +// const context = { x: 1, y: 2 }; +// const result = evaluate(program, context); +// const expected = 1 + 2; +// assert.strictEqual(result, expected, 'Addition operator failed'); +// }); + +// it('Evaluate addition on more than two arguments', () => { +// const program = '(+ x y z)'; +// const context = { x: 1, y: 2, z: 3 }; +// const result = evaluate(program, context); +// const expected = 1 + 2 + 3; +// assert.strictEqual(result, expected, 'Addition operator failed'); +// }); +// }); + +// describe('Subtraction', () => { +// it('Evaluate subtraction', () => { +// const program = '(- x y)'; +// const context = { x: 1, y: 2 }; +// const result = evaluate(program, context); +// const expected = 1 - 2; +// assert.strictEqual(result, expected, 'Subtraction operator failed'); +// }); + +// it('Evaluate subtraction on more than two arguments', () => { +// const program = '(- x y z)'; +// const context = { x: 1, y: 2, z: 3 }; +// const result = evaluate(program, context); +// const expected = 1 - 2 - 3; +// assert.strictEqual(result, expected, 'Subtraction operator failed'); +// }); +// }); + +// describe('Multiplication', () => { +// it('Evaluate multiplication', () => { +// const program = '(* x y)'; +// const context = { x: 1, y: 2 }; +// const result = evaluate(program, context); +// const expected = 1 * 2; +// assert.strictEqual(result, expected, 'Multiplication operator failed'); +// }); + +// it('Evaluate multiplication with no arguments', () => { +// const program = '(* )'; +// const result = evaluate(program); +// const expected = 1; +// assert.strictEqual(result, expected, 'Multiplication operator failed'); +// }); + +// it('Evaluate multiplication on more than two arguments', () => { +// const program = '(* x y z)'; +// const context = { x: 1, y: 2, z: 3 }; +// const result = evaluate(program, context); +// const expected = 1 * 2 * 3; +// assert.strictEqual(result, expected, 'Multiplication operator failed'); +// }); +// }); + +// describe('Division', () => { +// it('Evaluate division', () => { +// const program = '(/ x y)'; +// const context = { x: 1, y: 2 }; +// const result = evaluate(program, context); +// const expected = 1 / 2; +// assert.strictEqual(result, expected, 'Division operator failed'); +// }); + +// it('Evaluate division on more than two arguments', () => { +// const program = '(/ x y z)'; +// const context = { x: 3, y: 4, z: 5 }; +// const result = evaluate(program, context); +// const expected = 3 / (4 * 5); +// assert.strictEqual(result, expected, 'Division operator failed'); +// }); +// }); + +// it('Evaluate modulus', () => { +// const program = '(mod x y)'; +// const context = { x: 20, y: 10 }; +// const result = evaluate(program, context); +// const expected = 20 % 10; +// assert.strictEqual(result, expected, 'Modulus operator failed'); +// }); + +// it('Evaluate modulus with negative numbers', () => { +// const program = '(mod x y)'; +// const context = { x: -1, y: 5 }; +// const result = evaluate(program, context); +// const expected = ((-1 % 5) + 5) % 5; +// assert.strictEqual( +// result, +// expected, +// 'Modulus operator with negative numbers failed', +// ); +// }); + +// it('Evaluate remainder', () => { +// const program = '(rem x y)'; +// const context = { x: -1, y: 5 }; +// const result = evaluate(program, context); +// const expected = -1 % 5; +// assert.strictEqual(result, expected, 'Reminder operator failed'); +// }); + +// it('Evaluate increment', () => { +// const program = '(incf x)'; +// const context = { x: 1 }; +// const result = evaluate(program, context); +// const expected = 1 + 1; +// assert.strictEqual(result, expected, 'Increment operator failed'); +// }); + +// it('Evaluate increment with second argument', () => { +// const program = '(incf x y)'; +// const context = { x: 1, y: 2 }; +// const result = evaluate(program, context); +// const expected = 1 + 2; +// assert.strictEqual( +// result, +// expected, +// 'Increment operator with second argument failed', +// ); +// }); + +// it('Evaluate decrement', () => { +// const program = '(decf x)'; +// const context = { x: 1 }; +// const result = evaluate(program, context); +// const expected = 1 - 1; +// assert.strictEqual(result, expected, 'Decrement operator failed'); +// }); + +// it('Evaluate decrement with second argument', () => { +// const program = '(decf x y)'; +// const context = { x: 1, y: 2 }; +// const result = evaluate(program, context); +// const expected = 1 - 2; +// assert.strictEqual( +// result, +// expected, +// 'Decrement operator with second argument failed', +// ); +// }); + +// it('Evaluate increment shortcut', () => { +// const program = '(1+ x)'; +// const context = { x: 1 }; +// const result = evaluate(program, context); +// const expected = 1 + 1; +// assert.strictEqual(result, expected, 'Increment shortcut operator fail'); +// }); + +// it('Evaluate decrement shortcut', () => { +// const program = '(1- x)'; +// const context = { x: 1 }; +// const result = evaluate(program, context); +// const expected = 1 - 1; +// assert.strictEqual(result, expected, 'Decrement shortcut operator fail'); +// }); + +// it('Evaluate complex arithmetic expression', () => { +// const program = '(+ (mod x y) (incf y))'; +// const context = { x: -1, y: 5 }; +// const result = evaluate(program, context); +// const expected = (((-1 % 5) + 5) % 5) + 6; +// assert.strictEqual( +// result, +// expected, +// 'Complex arithmetic expression failed', +// ); +// }); + +// describe('Greatest common divisor', () => { +// it('Evaluate gcd on two arguments', () => { +// const program = '(gcd x y)'; +// const context = { x: 20, y: 10 }; +// const result = evaluate(program, context); +// const expected = 10; +// assert.strictEqual(result, expected, 'GCD operator failed'); +// }); + +// it('Evaluate gcd on multiple arguments', () => { +// const program = '(gcd x y z)'; +// const context = { x: 20, y: 10, z: 5 }; +// const result = evaluate(program, context); +// const expected = 5; +// assert.strictEqual(result, expected, 'GCD operator failed'); +// }); + +// it('Evaluate gcd on some negative arguments', () => { +// const program = '(gcd x y)'; +// const context = { x: -20, y: 10 }; +// const result = evaluate(program, context); +// const expected = 10; +// assert.strictEqual(result, expected, 'GCD operator failed'); +// }); + +// it('Evaluate gcd on single negative argument', () => { +// const program = '(gcd x)'; +// const context = { x: -20 }; +// const result = evaluate(program, context); +// const expected = 20; +// assert.strictEqual(result, expected, 'GCD operator failed'); +// }); + +// it('Evaluate gcd on no arguments', () => { +// const program = '(gcd)'; +// const result = evaluate(program); +// const expected = 0; +// assert.strictEqual(result, expected, 'GCD operator failed'); +// }); + +// it('Evaluate gcd on single argument', () => { +// const program = '(gcd x)'; +// const context = { x: 20 }; +// const result = evaluate(program, context); +// const expected = 20; +// assert.strictEqual(result, expected, 'GCD operator failed'); +// }); +// }); + +// describe('Least common multiple', () => { +// it('Evaluate lcm on two arguments', () => { +// const program = '(lcm x y)'; +// const context = { x: 20, y: 10 }; +// const result = evaluate(program, context); +// const expected = 20; +// assert.strictEqual(result, expected, 'LCM operator failed'); +// }); + +// it('Evaluate lcm on multiple arguments', () => { +// const program = '(lcm x y z)'; +// const context = { x: 1, y: 2, z: 3 }; +// const result = evaluate(program, context); +// const expected = 6; +// assert.strictEqual(result, expected, 'LCM operator failed'); +// }); + +// it('Evaluate lcm on some negative arguments', () => { +// const program = '(lcm x y)'; +// const context = { x: -20, y: 10 }; +// const result = evaluate(program, context); +// const expected = 20; +// assert.strictEqual(result, expected, 'LCM operator failed'); +// }); + +// it('Evaluate lcm on single negative argument', () => { +// const program = '(lcm x)'; +// const context = { x: -20 }; +// const result = evaluate(program, context); +// const expected = 20; +// assert.strictEqual(result, expected, 'LCM operator failed'); +// }); + +// it('Evaluate lcm on no arguments', () => { +// const program = '(lcm)'; +// const result = evaluate(program); +// const expected = 1; +// assert.strictEqual(result, expected, 'LCM operator failed'); +// }); +// }); +// }); From 3cd40f676976df442d130aa3cbd76596ee141faf Mon Sep 17 00:00:00 2001 From: Dmytro Brahinets Date: Thu, 5 Dec 2024 20:42:39 +0200 Subject: [PATCH 3/5] fix: linter errors --- lib/operators/arithmetic.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/operators/arithmetic.js b/lib/operators/arithmetic.js index c5b0866..18eaf43 100644 --- a/lib/operators/arithmetic.js +++ b/lib/operators/arithmetic.js @@ -21,9 +21,7 @@ const lcm = (...list) => { return list.reduce(lcmPair); }; -const additionPair = (a, b, ...list) => { - return a + b; -}; +const additionPair = (a, b) => a + b; const addition = (...list) => { if (list.length === 0) return 0; From 48f1a673690fba3bd2879e08b86b3854c49fd742 Mon Sep 17 00:00:00 2001 From: Dmytro Brahinets Date: Mon, 9 Dec 2024 20:07:50 +0200 Subject: [PATCH 4/5] Make code more readable and uncomment tests Refs: https://github.com/metarhia/metalisp/issues/5 --- lib/operators/arithmetic.js | 23 +- test/arithmetic.js | 481 ++++++++++++++++++------------------ 2 files changed, 243 insertions(+), 261 deletions(-) diff --git a/lib/operators/arithmetic.js b/lib/operators/arithmetic.js index 18eaf43..ea496d2 100644 --- a/lib/operators/arithmetic.js +++ b/lib/operators/arithmetic.js @@ -1,46 +1,37 @@ 'use strict'; -const gcdPair = (a, b) => { +const euclideanAlgorythm = (a, b) => { const r = a % b; if (r === 0) return b; - return gcdPair(b, r); + return euclideanAlgorythm(b, r); }; const gcd = (...list) => { if (list.length === 0) return 0; if (list.length === 1) return Math.abs(list[0]); - return list.reduce(gcdPair); + return list.reduce(euclideanAlgorythm); }; -//TODO replace Math.abs with a custom "Lisp" implementation -const lcmPair = (a, b) => Math.abs(a * b) / gcdPair(a, b); - const lcm = (...list) => { if (list.length === 0) return 1; if (list.length === 1) return Math.abs(list[0]); - return list.reduce(lcmPair); + return list.reduce((a, b) => Math.abs(a * b) / euclideanAlgorythm(a, b)); }; -const additionPair = (a, b) => a + b; - const addition = (...list) => { if (list.length === 0) return 0; - return list.reduce(additionPair); + return list.reduce((a, b) => a + b); }; -const subtractionPair = (a, b) => a - b; - const subtraction = (...list) => { if (list.length === 0) return 0; if (list.length === 1) return -list[0]; - return list.reduce(subtractionPair); + return list.reduce((a, b) => a - b); }; -const multiplicationPair = (a, b) => a * b; - const multiplication = (...list) => { if (list.length === 0) return 1; - return list.reduce(multiplicationPair); + return list.reduce((a, b) => a * b); }; const division = (...list) => { diff --git a/test/arithmetic.js b/test/arithmetic.js index 4e88dec..4c8f8de 100644 --- a/test/arithmetic.js +++ b/test/arithmetic.js @@ -4,277 +4,268 @@ const { describe, it } = require('node:test'); const { evaluate } = require('..'); describe('Arithmetic operators', () => { - it.only('Evaluate addition', () => { - const program = '(+ x y)'; - const context = { x: 1, y: 2 }; - const result = evaluate(program, context); - const expected = 1 + 2; - assert.strictEqual(result, expected, 'Addition operator failed'); - }); -}); -// describe('Arithmetic operators', () => { -// describe('Addition', () => { -// it.only('Evaluate addition', () => { -// const program = '(+ x y)'; -// const context = { x: 1, y: 2 }; -// const result = evaluate(program, context); -// const expected = 1 + 2; -// assert.strictEqual(result, expected, 'Addition operator failed'); -// }); + describe('Addition', () => { + it.only('Evaluate addition', () => { + const program = '(+ x y)'; + const context = { x: 1, y: 2 }; + const result = evaluate(program, context); + const expected = 1 + 2; + assert.strictEqual(result, expected, 'Addition operator failed'); + }); -// it('Evaluate addition on more than two arguments', () => { -// const program = '(+ x y z)'; -// const context = { x: 1, y: 2, z: 3 }; -// const result = evaluate(program, context); -// const expected = 1 + 2 + 3; -// assert.strictEqual(result, expected, 'Addition operator failed'); -// }); -// }); + it('Evaluate addition on more than two arguments', () => { + const program = '(+ x y z)'; + const context = { x: 1, y: 2, z: 3 }; + const result = evaluate(program, context); + const expected = 1 + 2 + 3; + assert.strictEqual(result, expected, 'Addition operator failed'); + }); + }); -// describe('Subtraction', () => { -// it('Evaluate subtraction', () => { -// const program = '(- x y)'; -// const context = { x: 1, y: 2 }; -// const result = evaluate(program, context); -// const expected = 1 - 2; -// assert.strictEqual(result, expected, 'Subtraction operator failed'); -// }); + describe('Subtraction', () => { + it('Evaluate subtraction', () => { + const program = '(- x y)'; + const context = { x: 1, y: 2 }; + const result = evaluate(program, context); + const expected = 1 - 2; + assert.strictEqual(result, expected, 'Subtraction operator failed'); + }); -// it('Evaluate subtraction on more than two arguments', () => { -// const program = '(- x y z)'; -// const context = { x: 1, y: 2, z: 3 }; -// const result = evaluate(program, context); -// const expected = 1 - 2 - 3; -// assert.strictEqual(result, expected, 'Subtraction operator failed'); -// }); -// }); + it('Evaluate subtraction on more than two arguments', () => { + const program = '(- x y z)'; + const context = { x: 1, y: 2, z: 3 }; + const result = evaluate(program, context); + const expected = 1 - 2 - 3; + assert.strictEqual(result, expected, 'Subtraction operator failed'); + }); + }); -// describe('Multiplication', () => { -// it('Evaluate multiplication', () => { -// const program = '(* x y)'; -// const context = { x: 1, y: 2 }; -// const result = evaluate(program, context); -// const expected = 1 * 2; -// assert.strictEqual(result, expected, 'Multiplication operator failed'); -// }); + describe('Multiplication', () => { + it('Evaluate multiplication', () => { + const program = '(* x y)'; + const context = { x: 1, y: 2 }; + const result = evaluate(program, context); + const expected = 1 * 2; + assert.strictEqual(result, expected, 'Multiplication operator failed'); + }); -// it('Evaluate multiplication with no arguments', () => { -// const program = '(* )'; -// const result = evaluate(program); -// const expected = 1; -// assert.strictEqual(result, expected, 'Multiplication operator failed'); -// }); + it('Evaluate multiplication with no arguments', () => { + const program = '(* )'; + const result = evaluate(program); + const expected = 1; + assert.strictEqual(result, expected, 'Multiplication operator failed'); + }); -// it('Evaluate multiplication on more than two arguments', () => { -// const program = '(* x y z)'; -// const context = { x: 1, y: 2, z: 3 }; -// const result = evaluate(program, context); -// const expected = 1 * 2 * 3; -// assert.strictEqual(result, expected, 'Multiplication operator failed'); -// }); -// }); + it('Evaluate multiplication on more than two arguments', () => { + const program = '(* x y z)'; + const context = { x: 1, y: 2, z: 3 }; + const result = evaluate(program, context); + const expected = 1 * 2 * 3; + assert.strictEqual(result, expected, 'Multiplication operator failed'); + }); + }); -// describe('Division', () => { -// it('Evaluate division', () => { -// const program = '(/ x y)'; -// const context = { x: 1, y: 2 }; -// const result = evaluate(program, context); -// const expected = 1 / 2; -// assert.strictEqual(result, expected, 'Division operator failed'); -// }); + describe('Division', () => { + it('Evaluate division', () => { + const program = '(/ x y)'; + const context = { x: 1, y: 2 }; + const result = evaluate(program, context); + const expected = 1 / 2; + assert.strictEqual(result, expected, 'Division operator failed'); + }); -// it('Evaluate division on more than two arguments', () => { -// const program = '(/ x y z)'; -// const context = { x: 3, y: 4, z: 5 }; -// const result = evaluate(program, context); -// const expected = 3 / (4 * 5); -// assert.strictEqual(result, expected, 'Division operator failed'); -// }); -// }); + it('Evaluate division on more than two arguments', () => { + const program = '(/ x y z)'; + const context = { x: 3, y: 4, z: 5 }; + const result = evaluate(program, context); + const expected = 3 / (4 * 5); + assert.strictEqual(result, expected, 'Division operator failed'); + }); + }); -// it('Evaluate modulus', () => { -// const program = '(mod x y)'; -// const context = { x: 20, y: 10 }; -// const result = evaluate(program, context); -// const expected = 20 % 10; -// assert.strictEqual(result, expected, 'Modulus operator failed'); -// }); + it('Evaluate modulus', () => { + const program = '(mod x y)'; + const context = { x: 20, y: 10 }; + const result = evaluate(program, context); + const expected = 20 % 10; + assert.strictEqual(result, expected, 'Modulus operator failed'); + }); -// it('Evaluate modulus with negative numbers', () => { -// const program = '(mod x y)'; -// const context = { x: -1, y: 5 }; -// const result = evaluate(program, context); -// const expected = ((-1 % 5) + 5) % 5; -// assert.strictEqual( -// result, -// expected, -// 'Modulus operator with negative numbers failed', -// ); -// }); + it('Evaluate modulus with negative numbers', () => { + const program = '(mod x y)'; + const context = { x: -1, y: 5 }; + const result = evaluate(program, context); + const expected = ((-1 % 5) + 5) % 5; + assert.strictEqual( + result, + expected, + 'Modulus operator with negative numbers failed', + ); + }); -// it('Evaluate remainder', () => { -// const program = '(rem x y)'; -// const context = { x: -1, y: 5 }; -// const result = evaluate(program, context); -// const expected = -1 % 5; -// assert.strictEqual(result, expected, 'Reminder operator failed'); -// }); + it('Evaluate remainder', () => { + const program = '(rem x y)'; + const context = { x: -1, y: 5 }; + const result = evaluate(program, context); + const expected = -1 % 5; + assert.strictEqual(result, expected, 'Reminder operator failed'); + }); -// it('Evaluate increment', () => { -// const program = '(incf x)'; -// const context = { x: 1 }; -// const result = evaluate(program, context); -// const expected = 1 + 1; -// assert.strictEqual(result, expected, 'Increment operator failed'); -// }); + it('Evaluate increment', () => { + const program = '(incf x)'; + const context = { x: 1 }; + const result = evaluate(program, context); + const expected = 1 + 1; + assert.strictEqual(result, expected, 'Increment operator failed'); + }); -// it('Evaluate increment with second argument', () => { -// const program = '(incf x y)'; -// const context = { x: 1, y: 2 }; -// const result = evaluate(program, context); -// const expected = 1 + 2; -// assert.strictEqual( -// result, -// expected, -// 'Increment operator with second argument failed', -// ); -// }); + it('Evaluate increment with second argument', () => { + const program = '(incf x y)'; + const context = { x: 1, y: 2 }; + const result = evaluate(program, context); + const expected = 1 + 2; + assert.strictEqual( + result, + expected, + 'Increment operator with second argument failed', + ); + }); -// it('Evaluate decrement', () => { -// const program = '(decf x)'; -// const context = { x: 1 }; -// const result = evaluate(program, context); -// const expected = 1 - 1; -// assert.strictEqual(result, expected, 'Decrement operator failed'); -// }); + it('Evaluate decrement', () => { + const program = '(decf x)'; + const context = { x: 1 }; + const result = evaluate(program, context); + const expected = 1 - 1; + assert.strictEqual(result, expected, 'Decrement operator failed'); + }); -// it('Evaluate decrement with second argument', () => { -// const program = '(decf x y)'; -// const context = { x: 1, y: 2 }; -// const result = evaluate(program, context); -// const expected = 1 - 2; -// assert.strictEqual( -// result, -// expected, -// 'Decrement operator with second argument failed', -// ); -// }); + it('Evaluate decrement with second argument', () => { + const program = '(decf x y)'; + const context = { x: 1, y: 2 }; + const result = evaluate(program, context); + const expected = 1 - 2; + assert.strictEqual( + result, + expected, + 'Decrement operator with second argument failed', + ); + }); -// it('Evaluate increment shortcut', () => { -// const program = '(1+ x)'; -// const context = { x: 1 }; -// const result = evaluate(program, context); -// const expected = 1 + 1; -// assert.strictEqual(result, expected, 'Increment shortcut operator fail'); -// }); + it('Evaluate increment shortcut', () => { + const program = '(1+ x)'; + const context = { x: 1 }; + const result = evaluate(program, context); + const expected = 1 + 1; + assert.strictEqual(result, expected, 'Increment shortcut operator fail'); + }); -// it('Evaluate decrement shortcut', () => { -// const program = '(1- x)'; -// const context = { x: 1 }; -// const result = evaluate(program, context); -// const expected = 1 - 1; -// assert.strictEqual(result, expected, 'Decrement shortcut operator fail'); -// }); + it('Evaluate decrement shortcut', () => { + const program = '(1- x)'; + const context = { x: 1 }; + const result = evaluate(program, context); + const expected = 1 - 1; + assert.strictEqual(result, expected, 'Decrement shortcut operator fail'); + }); -// it('Evaluate complex arithmetic expression', () => { -// const program = '(+ (mod x y) (incf y))'; -// const context = { x: -1, y: 5 }; -// const result = evaluate(program, context); -// const expected = (((-1 % 5) + 5) % 5) + 6; -// assert.strictEqual( -// result, -// expected, -// 'Complex arithmetic expression failed', -// ); -// }); + it('Evaluate complex arithmetic expression', () => { + const program = '(+ (mod x y) (incf y))'; + const context = { x: -1, y: 5 }; + const result = evaluate(program, context); + const expected = (((-1 % 5) + 5) % 5) + 6; + assert.strictEqual( + result, + expected, + 'Complex arithmetic expression failed', + ); + }); -// describe('Greatest common divisor', () => { -// it('Evaluate gcd on two arguments', () => { -// const program = '(gcd x y)'; -// const context = { x: 20, y: 10 }; -// const result = evaluate(program, context); -// const expected = 10; -// assert.strictEqual(result, expected, 'GCD operator failed'); -// }); + describe('Greatest common divisor', () => { + it('Evaluate gcd on two arguments', () => { + const program = '(gcd x y)'; + const context = { x: 20, y: 10 }; + const result = evaluate(program, context); + const expected = 10; + assert.strictEqual(result, expected, 'GCD operator failed'); + }); -// it('Evaluate gcd on multiple arguments', () => { -// const program = '(gcd x y z)'; -// const context = { x: 20, y: 10, z: 5 }; -// const result = evaluate(program, context); -// const expected = 5; -// assert.strictEqual(result, expected, 'GCD operator failed'); -// }); + it('Evaluate gcd on multiple arguments', () => { + const program = '(gcd x y z)'; + const context = { x: 20, y: 10, z: 5 }; + const result = evaluate(program, context); + const expected = 5; + assert.strictEqual(result, expected, 'GCD operator failed'); + }); -// it('Evaluate gcd on some negative arguments', () => { -// const program = '(gcd x y)'; -// const context = { x: -20, y: 10 }; -// const result = evaluate(program, context); -// const expected = 10; -// assert.strictEqual(result, expected, 'GCD operator failed'); -// }); + it('Evaluate gcd on some negative arguments', () => { + const program = '(gcd x y)'; + const context = { x: -20, y: 10 }; + const result = evaluate(program, context); + const expected = 10; + assert.strictEqual(result, expected, 'GCD operator failed'); + }); -// it('Evaluate gcd on single negative argument', () => { -// const program = '(gcd x)'; -// const context = { x: -20 }; -// const result = evaluate(program, context); -// const expected = 20; -// assert.strictEqual(result, expected, 'GCD operator failed'); -// }); + it('Evaluate gcd on single negative argument', () => { + const program = '(gcd x)'; + const context = { x: -20 }; + const result = evaluate(program, context); + const expected = 20; + assert.strictEqual(result, expected, 'GCD operator failed'); + }); -// it('Evaluate gcd on no arguments', () => { -// const program = '(gcd)'; -// const result = evaluate(program); -// const expected = 0; -// assert.strictEqual(result, expected, 'GCD operator failed'); -// }); + it('Evaluate gcd on no arguments', () => { + const program = '(gcd)'; + const result = evaluate(program); + const expected = 0; + assert.strictEqual(result, expected, 'GCD operator failed'); + }); -// it('Evaluate gcd on single argument', () => { -// const program = '(gcd x)'; -// const context = { x: 20 }; -// const result = evaluate(program, context); -// const expected = 20; -// assert.strictEqual(result, expected, 'GCD operator failed'); -// }); -// }); + it('Evaluate gcd on single argument', () => { + const program = '(gcd x)'; + const context = { x: 20 }; + const result = evaluate(program, context); + const expected = 20; + assert.strictEqual(result, expected, 'GCD operator failed'); + }); + }); -// describe('Least common multiple', () => { -// it('Evaluate lcm on two arguments', () => { -// const program = '(lcm x y)'; -// const context = { x: 20, y: 10 }; -// const result = evaluate(program, context); -// const expected = 20; -// assert.strictEqual(result, expected, 'LCM operator failed'); -// }); + describe('Least common multiple', () => { + it('Evaluate lcm on two arguments', () => { + const program = '(lcm x y)'; + const context = { x: 20, y: 10 }; + const result = evaluate(program, context); + const expected = 20; + assert.strictEqual(result, expected, 'LCM operator failed'); + }); -// it('Evaluate lcm on multiple arguments', () => { -// const program = '(lcm x y z)'; -// const context = { x: 1, y: 2, z: 3 }; -// const result = evaluate(program, context); -// const expected = 6; -// assert.strictEqual(result, expected, 'LCM operator failed'); -// }); + it('Evaluate lcm on multiple arguments', () => { + const program = '(lcm x y z)'; + const context = { x: 1, y: 2, z: 3 }; + const result = evaluate(program, context); + const expected = 6; + assert.strictEqual(result, expected, 'LCM operator failed'); + }); -// it('Evaluate lcm on some negative arguments', () => { -// const program = '(lcm x y)'; -// const context = { x: -20, y: 10 }; -// const result = evaluate(program, context); -// const expected = 20; -// assert.strictEqual(result, expected, 'LCM operator failed'); -// }); + it('Evaluate lcm on some negative arguments', () => { + const program = '(lcm x y)'; + const context = { x: -20, y: 10 }; + const result = evaluate(program, context); + const expected = 20; + assert.strictEqual(result, expected, 'LCM operator failed'); + }); -// it('Evaluate lcm on single negative argument', () => { -// const program = '(lcm x)'; -// const context = { x: -20 }; -// const result = evaluate(program, context); -// const expected = 20; -// assert.strictEqual(result, expected, 'LCM operator failed'); -// }); + it('Evaluate lcm on single negative argument', () => { + const program = '(lcm x)'; + const context = { x: -20 }; + const result = evaluate(program, context); + const expected = 20; + assert.strictEqual(result, expected, 'LCM operator failed'); + }); -// it('Evaluate lcm on no arguments', () => { -// const program = '(lcm)'; -// const result = evaluate(program); -// const expected = 1; -// assert.strictEqual(result, expected, 'LCM operator failed'); -// }); -// }); -// }); + it('Evaluate lcm on no arguments', () => { + const program = '(lcm)'; + const result = evaluate(program); + const expected = 1; + assert.strictEqual(result, expected, 'LCM operator failed'); + }); + }); +}); From 68d3baee2044d91dc4ee9de51d2b1749c70fe287 Mon Sep 17 00:00:00 2001 From: Dmytro Brahinets Date: Mon, 9 Dec 2024 20:11:48 +0200 Subject: [PATCH 5/5] Remove only from tests --- test/arithmetic.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/arithmetic.js b/test/arithmetic.js index 4c8f8de..8d81b53 100644 --- a/test/arithmetic.js +++ b/test/arithmetic.js @@ -5,7 +5,7 @@ const { evaluate } = require('..'); describe('Arithmetic operators', () => { describe('Addition', () => { - it.only('Evaluate addition', () => { + it('Evaluate addition', () => { const program = '(+ x y)'; const context = { x: 1, y: 2 }; const result = evaluate(program, context);