From: | cliffc@ami.sps.mot.com (Cliff Click) |
Newsgroups: | comp.compilers |
Date: | 30 Jun 1996 16:29:11 -0400 |
Organization: | Compilers Central |
References: | 96-06-047 96-06-064 96-06-117 |
Keywords: | OOP |
bobduff@world.std.com (Robert A Duff) writes:
How is the Visitor pattern any different from the "old fashioned"
(non-OO) way of writing a compiler (or any other program, for that
matter)? That is, define a bunch of variant records to represent the
abstract syntax tree, and write several procedures that do various
things, like Do_Semantic_Analysis, Optimize, Generate_Code, etc -- each
procedure has a giant case statement based on the tag field of the
current tree node.
That is, it seems to me that when you choose to use the Visitor pattern,
you're basically saying that the OOP way is inappropriate in that
particular case. The OOP way organizes keeps classes together, and
scatters the operations all over; the "old fashioned" way keeps each
operation together in one place, as does the Visitor pattern. The "old
fashioned" way requires that the fields of each node type be visible to
the operations, or else accessor functions are needed -- just like the
Visitor pattern.
I do a lot of OOP work in my compiler. I'm interested in optimizers,
not scanners, so I work with 3-address-code instructions, DAGs and cycles
(and not trees). I "slice" the problem by opcode type: each opcode is
it's own class. Each opcode-class defines functions with semantic
meaning; these functions are used by optimizations like Common Subexpression
Elimination (CSE).
I use several different CSE algorithms. For convenience I might lump
a CSE phase together into an object, but there will be only one such
object running around at a time (i.e., CSE-as-an-object isn't very
object oriented). Inside CSE I'll use virtual function calls on the
object-classes instead of a giant switch statement.
This organization lets me add new opcode types quickly with inherited
default behavior, then lets me add functionality incrementally to
improve optimization. Example: I add a new opcode 'power' to replace
calls to some math library function (ignore language binding issues
for the moment: the user has asked for optimization and wants the
compiler to bind some functions at compile time if it improves
performance). Power's default behavior is to always claim it produces a
new result. Later I can make 'power' understand that x^1 is x. This
will help all my CSE implementations without me touching any CSE code.
Cliff
--
Cliff Click, Ph.D. Compiler Researcher & Designer
RISC Software, Motorola PowerPC Compilers
cliffc@risc.sps.mot.com (512) 891-7240
http://members.aol.com/mjclick1
--
Return to the
comp.compilers page.
Search the
comp.compilers archives again.