Visitor pattern: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
(Add Python)
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(3 intermediate revisions by 2 users not shown)
Line 83:
</syntaxhighlight>{{out}} Same as Phix entry.
 
=={{header|Nim}}==
This is a translation of the Wikipedia C# example.
 
Note that Nim has no notion of “class” but only object types which allow simple inheritance. But it provides a way to define methods with dynamic dispatch and allows procedure overloading. So the translation of the C# example is easy.
<syntaxhighlight lang="Nim">import std/strutils
 
type
 
ExpressionPrintingVisitor = object
 
Expression = ref object of RootObj
 
Literal = ref object of Expression
value: float
 
Addition = ref object of Expression
left, right: Expression
 
 
# Expression procedures and methods.
 
method accept(e: Expression; v: ExpressionPrintingVisitor) {.base.} =
raise newException(CatchableError, "Method without implementation override")
 
method getValue(e: Expression): float {.base.} =
raise newException(CatchableError, "Method without implementation override")
 
 
# ExpressionPrintingVisitor procedures.
 
proc printLiteral(v: ExpressionPrintingVisitor; literal: Literal) =
echo literal.value
 
proc printAddition(v: ExpressionPrintingVisitor; addition: Addition) =
let leftValue = addition.left.getValue()
let rightValue = addition.right.getValue()
let sum = addition.getValue()
echo "$1 + $2 = $3".format(leftValue, rightValue, sum)
 
 
# Literal procedure and methods.
proc newLiteral(value: float): Literal =
Literal(value: value)
 
method accept(lit: Literal; v: ExpressionPrintingVisitor) =
v.printLiteral(lit)
 
method getValue(lit: Literal): float = lit.value
 
 
# Addition procedure and methods.
proc newAddition(left, right: Expression): Addition =
Addition(left: left, right: right)
 
method accept(a: Addition; v: ExpressionPrintingVisitor) =
a.left.accept(v)
a.right.accept(v)
v.printAddition(a)
 
method getValue(a: Addition): float =
a.left.getValue() + a.right.getValue()
 
 
proc main() =
# Emulate 1 + 2 + 3.
let e = newAddition(
newAddition(newLiteral(1), newLiteral(2)),
newLiteral(3))
var printingVisitor: ExpressionPrintingVisitor
e.accept(printingVisitor)
 
main()
</syntaxhighlight>
 
{{out}}
<pre>1.0
2.0
1.0 + 2.0 = 3.0
3.0
3.0 + 3.0 = 6.0</pre>
 
=={{header|Phix}}==
Line 186 ⟶ 266:
 
=={{header|Python}}==
 
This is based on the [[wp:Visitor_pattern|Wikipedia]] Python example, but uses structural pattern matching instead of multiple visit methods.
 
<syntaxhighlight lang="python">
Line 385 ⟶ 467:
===Translation of C# example===
As is often the case in practice, the following example departs somewhat from the typical operation of the pattern described above. There is no abstract Visitor class - only a concrete Visitor class - and the 'visit' methods are called something else.
<syntaxhighlight lang="ecmascriptwren">class ExpressionPrintingVisitor {
construct new(){}
 
Line 458 ⟶ 540:
{{libheader|Wren-str}}
Note that Wren is dynamically typed and can only overload methods based on arity and not on argument type. In the following example, rather than having separate methods for each element type, we instead have a single 'visit' method which tests the type of the argument at run time and takes the appropriate action.
<syntaxhighlight lang="ecmascriptwren">import "./str" for Str
 
// abstract class
9,476

edits