Im trying to develop a way to construct an arithmetic and logical expressions, and perform operations on them. For the structure I am using the composite pattern, and for the operations I am using the visitor pattern.
I am a little confused on the implementation of the concrete visitor class.
Here is how I currently do it:
My ADDITION class:
class
ADDITION
inherit
BINARY
create
make
feature -- ctor
make (left : EXPRESSION ; right : EXPRESSION)
do
left_expression := left
right_expression := right
end
feature -- deferred implementation
evaluate : INTEGER
do
Result := left_expression.evaluate + right_expression.evaluate
end
to_string : STRING
do
create Result.make_empty
end
accept (v : VISITOR)
do
v.visit_addition (Current)
end
end
Now for the visitor pattern, here is a concrete visitor that is supposed to evaluated the given expression (I also want a concrete visitor that does type checking, pretty printing, etc.).
class
EVALUATE_VISITOR
inherit
VISITOR
create
make
feature -- attribs
value : INTEGER
value_bool : BOOLEAN
feature -- ctor
make
do
end
feature
visit_addition (expression : ADDITION)
do
value := expression.left_expression.evaluate +
expression.right_expression.evaluate
end
end
My question is, doesnt having the evaluate method in each of my structures (ADDITION, SUBTRACTION, NEGATION, etc.) defeat the purpose of the visitor pattern, since all the evaluation should be done in the visitor class? How do I implement it in the visitor class then? I was thinking I could do something like:
visit_addition (expression : ADDITION)
do
value := expression.left_expression.accept(Current) +
expression.right_expression.accept(Current)
end
but then I would have to have many accept methods in my structures, for arithmetic expressions it would have to return INTEGER, and for logical operations it would have to return BOOLEAN.
Actually the way to do this would be the following:
visit_addition (expression: ADDITION)
local
l_left_value, l_right_value: INTEGER
do
expression.left_expression.accept (Current)
l_left_value := last_value
expression.right_expression.accept (Current)
l_right_value := last_value
last_value := l_left_value + l_right_value
end
This is in a visitor that computes additions of INTEGERs. The `last_value' attribute is defined in your visitor class.
To answer your other question, in the ADDITION class you do not need `evaluate'.