how do i implement double-dispatching?

From: cl1motorsports (cwlambert76_at_yahoo.com)
Date: 12/17/03


Date: Wed, 17 Dec 2003 12:08:41 -0600

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



Relevant Pages

  • Re: how do i implement double-dispatching?
    ... I have a parse tree package that has all the node types of ... > has a Visit operation for all the types in the parse tree. ... > of the parse tree and abstract visitor code with gnatmake errors below. ... Note that there is a choice, you can make Visit dispatching in the Node ...
    (comp.lang.ada)
  • Re: how do i implement double-dispatching?
    ... >> Okay. ... now it works when the Visitor type, ... >> what is my scope issue with being in the same package that doesn't apply ... visit or a parse tree with no visitor to run operations on it. ...
    (comp.lang.ada)
  • Re: how do i implement double-dispatching?
    ... cl1motorsports writes: ... > Accept_Visitorprocedure is in a separate package from the parse tree. ...
    (comp.lang.ada)
  • Re: How to extend packages
    ... package System.Regpat.Extended is ... $ gnatmake s-regext.ads ... compile file with "-gnatg" switch ... When trying the -a switch: ...
    (comp.lang.ada)
  • Re: GdMs DOS 3d engine in Ada
    ... gnatmake: "demos.adb" compilation error ... E.g. package "UnZip.Decompress.Huffman" has the file name "undechuf.ads". ... Just this option was default in all previous GNAT for DOS versions, and I had to make it explicit. ...
    (comp.os.msdos.djgpp)