Skip to content

Commit f6e9c5f

Browse files
committed
🚧 adding procedure symbols to symbol table
1 parent 31c0bbd commit f6e9c5f

File tree

6 files changed

+50
-20
lines changed

6 files changed

+50
-20
lines changed

PascalInterpreter/PascalInterpreter.xcodeproj/project.pbxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,10 @@
174174
F300A0E01FDDB74700E5894D /* Semantic analyzer */ = {
175175
isa = PBXGroup;
176176
children = (
177-
F300A0E11FDDB74700E5894D /* Symbol+Extensions.swift */,
177+
F300A0E41FDDB74700E5894D /* SemanticAnalyzer.swift */,
178178
F300A0E21FDDB74700E5894D /* Symbol.swift */,
179+
F300A0E11FDDB74700E5894D /* Symbol+Extensions.swift */,
179180
F300A0E31FDDB74700E5894D /* SymbolTable.swift */,
180-
F300A0E41FDDB74700E5894D /* SemanticAnalyzer.swift */,
181181
);
182182
path = "Semantic analyzer";
183183
sourceTree = "<group>";

PascalInterpreter/PascalInterpreter/Interpreter/Interpreter.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public class Interpreter {
6161
fatalError("Assignment left side is not a variable")
6262
}
6363

64-
guard let symbol = symbolTable.lookup(name), case let .variable(name: _, type: type) = symbol else {
64+
guard let symbol = symbolTable.lookup(name), case let .variable(name: _, type: .builtIn(type)) = symbol else {
6565
fatalError("Variable \(name) not in the symbol table")
6666
}
6767

@@ -84,7 +84,7 @@ public class Interpreter {
8484
return nil
8585
}
8686
case let .variable(name):
87-
guard let symbol = symbolTable.lookup(name), case let .variable(name: _, type: type) = symbol else {
87+
guard let symbol = symbolTable.lookup(name), case let .variable(name: _, type: .builtIn(type)) = symbol else {
8888
fatalError("Variable \(name) not in the symbol table")
8989
}
9090

PascalInterpreter/PascalInterpreter/Semantic analyzer/SemanticAnalyzer.swift

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public class SemanticAnalyzer {
5555
fatalError("Duplicate identifier '\(name)' found")
5656
}
5757

58-
guard let resolved = symbolTable.lookup(type.description), case let .builtIn(symbolType) = resolved else {
58+
guard let symbolType = symbolTable.lookup(type.description) else {
5959
fatalError("Type not found '\(type.description)'")
6060
}
6161

@@ -65,9 +65,19 @@ public class SemanticAnalyzer {
6565
visit(node: left)
6666
case .type:
6767
break
68-
case .procedure:
69-
// TODO: local scope
70-
break
68+
case let .procedure(name: name, params: params, block: _):
69+
var parameters: [Symbol] = []
70+
for param in params {
71+
guard case let .param(name: name, type: .type(type)) = param else {
72+
fatalError("Only built int type parameters supported in procedure, got \(param)")
73+
}
74+
guard let symbol = symbolTable.lookup(type.description) else {
75+
fatalError("Type not found '\(type.description)'")
76+
}
77+
parameters.append(.variable(name: name, type: symbol))
78+
}
79+
let symbol = Symbol.procedure(name: name, params: parameters)
80+
symbolTable.insert(symbol)
7181
case .param:
7282
break
7383
}

PascalInterpreter/PascalInterpreter/Semantic analyzer/Symbol+Extensions.swift

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ import Foundation
1010

1111
extension BuiltInType: CustomStringConvertible {
1212
public var description: String {
13+
return "<BuiltinTypeSymbol(name='\(self.name)')>"
14+
}
15+
16+
public var name: String {
1317
switch self {
1418
case .integer:
1519
return "INTEGER"
@@ -25,7 +29,9 @@ extension Symbol: CustomStringConvertible {
2529
case let .builtIn(type):
2630
return type.description
2731
case let .variable(name: name, type: type):
28-
return "<\(name):\(type)>"
32+
return "<VarSymbol(name='\(name)', type='\(type.name)')>"
33+
case let .procedure(name: name, params: params):
34+
return "<ProcedureSymbol(name=\(name), parameters=[\(params.reduce("", { $0.description + "," + $1.description }))]>"
2935
}
3036
}
3137
}
@@ -43,3 +49,16 @@ extension Symbol: Equatable {
4349
}
4450

4551
}
52+
53+
extension Symbol {
54+
public var name: String {
55+
switch self {
56+
case let .builtIn(type):
57+
return type.name
58+
case .procedure(name: let name, params: _):
59+
return name
60+
case .variable(name: let name, type: _):
61+
return name
62+
}
63+
}
64+
}

PascalInterpreter/PascalInterpreter/Semantic analyzer/Symbol.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ public enum BuiltInType {
1313
case real
1414
}
1515

16-
public enum Symbol {
16+
public indirect enum Symbol {
1717
case builtIn(BuiltInType)
18-
case variable(name: String, type: BuiltInType)
18+
case variable(name: String, type: Symbol)
19+
case procedure(name: String, params: [Symbol])
1920
}

PascalInterpreter/PascalInterpreter/Semantic analyzer/SymbolTable.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,12 @@ public class ScopedSymbolTable {
1818
self.name = name
1919
self.level = level
2020

21-
let integer = Symbol.builtIn(.integer)
22-
let real = Symbol.builtIn(.real)
23-
symbols[integer.description] = integer
24-
symbols[real.description] = real
21+
insert(.builtIn(.integer))
22+
insert(.builtIn(.real))
2523
}
2624

2725
func insert(_ symbol: Symbol) {
28-
guard case let .variable(name: name, type: _) = symbol else {
29-
fatalError("Cannot insert built in type \(symbol), only variables")
30-
}
31-
32-
symbols[name] = symbol
26+
symbols[symbol.name] = symbol
3327
}
3428

3529
func lookup(_ name: String) -> Symbol? {
@@ -68,6 +62,12 @@ extension ScopedSymbolTable: CustomStringConvertible {
6862
return false
6963
case (.variable, .variable):
7064
return lhs.key < rhs.key
65+
case (.procedure, .procedure):
66+
return lhs.key < rhs.key
67+
case (.procedure, _):
68+
return false
69+
case (_, .procedure):
70+
return true
7171
}
7272
}) {
7373
lines.append("\(pair.key.padding(toLength: 7, withPad: " ", startingAt: 0)): \(pair.value)")

0 commit comments

Comments
 (0)