diff --git a/slox/Interpreter.swift b/slox/Interpreter.swift index f9e4a85..a46fe5e 100644 --- a/slox/Interpreter.swift +++ b/slox/Interpreter.swift @@ -17,6 +17,33 @@ class Interpreter { deleteAt(index) { return deleteAtNative(this, index); } + + map(fn) { + var result = []; + for (var i = 0; i < this.count; i = i + 1) { + var newElement = fn(this[i]); + result.append(newElement); + } + return result; + } + + filter(fn) { + var result = []; + for (var i = 0; i < this.count; i = i + 1) { + if (fn(this[i])) { + result.append(this[i]); + } + } + return result; + } + + reduce(initial, fn) { + var result = initial; + for (var i = 0; i < this.count; i = i + 1) { + result = fn(result, this[i]); + } + return result; + } } """ var environment: Environment = Environment() diff --git a/sloxTests/InterpreterTests.swift b/sloxTests/InterpreterTests.swift index fc09930..242be99 100644 --- a/sloxTests/InterpreterTests.swift +++ b/sloxTests/InterpreterTests.swift @@ -579,6 +579,52 @@ foo.count XCTAssertEqual(actual, expected) } + func testInterpretMappingOverAList() throws { + let input = """ +var foo = [1, 2, 3, 4, 5]; +foo.map(fun(n) { return n*n; }) +""" + + let interpreter = Interpreter() + let actual = try interpreter.interpretRepl(source: input) + let expected = try interpreter.makeList(elements: [ + .int(1), + .int(4), + .int(9), + .int(16), + .int(25), + ]) + XCTAssertEqual(actual, expected) + } + + func testInterpretFilteringAList() throws { + let input = """ +var foo = [1, 2, 3, 4, 5]; +foo.filter(fun(n) { return n<=3; }) +""" + + let interpreter = Interpreter() + let actual = try interpreter.interpretRepl(source: input) + let expected = try interpreter.makeList(elements: [ + .int(1), + .int(2), + .int(3), + ]) + XCTAssertEqual(actual, expected) + } + + func testInterpretReducingOverAList() throws { + let input = """ +var foo = [1, 2, 3, 4, 5]; +foo.reduce(0, fun(acc, n) { return acc+n; }) +""" + + let interpreter = Interpreter() + let actual = try interpreter.interpretRepl(source: input) + let expected: LoxValue = .int(15) + XCTAssertEqual(actual, expected) + } + func testInterpretForLoopWithBreakStatement() throws { let input = """ var sum = 0;