Skip to content

Commit 0e751c5

Browse files
committed
🚨 tests passing again
1 parent bf339f1 commit 0e751c5

File tree

9 files changed

+87
-43
lines changed

9 files changed

+87
-43
lines changed

PascalInterpreter/PascalInterpreter/FatalError.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ import Foundation
1111
/**
1212
Taken from https://medium.com/@marcosantadev/how-to-test-fatalerror-in-swift-e1be9ff11a29
1313
*/
14-
/*func fatalError(_ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) -> Never {
14+
func fatalError(_ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) -> Never {
1515
FatalErrorUtil.fatalErrorClosure(message(), file, line)
16-
}*/
16+
}
1717

1818
struct FatalErrorUtil {
1919

PascalInterpreter/PascalInterpreter/Interpreter/Frame.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ class Frame {
3030
case .real:
3131
arrays[symbol.key.uppercased()] = Array(repeating: .number(.real(0)), count: arraySymbol.endIndex - arraySymbol.startIndex + 1)
3232
case .boolean:
33-
arrays[symbol.key.uppercased()] = Array(repeating: .boolean(false), count: arraySymbol.endIndex - arraySymbol.startIndex + 1)
33+
arrays[symbol.key.uppercased()] = Array(repeating: .boolean(false), count: arraySymbol.endIndex - arraySymbol.startIndex + 1)
3434
case .string:
35-
arrays[symbol.key.uppercased()] = Array(repeating: .string(""), count: arraySymbol.endIndex - arraySymbol.startIndex + 1)
35+
arrays[symbol.key.uppercased()] = Array(repeating: .string(""), count: arraySymbol.endIndex - arraySymbol.startIndex + 1)
3636
}
3737
}
3838
}
@@ -46,7 +46,7 @@ class Frame {
4646
let arraySymbol = symbol as? ArraySymbol,
4747
let type = arraySymbol.type as? BuiltInTypeSymbol {
4848

49-
let computedIndex = index - arraySymbol.startIndex
49+
let computedIndex = index - arraySymbol.startIndex
5050
switch (value, type) {
5151
case (.number(.integer), .integer):
5252
arrays[variable.uppercased()]![computedIndex] = value
@@ -116,7 +116,7 @@ class Frame {
116116
func get(variable: String, index: Int) -> Value {
117117
// variable define in current scole (procedure declataion, etc)
118118
if let symbol = scope.lookup(variable, currentScopeOnly: true), let arraySymbol = symbol as? ArraySymbol {
119-
let computedIndex = index - arraySymbol.startIndex
119+
let computedIndex = index - arraySymbol.startIndex
120120
return arrays[variable.uppercased()]![computedIndex]
121121
}
122122

PascalInterpreter/PascalInterpreter/Interpreter/Interpreter+Standard.swift

+10
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,21 @@ extension Interpreter {
2525
return .none
2626
case "RANDOM":
2727
return random(params: params)
28+
case "LENGTH":
29+
return length(params: params, frame: frame)
2830
default:
2931
fatalError("Implement built in procedure \(procedure)")
3032
}
3133
}
3234

35+
private func length(params: [AST], frame: Frame) -> Value {
36+
guard params.count == 1, let first = params.first, let variable = first as? Variable, let definition = frame.scope.lookup(variable.name) as? ArraySymbol else {
37+
fatalError("Length called with invalid parameters")
38+
}
39+
40+
return .number(.integer(definition.endIndex - definition.startIndex + 1))
41+
}
42+
3343
private func random(params: [AST]) -> Value {
3444
guard params.count == 1, let first = params.first, case let .number(.integer(l)) = eval(node: first) else {
3545
fatalError("Random called with invalid parameters")

PascalInterpreter/PascalInterpreter/Interpreter/Interpreter.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,8 @@ public class Interpreter {
240240
eval(node: tree)
241241
}
242242

243-
func getState() -> ([String: Value]) {
244-
return (callStack.peek()!.scalars)
243+
func getState() -> ([String: Value], [String: [Value]]) {
244+
return (callStack.peek()!.scalars, callStack.peek()!.arrays)
245245
}
246246

247247
public func printState() {

PascalInterpreter/PascalInterpreter/Lexer/Lexer.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public class Lexer {
115115
advance()
116116
}
117117

118-
if let character = currentCharacter, character == ".", text[text.index(text.startIndex, offsetBy: currentPosition)] != "." {
118+
if let character = currentCharacter, character == ".", text[text.index(text.startIndex, offsetBy: currentPosition + 1)] != "." {
119119
lexem += "."
120120
advance()
121121

PascalInterpreter/PascalInterpreter/Parser/Parser.swift

+4-2
Original file line numberDiff line numberDiff line change
@@ -234,9 +234,11 @@ public class Parser {
234234
}
235235
eat(.bracket(.right))
236236
eat(.of)
237-
return variableNames.map({ ArrayDeclaration(variable: Variable(name: $0), type: typeSpec(), startIndex: startIndex, endIndex: endIndex) })
237+
let type = typeSpec()
238+
return variableNames.map({ ArrayDeclaration(variable: Variable(name: $0), type: type, startIndex: startIndex, endIndex: endIndex) })
238239
} else {
239-
return variableNames.map({ VariableDeclaration(variable: Variable(name: $0), type: typeSpec()) })
240+
let type = typeSpec()
241+
return variableNames.map({ VariableDeclaration(variable: Variable(name: $0), type: type) })
240242
}
241243
}
242244

PascalInterpreter/PascalInterpreter/Semantic analyzer/SymbolTable.swift

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public class ScopedSymbolTable {
3737
symbols["READ"] = BuiltInProcedureSymbol(name: "READ", parameters: [], hasVariableParameters: true)
3838
symbols["READLN"] = BuiltInProcedureSymbol(name: "READLN", parameters: [], hasVariableParameters: true)
3939
symbols["RANDOM"] = BuiltInProcedureSymbol(name: "RANDOM", parameters: [BuiltInTypeSymbol.integer], hasVariableParameters: false)
40+
symbols["LENGTH"] = BuiltInProcedureSymbol(name: "LENGTH", parameters: [], hasVariableParameters: true)
4041
}
4142

4243
func insert(_ symbol: Symbol) {

PascalInterpreter/PascalInterpreterTests/InterpreterTests.swift

+46-32
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ class InterpreterTests: XCTestCase {
2525

2626
let interpeter = Interpreter(program)
2727
interpeter.interpret()
28-
let state = interpeter.getState()
29-
XCTAssert(state == ["a": Value.number(.integer(2))])
28+
let (scalars, arrays) = interpeter.getState()
29+
XCTAssert(scalars == ["A": Value.number(.integer(2))])
30+
XCTAssert(arrays.count == 0)
3031
}
3132

3233
func testMoreComplexProgram() {
@@ -48,8 +49,9 @@ class InterpreterTests: XCTestCase {
4849

4950
let interpeter = Interpreter(program)
5051
interpeter.interpret()
51-
let state = interpeter.getState()
52-
XCTAssert(state == ["b": Value.number(.integer(25)), "number": Value.number(.integer(2)), "a": Value.number(.integer(2)), "x": Value.number(.integer(11)), "c": Value.number(.integer(27))])
52+
let (scalars, arrays) = interpeter.getState()
53+
XCTAssert(scalars == ["B": Value.number(.integer(25)), "NUMBER": Value.number(.integer(2)), "A": Value.number(.integer(2)), "X": Value.number(.integer(11)), "C": Value.number(.integer(27))])
54+
XCTAssert(arrays.count == 0)
5355
}
5456

5557
func testProgramWithDeclarations() {
@@ -69,8 +71,9 @@ class InterpreterTests: XCTestCase {
6971

7072
let interpeter = Interpreter(program)
7173
interpeter.interpret()
72-
let state = interpeter.getState()
73-
XCTAssert(state == ["b": Value.number(.integer(25)), "a": Value.number(.integer(2)), "y": Value.number(.real(5.9971428571428573))])
74+
let (scalars, arrays) = interpeter.getState()
75+
XCTAssert(scalars == ["B": Value.number(.integer(25)), "A": Value.number(.integer(2)), "Y": Value.number(.real(5.9971428571428573))])
76+
XCTAssert(arrays.count == 0)
7477
}
7578

7679
func testProgramWithProcedureCallAndNoParameters() {
@@ -94,8 +97,9 @@ class InterpreterTests: XCTestCase {
9497

9598
let interpeter = Interpreter(program)
9699
interpeter.interpret()
97-
let state = interpeter.getState()
98-
XCTAssert(state == ["x": Value.number(.real(7)), "y": Value.number(.real(5))])
100+
let (scalars, arrays) = interpeter.getState()
101+
XCTAssert(scalars == ["X": Value.number(.real(7)), "Y": Value.number(.real(5))])
102+
XCTAssert(arrays.count == 0)
99103
}
100104

101105
func testProgramWithProcedureCallAndParameters() {
@@ -117,8 +121,9 @@ class InterpreterTests: XCTestCase {
117121

118122
let interpeter = Interpreter(program)
119123
interpeter.interpret()
120-
let state = interpeter.getState()
121-
XCTAssert(state == ["x": Value.number(.real(5)), "y": Value.number(.real(3))])
124+
let (scalars, arrays) = interpeter.getState()
125+
XCTAssert(scalars == ["X": Value.number(.real(5)), "Y": Value.number(.real(3))])
126+
XCTAssert(arrays.count == 0)
122127
}
123128

124129
func testProgramWithRecursiveFunction() {
@@ -142,8 +147,9 @@ class InterpreterTests: XCTestCase {
142147

143148
let interpeter = Interpreter(program)
144149
interpeter.interpret()
145-
let state = interpeter.getState()
146-
XCTAssert(state == ["result": Value.number(.integer(720))])
150+
let (scalars, arrays) = interpeter.getState()
151+
XCTAssert(scalars == ["RESULT": Value.number(.integer(720))])
152+
XCTAssert(arrays.count == 0)
147153
}
148154

149155
func testProgramWithRecursiveAndBuiltInFunctions() {
@@ -168,8 +174,9 @@ class InterpreterTests: XCTestCase {
168174

169175
let interpeter = Interpreter(program)
170176
interpeter.interpret()
171-
let state = interpeter.getState()
172-
XCTAssert(state == ["result": Value.number(.integer(720))])
177+
let (scalars, arrays) = interpeter.getState()
178+
XCTAssert(scalars == ["RESULT": Value.number(.integer(720))])
179+
XCTAssert(arrays.count == 0)
173180
}
174181

175182
func testProgramWithRecursiveFunctionsAndParameterTheSameName() {
@@ -194,8 +201,9 @@ class InterpreterTests: XCTestCase {
194201

195202
let interpeter = Interpreter(program)
196203
interpeter.interpret()
197-
let state = interpeter.getState()
198-
XCTAssert(state == ["result": Value.number(.integer(720)), "number": Value.number(.integer(6))])
204+
let (scalars, arrays) = interpeter.getState()
205+
XCTAssert(scalars == ["RESULT": Value.number(.integer(720)), "NUMBER": Value.number(.integer(6))])
206+
XCTAssert(arrays.count == 0)
199207
}
200208

201209
func testProgramWithRepeatUntil() {
@@ -215,8 +223,9 @@ class InterpreterTests: XCTestCase {
215223

216224
let interpeter = Interpreter(program)
217225
interpeter.interpret()
218-
let state = interpeter.getState()
219-
XCTAssert(state == ["x": Value.number(.integer(6))])
226+
let (scalars, arrays) = interpeter.getState()
227+
XCTAssert(scalars == ["X": Value.number(.integer(6))])
228+
XCTAssert(arrays.count == 0)
220229
}
221230

222231
func testProgramWithForLoop() {
@@ -235,25 +244,30 @@ class InterpreterTests: XCTestCase {
235244

236245
let interpeter = Interpreter(program)
237246
interpeter.interpret()
238-
let state = interpeter.getState()
239-
XCTAssert(state == ["x": Value.number(.integer(6))])
247+
let (scalars, arrays) = interpeter.getState()
248+
XCTAssert(scalars == ["X": Value.number(.integer(6))])
249+
XCTAssert(arrays.count == 0)
240250
}
241251

242252
func testProgramWithArray() {
243-
let program =
244-
"""
245-
program Main;
246-
var data: array [1..5] of Integer;
247-
248-
begin
249-
for i:=1 to 5 do
250-
begin
251-
data[i] := i;
252-
end;
253-
end.
254-
"""
253+
let program =
254+
"""
255+
program Main;
256+
var data: array [1..5] of Integer;
257+
258+
begin
259+
for i:=1 to length(data) do
260+
begin
261+
data[i] := i;
262+
end;
263+
end.
264+
"""
255265

256266
let interpeter = Interpreter(program)
257267
interpeter.interpret()
268+
let (scalars, arrays) = interpeter.getState()
269+
XCTAssert(scalars == [:])
270+
XCTAssert(arrays.count==1)
271+
XCTAssert(arrays["DATA"]! == [Value.number(.integer(1)), Value.number(.integer(2)), Value.number(.integer(3)), Value.number(.integer(4)), Value.number(.integer(5))])
258272
}
259273
}

PascalInterpreter/PascalInterpreterTests/LexerTests.swift

+17
Original file line numberDiff line numberDiff line change
@@ -480,4 +480,21 @@ class LexerTests: XCTestCase {
480480
XCTAssert(lexer.getNextToken() == .constant(.integer(1)))
481481
XCTAssert(lexer.getNextToken() == .eof)
482482
}
483+
484+
func testArrayTokens() {
485+
let lexer = Lexer("var x: array [1..5] of Integer")
486+
XCTAssert(lexer.getNextToken() == .varDef)
487+
XCTAssert(lexer.getNextToken() == .id("x"))
488+
XCTAssert(lexer.getNextToken() == .colon)
489+
XCTAssert(lexer.getNextToken() == .array)
490+
XCTAssert(lexer.getNextToken() == .bracket(.left))
491+
XCTAssert(lexer.getNextToken() == .constant(.integer(1)))
492+
XCTAssert(lexer.getNextToken() == .dot)
493+
XCTAssert(lexer.getNextToken() == .dot)
494+
XCTAssert(lexer.getNextToken() == .constant(.integer(5)))
495+
XCTAssert(lexer.getNextToken() == .bracket(.right))
496+
XCTAssert(lexer.getNextToken() == .of)
497+
XCTAssert(lexer.getNextToken() == .type(.integer))
498+
XCTAssert(lexer.getNextToken() == .eof)
499+
}
483500
}

0 commit comments

Comments
 (0)