Intrusive Expressing Printing
protocol Expression
{
func print(_ buffer: inout String)
}
class DoubleExpression: Expression
{
private var value: Double
init(_ value: Double)
{
self.value = value
}
func print(_ buffer: inout String)
{
buffer.append(String(value))
}
}
class AdditionExpression: Expression
{
private var left, right : Expression
init(_ left: Expression, _ right: Expression)
{
self.left = left
self.right = right
}
func print(_ buffer: inout String)
{
buffer.append("(")
left.print(&buffer)
buffer.append("+")
right.print(&buffer)
buffer.append(")")
}
}
func main()
{
// 1 + (2+3)
let e = AdditionExpression(DoubleExpression(1),
AdditionExpression(DoubleExpression(2),
DoubleExpression(3)))
var s = ""
e.print(&s)
print(s)
}
Reflection-Based Printing
class ExpressionPrinter
{
func print(_ e: Expression, _ s: inout String)
{
if let de = e as? DoubleExpression
{
s.append(String(de.value))
}
else if let ae = e as? AdditionExpression
{
s.append("(")
print(ae.left, &s)
s.append("+")
print(ae.right, &s)
s.append(")")
}
}
}
Classic Visitor (Double Dispatch)
protocol Expression
{
func accept(_ visitor: ExpressionVisitor)
func print(_ buffer: inout String)
}
class DoubleExpression: Expression
{
var value: Double
init(_ value: Double)
{
self.value = value
}
func print(_ buffer: inout String)
{
buffer.append(String(value))
}
func accept(_ visitor: ExpressionVisitor) {
visitor.visit(self)
}
}
class AdditionExpression: Expression
{
var left, right : Expression
init(_ left: Expression, _ right: Expression)
{
self.left = left
self.right = right
}
func print(_ buffer: inout String)
{
buffer.append("(")
left.print(&buffer)
buffer.append("+")
right.print(&buffer)
buffer.append(")")
}
func accept(_ visitor: ExpressionVisitor) {
visitor.visit(self)
}
}
protocol ExpressionVisitor
{
func visit(_ de: DoubleExpression)
func visit(_ ae: AdditionExpression)
}
class ExpressionPrinter: ExpressionVisitor, CustomStringConvertible
{
private var buffer = ""
func visit(_ de: DoubleExpression) {
buffer.append(String(de.value))
}
func visit(_ ae: AdditionExpression) {
buffer.append("(")
ae.left.accept(self)
buffer.append("+")
ae.right.accept(self)
buffer.append(")")
}
var description: String
{
return buffer
}
}
class ExpressionCalculator: ExpressionVisitor
{
var result = 0.0
func visit(_ de: DoubleExpression)
{
result = de.value
}
func visit(_ ae: AdditionExpression)
{
ae.left.accept(self)
let a = result
ae.right.accept(self)
let b = result
result = a + b
}
}
func main()
{
// 1 + (2+3)
let e = AdditionExpression(DoubleExpression(1),
AdditionExpression(DoubleExpression(2),
DoubleExpression(3)))
let ep = ExpressionPrinter()
ep.visit(e)
print(ep)
let calc = ExpressionCalculator()
calc.visit(e)
print("\(ep) = \(calc.result)")
}