|
9 | 9 | import Foundation |
10 | 10 |
|
11 | 11 | public class Interpreter { |
12 | | - private let lexer: Lexer |
13 | | - private var currentToken: Token |
| 12 | + private let parser: Parser |
14 | 13 |
|
15 | 14 | public init(_ text: String) { |
16 | | - lexer = Lexer(text) |
17 | | - currentToken = lexer.getNextToken() |
| 15 | + parser = Parser(text) |
18 | 16 | } |
19 | 17 |
|
20 | | - private func eatInteger() { |
21 | | - switch currentToken { |
22 | | - case .integer: |
23 | | - currentToken = lexer.getNextToken() |
24 | | - default: |
25 | | - fatalError("Expected integer, got \(currentToken)") |
26 | | - } |
27 | | - } |
28 | | - |
29 | | - private func eatOperation(_ operation: Operation) { |
30 | | - switch currentToken { |
31 | | - case .operation(operation): |
32 | | - currentToken = lexer.getNextToken() |
33 | | - default: |
34 | | - fatalError("Expected \(operation), got \(currentToken)") |
35 | | - } |
36 | | - } |
37 | | - |
38 | | - private func eatParenthesis(_ parenthesis: Parenthesis) { |
39 | | - switch currentToken { |
40 | | - case .parenthesis(parenthesis): |
41 | | - currentToken = lexer.getNextToken() |
42 | | - default: |
43 | | - fatalError("Expected \(parenthesis), got \(currentToken)") |
44 | | - } |
| 18 | + public func eval() -> Int { |
| 19 | + let node = parser.expr() |
| 20 | + return visit(node) |
45 | 21 | } |
46 | 22 |
|
47 | | - /** |
48 | | - Factor for the grammar described in the `expr` method |
49 | | - |
50 | | - Returns: Int value |
51 | | - */ |
52 | | - func factor() -> Int { |
53 | | - let token = currentToken |
54 | | - switch token { |
55 | | - case let .integer(value): |
56 | | - eatInteger() |
| 23 | + private func visit(_ node: AST) -> Int { |
| 24 | + switch node { |
| 25 | + case let .number(value): |
57 | 26 | return value |
58 | | - case .parenthesis(.left): |
59 | | - eatParenthesis(.left) |
60 | | - let result = expr() |
61 | | - eatParenthesis(.right) |
62 | | - return result |
63 | | - default: |
64 | | - fatalError("Syntax error") |
65 | | - } |
66 | | - } |
67 | | - |
68 | | - /** |
69 | | - Term for the grammar described in the `expr` method |
70 | | - |
71 | | - Returns: Int value |
72 | | - */ |
73 | | - func term() -> Int { |
74 | | - var result = factor() |
75 | | - |
76 | | - while [.operation(.mult), .operation(.div)].contains(currentToken) { |
77 | | - if currentToken == .operation(.mult) { |
78 | | - eatOperation(.mult) |
79 | | - result *= term() |
80 | | - } else if currentToken == .operation(.div) { |
81 | | - eatOperation(.div) |
82 | | - result /= term() |
| 27 | + case let .binaryOperation(left: left, operation: operation, right: right): |
| 28 | + switch operation { |
| 29 | + case .plus: |
| 30 | + return visit(left) + visit(right) |
| 31 | + case .minus: |
| 32 | + return visit(left) - visit(right) |
| 33 | + case .mult: |
| 34 | + return visit(left) * visit(right) |
| 35 | + case .div: |
| 36 | + return visit(left) / visit(right) |
83 | 37 | } |
84 | 38 | } |
85 | | - |
86 | | - return result |
87 | | - } |
88 | | - |
89 | | - /** |
90 | | - Arithmetic expression parser |
91 | | - |
92 | | - expr : term (PLUS | MINUS) term)* |
93 | | - term : factor ((MUL | DIV) factor)* |
94 | | - factor : INTEGER | LPAREN factor RPAREN |
95 | | - |
96 | | - Returns: Int value |
97 | | - */ |
98 | | - public func expr() -> Int { |
99 | | - |
100 | | - var result = term() |
101 | | - |
102 | | - while [.operation(.plus), .operation(.minus)].contains(currentToken) { |
103 | | - if currentToken == .operation(.plus) { |
104 | | - eatOperation(.plus) |
105 | | - result += term() |
106 | | - } else if currentToken == .operation(.minus) { |
107 | | - eatOperation(.minus) |
108 | | - result -= term() |
109 | | - } |
110 | | - } |
111 | | - |
112 | | - return result |
113 | 39 | } |
114 | 40 | } |
0 commit comments