Skip to content

Commit 941bb40

Browse files
committed
🐛 fixing the Interpreter
1 parent 6c7d990 commit 941bb40

File tree

5 files changed

+46
-49
lines changed

5 files changed

+46
-49
lines changed

PascalInterpreter/PascalInterpreter/Interpreter/Interpreter.swift

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,13 @@ import Foundation
1111
public class Interpreter {
1212
private var integerMemory: [String: Int] = [:]
1313
private var realMemory: [String: Double] = [:]
14-
private let symbolTable: ScopedSymbolTable
1514
private let tree: AST
1615

1716
public init(_ text: String) {
1817
let parser = Parser(text)
1918
tree = parser.parse()
2019
let semanticAnalyzer = SemanticAnalyzer()
21-
symbolTable = semanticAnalyzer.build(node: tree)
20+
semanticAnalyzer.analyze(node: tree)
2221
}
2322

2423
@discardableResult private func eval(_ node: AST) -> Number? {
@@ -58,51 +57,56 @@ public class Interpreter {
5857
return nil
5958
case let .assignment(left, right):
6059
guard case let .variable(name) = left else {
61-
fatalError("Assignment left side is not a variable")
60+
fatalError("Assignment left side is not a variable, check Parser implementation")
6261
}
6362

64-
guard let symbol = symbolTable.lookup(name), case let .variable(name: _, type: .builtIn(type)) = symbol else {
65-
fatalError("Variable \(name) not in the symbol table")
66-
}
67-
68-
switch type {
69-
case .integer:
63+
if integerMemory.keys.contains(name) {
7064
switch eval(right)! {
7165
case let .integer(value):
7266
integerMemory[name] = value
67+
return nil
7368
case .real:
74-
fatalError("Cannot assign real value to Int variable \(name)")
69+
fatalError("Cannot assign Real value to Int variable \(name)")
7570
}
76-
return nil
77-
case .real:
71+
}
72+
73+
if realMemory.keys.contains(name) {
7874
switch eval(right)! {
7975
case let .integer(value):
8076
realMemory[name] = Double(value)
77+
return nil
8178
case let .real(value):
8279
realMemory[name] = value
80+
return nil
8381
}
84-
return nil
8582
}
83+
84+
fatalError("Variable \(name) not found, check the SemanticAnalyzer implementation")
8685
case let .variable(name):
87-
guard let symbol = symbolTable.lookup(name), case let .variable(name: _, type: .builtIn(type)) = symbol else {
88-
fatalError("Variable \(name) not in the symbol table")
86+
if let value = integerMemory[name] {
87+
return .integer(value)
8988
}
90-
91-
switch type {
92-
case .integer:
93-
return .integer(integerMemory[name]!)
94-
case .real:
95-
return .real(realMemory[name]!)
89+
if let value = realMemory[name] {
90+
return .real(value)
9691
}
92+
fatalError("Variable \(name) not found, check the SemanticAnalyzer implementation")
9793
case .noOp:
9894
return nil
9995
case let .block(declarations, compound):
10096
for declaration in declarations {
10197
eval(declaration)
10298
}
10399
return eval(compound)
104-
case .variableDeclaration:
105-
// process by the symbol table
100+
case let .variableDeclaration(name: name, type: type):
101+
guard case let .type(type) = type, case let .variable(name: name) = name else {
102+
fatalError("Invalid variable declaration, check Parser implementation")
103+
}
104+
switch type {
105+
case .integer:
106+
integerMemory[name] = 0
107+
case .real:
108+
realMemory[name] = 0
109+
}
106110
return nil
107111
case .type:
108112
return nil

PascalInterpreter/PascalInterpreter/Semantic analyzer/SemanticAnalyzer.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,8 @@ public class SemanticAnalyzer {
1515

1616
}
1717

18-
public func build(node: AST) -> ScopedSymbolTable {
18+
public func analyze(node: AST) {
1919
visit(node: node)
20-
return ScopedSymbolTable(name: "global", level: 1, enclosingScope: nil)
2120
}
2221

2322
private func visit(node: AST) {

PascalInterpreter/PascalInterpreterTests/ParserTests.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ class ParserTests: XCTestCase {
167167
let compound = AST.compound(children: [AST.assignment(left: a, right: two), empty])
168168
let aDec = AST.variableDeclaration(name: AST.variable("a"), type: .type(.integer))
169169
let bDec = AST.variableDeclaration(name: AST.variable("b"), type: .type(.integer))
170-
let p1 = AST.procedure(name: "P1", block: AST.block(declarations: [], compound: AST.compound(children: [.noOp])))
170+
let p1 = AST.procedure(name: "P1", params: [], block: AST.block(declarations: [], compound: AST.compound(children: [.noOp])))
171171
let node = AST.program(name: "Part10AST", block: AST.block(declarations: [aDec, bDec, p1], compound: compound))
172172
XCTAssert(result == node)
173173
}
@@ -207,8 +207,8 @@ class ParserTests: XCTestCase {
207207
let a = AST.variable("a")
208208
let compound = AST.compound(children: [AST.assignment(left: a, right: ten), empty])
209209
let aDec = AST.variableDeclaration(name: AST.variable("a"), type: .type(.integer))
210-
let p2 = AST.procedure(name: "P2", block: AST.block(declarations: [AST.variableDeclaration(name: .variable("a"), type: .type(.integer)), AST.variableDeclaration(name: .variable("z"), type: .type(.integer))], compound: AST.compound(children: [AST.assignment(left: AST.variable("z"), right: AST.number(.integer(777))), empty])))
211-
let p1 = AST.procedure(name: "P1", block: AST.block(declarations: [AST.variableDeclaration(name: .variable("a"), type: .type(.real)), AST.variableDeclaration(name: .variable("k"), type: .type(.integer)), p2], compound: AST.compound(children: [empty])))
210+
let p2 = AST.procedure(name: "P2", params: [], block: AST.block(declarations: [AST.variableDeclaration(name: .variable("a"), type: .type(.integer)), AST.variableDeclaration(name: .variable("z"), type: .type(.integer))], compound: AST.compound(children: [AST.assignment(left: AST.variable("z"), right: AST.number(.integer(777))), empty])))
211+
let p1 = AST.procedure(name: "P1", params: [], block: AST.block(declarations: [AST.variableDeclaration(name: .variable("a"), type: .type(.real)), AST.variableDeclaration(name: .variable("k"), type: .type(.integer)), p2], compound: AST.compound(children: [empty])))
212212
let node = AST.program(name: "Part12", block: AST.block(declarations: [aDec, p1], compound: compound))
213213
XCTAssert(result == node)
214214
}

PascalInterpreter/PascalInterpreterTests/SemanticAnalyzer.swift

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,6 @@ import XCTest
1414

1515
class SemanticAnalyzerTests: XCTestCase {
1616
func testSemanticAnalyzer() {
17-
let table = SymbolTable()
18-
table.insert(.variable(name: "y", type: .real))
19-
table.insert(.variable(name: "a", type: .integer))
20-
table.insert(.variable(name: "b", type: .integer))
21-
table.insert(.variable(name: "number", type: .integer))
22-
2317
let program =
2418
"""
2519
PROGRAM Part10AST;
@@ -40,8 +34,7 @@ class SemanticAnalyzerTests: XCTestCase {
4034
let node = parser.parse()
4135

4236
let analyzer = SemanticAnalyzer()
43-
let result = analyzer.build(node: node)
44-
XCTAssert(result == table)
37+
analyzer.analyze(node: node)
4538
}
4639

4740
func testSemanticAnalyzerAssignUndeclaredVariable() {
@@ -66,7 +59,7 @@ class SemanticAnalyzerTests: XCTestCase {
6659

6760
let analyzer = SemanticAnalyzer()
6861
expectFatalError(expectedMessage: "Symbol(indetifier) not found 'x'") {
69-
_ = analyzer.build(node: node)
62+
analyzer.analyze(node: node)
7063
}
7164
}
7265

@@ -86,7 +79,7 @@ class SemanticAnalyzerTests: XCTestCase {
8679

8780
let analyzer = SemanticAnalyzer()
8881
expectFatalError(expectedMessage: "Symbol(indetifier) not found 'y'") {
89-
_ = analyzer.build(node: node)
82+
analyzer.analyze(node: node)
9083
}
9184
}
9285

@@ -107,7 +100,7 @@ class SemanticAnalyzerTests: XCTestCase {
107100

108101
let analyzer = SemanticAnalyzer()
109102
expectFatalError(expectedMessage: "Duplicate identifier 'y' found") {
110-
_ = analyzer.build(node: node)
103+
analyzer.analyze(node: node)
111104
}
112105
}
113106
}

Playground.playground/Contents.swift

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ let program =
1717
"""
1818
PROGRAM Part10AST;
1919
VAR
20-
a, b : INTEGER;
21-
y : REAL;
20+
a, b : INTEGER;
21+
y : REAL;
2222
2323
BEGIN {Part10AST}
24-
a := 2;
25-
b := 10 * a + 10 * a DIV 4;
26-
y := 20 / 7 + 3.14 + a;
24+
a := 2;
25+
b := 10 * a + 10 * a DIV 4;
26+
y := 20 / 7 + 3.14 + a;
2727
END. {Part10AST}
2828
"""
2929

@@ -32,11 +32,12 @@ let node = parser.parse()
3232
print(node)
3333
print("")
3434

35+
let analyzer = SemanticAnalyzer()
36+
analyzer.analyze(node: node)
37+
38+
print("")
39+
3540
let interpreter = Interpreter(program)
3641
interpreter.interpret()
37-
interpreter.printState()
38-
3942
print("")
40-
let analyzer = SemanticAnalyzer()
41-
let table = analyzer.build(node: node)
42-
print(table)
43+
interpreter.printState()

0 commit comments

Comments
 (0)