@@ -664,7 +664,7 @@ Let's now consider :class:`Terminal`. What does it need to set?
664
664
:meth: `~object.__init__ `
665
665
The :term: `constructor ` for :class: `Expression ` assumes that an expression is
666
666
defined by a series of operands. Terminals have an empty list of operands
667
- but do have something that other expressions lack, a value. In the case of
667
+ but do have something that other expressions lack: a value. In the case of
668
668
:class: `Number `, this is a number, while for :class: `Symbol ` the value is a
669
669
string (usually a single character). :class: `Terminal ` therefore needs its
670
670
own :meth: `__init__ ` which will take a value argument.
@@ -719,6 +719,24 @@ long as the right number of arguments are passed). A single dispatch function is
719
719
not like this. Instead, calling a single function name causes different function
720
720
code to execute, depending on the type of the first argument [#single ]_.
721
721
722
+ :numref: `tree_evaluate ` shows a single dispatch function for a visitor function
723
+ which evaluates a :class: `Expression `. Start with lines 6-24. These define a
724
+ function :func: `~example_code.expression_tools.evaluate ` which will be used in
725
+ the default case, that is, in the case where the :class: `type ` of the first
726
+ argument doesn't match any of the other implementations of
727
+ :func: `~example_code.expression_tools.evaluate `. In this case, the first
728
+ argument is the expression that we're evaluating, so if the type doesn't match
729
+ then this means that we don't know how to evaluate this object, and the only
730
+ course of action available is to throw an :term: `exception `.
731
+
732
+ The new feature that we haven't met before appears on line 5.
733
+ :func: `functools.singledispatch ` turns a function into
734
+ a single dispatch function. The `@ ` symbol marks
735
+ :func: `~functools.singledispatch ` as a :term: `decorator `. We'll return to them
736
+ in :numref: `decorators `. For the moment, we just need to know that
737
+ `@singledispatch ` turns the function it precedes into a single dispatch
738
+ function.
739
+
722
740
.. _tree_evaluate :
723
741
724
742
.. code-block :: python3
@@ -743,7 +761,8 @@ code to execute, depending on the type of the first argument [#single]_.
743
761
*o: numbers.Number
744
762
The results of evaluating the operands of expr.
745
763
**kwargs:
746
- Any keyword arguments required to evaluate specific types of expression.
764
+ Any keyword arguments required to evaluate specific types of
765
+ expression.
747
766
symbol_map: dict
748
767
A dictionary mapping Symbol names to numerical values, for example:
749
768
@@ -787,46 +806,28 @@ code to execute, depending on the type of the first argument [#single]_.
787
806
def _(expr, *o, **kwargs):
788
807
return o[0] ** o[1]
789
808
790
- :numref: `tree_evaluate ` shows a single dispatch function for a visitor function
791
- which evaluates a :class: `Expression `. Start with lines 6-19. These define a
792
- function :func: `~example_code.expression_tools.evaluate ` which will be used in
793
- the default case, that is, in the case where the :class: `type ` of the first
794
- argument doesn't match any of the other implementations of
795
- :func: `~example_code.expression_tools.evaluate `. In this case, the first
796
- argument is the expression that we're evaluating, so if the type doesn't match
797
- then this means that we don't know how to evaluate this object, and the only
798
- course of action available is to throw an :term: `exception `.
799
-
800
- The new feature that we haven't met before appears on line 5.
801
- :func: `functools.singledispatch ` turns a function into
802
- a single dispatch function. The `@ ` symbol marks
803
- :func: `~functools.singledispatch ` as a :term: `decorator `. We'll return to them
804
- in :numref: `decorators `. For the moment, we just need to know that
805
- `@singledispatch ` turns the function it precedes into a single dispatch
806
- function.
807
-
808
809
Next we turn our attention to the implementation of evaluation for the different
809
- expression types. Look first at lines 26-28 , which provide the evaluation of
810
+ expression types. Look first at lines 27-29 , which provide the evaluation of
810
811
:class: `Number ` nodes. The function body is trivial: the evaluation of a
811
812
:class: `Number ` is simply its value. The function interface is more interesting.
812
813
Notice that the function name is given as `_ `. This is the Python convention for
813
814
a name which will never be used. This function will never be called by its
814
- declared name. Instead, look at the decorator on line 26 . The single dispatch
815
+ declared name. Instead, look at the decorator on line 27 . The single dispatch
815
816
function :func: `~example_code.expression_tools.evaluate ` has a :term: `method `
816
817
:meth: `register `. When used as a decorator, the :meth: `register ` method of a
817
818
single dispatch function registers the function that follows as implementation
818
819
for the :keyword: `class ` given as an argument to :meth: `register `. On this
819
820
occasion, this is :class: `expressions.Number `.
820
821
821
- Now look at lines 31-33 . These contain the implementation of
822
+ Now look at lines 32-34 . These contain the implementation of
822
823
:func: `~example_code.expression_tools.evaluate ` for :class: `expressions.Symbol `.
823
824
In order to evaluate a symbol, we depend on the mapping from symbol names to
824
825
numerical values that has been passed in.
825
826
826
- Finally, look at lines 36-38 . These define the evaluation visitor for addition.
827
+ Finally, look at lines 37-39 . These define the evaluation visitor for addition.
827
828
This works simply by adding the results of evaluating the two operands of
828
- :class: `expressions.Add `. The evaluation visitors for the other operators follow
829
- * mutatis mutandis * .
829
+ :class: `expressions.Add `. The evaluation visitors for the other operators
830
+ follow in an analogous manner .
830
831
831
832
An expanded tree visitor
832
833
~~~~~~~~~~~~~~~~~~~~~~~~
0 commit comments