-
Notifications
You must be signed in to change notification settings - Fork 17
/
SymbolTable.swift
72 lines (60 loc) · 2.53 KB
/
SymbolTable.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//
// SymbolTable.swift
// SwiftPascalInterpreter
//
// Created by Igor Kulman on 10/12/2017.
// Copyright © 2017 Igor Kulman. All rights reserved.
//
import Foundation
public class ScopedSymbolTable {
private(set) var symbols: [String: Symbol] = [:]
let name: String
let level: Int
let enclosingScope: ScopedSymbolTable?
init(name: String, level: Int, enclosingScope: ScopedSymbolTable?) {
self.name = name
self.level = level
self.enclosingScope = enclosingScope
insertBuiltInTypes()
insertBuildInProcedures()
}
private func insertBuiltInTypes() {
insert(BuiltInTypeSymbol.integer)
insert(BuiltInTypeSymbol.real)
insert(BuiltInTypeSymbol.boolean)
insert(BuiltInTypeSymbol.string)
}
private func insertBuildInProcedures() {
symbols["WRITELN"] = BuiltInProcedureSymbol(name: "WRITELN", parameters: [], hasVariableParameters: true)
symbols["WRITE"] = BuiltInProcedureSymbol(name: "WRITE", parameters: [], hasVariableParameters: true)
symbols["READ"] = BuiltInProcedureSymbol(name: "READ", parameters: [], hasVariableParameters: true)
symbols["READLN"] = BuiltInProcedureSymbol(name: "READLN", parameters: [], hasVariableParameters: true)
symbols["RANDOM"] = BuiltInProcedureSymbol(name: "RANDOM", parameters: [BuiltInTypeSymbol.integer], hasVariableParameters: false)
symbols["LENGTH"] = BuiltInProcedureSymbol(name: "LENGTH", parameters: [], hasVariableParameters: true)
}
func insert(_ symbol: Symbol) {
symbols[symbol.name.uppercased()] = symbol
}
func lookup(_ name: String, currentScopeOnly: Bool = false) -> Symbol? {
if let symbol = symbols[name.uppercased()] {
return symbol
}
if currentScopeOnly {
return nil
}
return enclosingScope?.lookup(name)
}
}
extension ScopedSymbolTable: CustomStringConvertible {
public var description: String {
var lines = ["SCOPE (SCOPED SYMBOL TABLE)", "==========================="]
lines.append("Scope name : \(name)")
lines.append("Scope level : \(level)")
lines.append("Scope (Scoped symbol table) contents")
lines.append("------------------------------------")
lines.append(contentsOf: symbols.sorted(by: { $0.value.sortOrder < $1.value.sortOrder }).map({ key, value in
"\(key.padding(toLength: 12, withPad: " ", startingAt: 0)): \(value)"
}))
return lines.reduce("", { $0 + "\n" + $1 })
}
}