From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,87077e61d6b3095b,start X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-12-17 10:26:54 PST Path: archiver1.google.com!news1.google.com!sn-xit-02!sn-xit-01!sn-post-02!sn-post-01!supernews.com!corp.supernews.com!not-for-mail From: cl1motorsports Newsgroups: comp.lang.ada Subject: how do i implement double-dispatching? Date: Wed, 17 Dec 2003 12:08:41 -0600 Organization: Posted via Supernews, http://www.supernews.com Message-Id: User-Agent: Pan/0.14.2 (This is not a psychotic episode. It's a cleansing moment of clarity. (Debian GNU/Linux)) MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit X-Complaints-To: abuse@supernews.com Xref: archiver1.google.com comp.lang.ada:3510 Date: 2003-12-17T12:08:41-06:00 List-Id: I'm trying to implement double dispatching with a visitor pattern in (of course) Ada. I have a parse tree package that has all the node types of the tree, and i have a visitor package with an abstract visitor type that has a Visit operation for all the types in the parse tree. It doesn't want to compile the way i have it written. I have provided a shortened version of the parse tree and abstract visitor code with gnatmake errors below. If anyone has a solution to this please point me in the correct direction. My purpose here is to implement a framework for pretty-printers, html-izers, language translators (e.g c2ada) all from the same parse tree without having to recompile the parse tree. basically the framework user will create a new type that inherits from the abstract visitor type to insure that operations for each type of node in the parse tree are implemented. Just thought i would give some background info on the code so you would know why i tried to implement it like this and so you could give a solution within the domain. well enough ranting, On to the Code!!! -- parse_tree_pkg.ads with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; package Parse_Tree_Pkg is -- abstract parse tree node type Parse_Tree_Node_Record is abstract tagged record Start_Line : Integer; Start_Column : Integer; End_Line : Integer; End_Column : Integer; end record; type Parse_Tree_Node is access Parse_Tree_Node_Record'Class; -- actual(concrete) parse tree nodes type Equal_Op is new Parse_Tree_Node_Record with null record; type Number_Node is new Parse_Tree_Node_Record with record Value : Float; end record; type Name_Node is new Parse_Tree_Node_Record with record Value : Unbounded_String; end record; type Assignment_Node is new Parse_Tree_Node_Record with record Name : Parse_Tree_Node; Equal : Parse_Tree_Node; Expression : Parse_Tree_Node; end record; end Parse_Tree_Pkg; -- abstract_visitor.ads with Parse_Tree_Pkg; use Parse_Tree_Pkg; package Abstract_Visitor is -- This package provides a visitor interface -- so that operations can be created independant -- of the parse tree. -- If you want to implement a visitor to run -- operations on the parse tree you must "with" this -- package and create all the visit operations in -- it. type Visitor_Record is abstract tagged null record; type Visitor_Access is access Visitor_Record'Class; procedure Visit(V : in out Visitor_Record; Node : in Equal_Op) is abstract; procedure Visit(V : in out Visitor_Record; Node : in Number_Node) is abstract; procedure Visit(V : in out Visitor_Record; Node : in Name_Node) is abstract; procedure Visit(V : in out Visitor_Record; Node : in Assignment_Node) is abstract; procedure Accept_Visitor(V : in out Visitor_Record'Class; Node : in Parse_Tree_Node_Record'Class); end Abstract_Visitor; -- abstract_visitor.adb package body Abstract_Visitor is procedure Accept_Visitor(V : in out Visitor_Record'Class; Node : in Parse_Tree_Node_Record'Class) is begin Visit(V, Node); end Accept_Visitor; end Abstract_Visitor; -- END OF CODE and here are the errors from running gnatmake: $ gnatmake abstract_visitor gcc -c abstract_visitor.adb abstract_visitor.adb:5:07: invalid parameter list in call (use -gnatf for details) gnatmake: "abstract_visitor.adb" compilation error $ gnatmake -gnatf abstract_visitor gcc -c -gnatf abstract_visitor.adb abstract_visitor.adb:5:07: no candidate interpretations match the actuals: abstract_visitor.adb:5:16: expected type "Assignment_Node" defined at parse_tree_pkg.ads:28 abstract_visitor.adb:5:16: found type "Parse_Tree_Node_Record'Class" defined at parse_tree_pkg.ads:5 abstract_visitor.adb:5:16: ==> in call to "Visit" at abstract_visitor.ads:24 abstract_visitor.adb:5:16: ==> in call to "Visit" at abstract_visitor.ads:21 abstract_visitor.adb:5:16: ==> in call to "Visit" at abstract_visitor.ads:20 abstract_visitor.adb:5:16: ==> in call to "Visit" at abstract_visitor.ads:17 gnatmake: "abstract_visitor.adb" compilation error $ this has been really frustrating :/ oh and this is my first post ever to a newsgroup so be gentle :) Thanks in Advance, Charles