initial
[prop.git] / prop-src / graphtype.pcc
blobb375e802d2cbe3121cb63d847ee953dfd0fe95fa
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // This file implements the graph type generator
4 //
5 ///////////////////////////////////////////////////////////////////////////////
7 #include "ast.ph"
8 #include "graphtype.ph"
9 #include "type.h"
11 ///////////////////////////////////////////////////////////////////////////////
13 //  Method to create a graph type definition.
15 ///////////////////////////////////////////////////////////////////////////////
16 GraphTypeDef::GraphTypeDef
17    (Id id, Inherits i, TyQual q, NodeDefs nodes, EdgeDefs edges, Decls b) 
18    : ClassDefinition(GRAPHTYPE_CLASS, id, #[],
19         add_inherit("GraphType",#[],i,PUBLICscope,QUALvirtualdestr), q, b), 
20      node_defs(nodes), edge_defs(edges)
21 {  add_type(id, #[], TYCONty(GRAPHtycon(this),#[])); }
23 GraphTypeDef::~GraphTypeDef() {}
25 ///////////////////////////////////////////////////////////////////////////////
27 //  Method to create a node type definition.
29 ///////////////////////////////////////////////////////////////////////////////
30 NodeDef::NodeDef(GraphTypeDef * g, Id id, Ty ty, 
31                  Id hash, Id eq, LabTys attribs)
32    : G(g), node_name(id), node_type(ty), hash_fun(hash), eq_fun(eq), 
33      attributes(attribs), rep(UNBASEDrep) 
34      {  if (hash_fun == 0) hash_fun = "hash";
35         if (eq_fun == 0) eq_fun = "equal";
36      }
37 NodeDef::~NodeDef() {}
39 ///////////////////////////////////////////////////////////////////////////////
41 //  Method to create an edge type definition.
43 ///////////////////////////////////////////////////////////////////////////////
44 EdgeDef::EdgeDef(GraphTypeDef * G,
45                  Id id, NodeDef* a, NodeDef* b, 
46                  GraphIndexing i, LabTys attribs)
47    : graph(G), edge_name(id), domain_type(a), range_type(b), indexing(i), 
48      attributes(attribs), ops(NOgop) 
49      {  
50      }
51 EdgeDef::~EdgeDef() {}
53 void GraphTypeDef::set_nodes(NodeDefs n) { node_defs = n; }
54 void GraphTypeDef::set_edges(EdgeDefs e) { edge_defs = e; }
55 void GraphTypeDef::set_body(Decls b) { class_body = b; }
57 ///////////////////////////////////////////////////////////////////////////////
59 //  Method to lookup a node definition by name
61 ///////////////////////////////////////////////////////////////////////////////
62 NodeDef * GraphTypeDef::lookup_node (Id id)
63 {  for_each (NodeDef *, n, node_defs)
64    {
65       if (n->node_name == id) return n;
66    }
67    error("%Lnode %s is not defined in graphtype %s\n", id, class_name); 
68    return 0;
71 ///////////////////////////////////////////////////////////////////////////////
73 //  Method to lookup an edge definition by name
75 ///////////////////////////////////////////////////////////////////////////////
76 EdgeDef * GraphTypeDef::lookup_edge (Id id)
77 {  for_each (EdgeDef *, e, edge_defs)
78    {
79       if (e->edge_name == id) return e;
80    }
81    error("%Ledge %s is not defined in graphtype %s\n", id, class_name); 
82    return 0;
85 ///////////////////////////////////////////////////////////////////////////////
87 //  Method to choose a representation for the graph type.
89 ///////////////////////////////////////////////////////////////////////////////
90 void GraphTypeDef::choose_representation()
91 {  for_each(EdgeDef *, e, edge_defs)
92        e->choose_representation();
93    for_each(NodeDef *, n, node_defs)
94        n->choose_representation();
97 ///////////////////////////////////////////////////////////////////////////////
99 //  Method to generate the graph type internals.
101 ///////////////////////////////////////////////////////////////////////////////
102 void GraphTypeDef::gen_class_predefinition (CodeGen& C)
104    choose_representation();
106    C.pr("%^%/"
107         "%^//"
108         "%^//  Internal representation of nodes in graphtype %s"
109         "%^//"
110         "%^%/",  
111         class_name);
113    ////////////////////////////////////////////////////////////////////////////
114    // 
115    //  Generate any forward declarations from the node definitions
116    //
117    ////////////////////////////////////////////////////////////////////////////
118    {  for_each(NodeDef *, n, node_defs)
119          n->generate_forward_decls(C);
120    }
122    ////////////////////////////////////////////////////////////////////////////
123    // 
124    //  Generate the representation for the nodes
125    //
126    ////////////////////////////////////////////////////////////////////////////
127    {  for_each(NodeDef *, n, node_defs)
128          n->generate_representation(C);
129    }
131    C.pr("%^%/"
132         "%^//"
133         "%^//  Definition of graphtype %s"
134         "%^//"
135         "%^%/",  
136         class_name);
139 ///////////////////////////////////////////////////////////////////////////////
141 //  Method to generate the interface methods 
143 ///////////////////////////////////////////////////////////////////////////////
144 void GraphTypeDef::gen_class_interface (CodeGen& C)
146    ////////////////////////////////////////////////////////////////////////////
147    //
148    //  Generate forward type definitions 
149    //
150    ////////////////////////////////////////////////////////////////////////////
151    {  C.pr("%-%^public:%+");
152       for_each(NodeDef *, n, node_defs)
153       {  C.pr("%^typedef %s_%s_node * %s;"
154               "%^class %s_set {"
155               "%^public:"
156               "%^   friend class %s_iterator;"
157               "%^   const GraphType::Link& link;"
158               "%^   long offset;"
159               "%^   %s_set(const GraphType::Link& l, long n = 0)"
160               "%^      : link(l), offset(n) {}"
161               "%^   Bool is_empty() const { return link.is_empty(); }"
162               "%^   operator Bool () const { return link.is_empty(); }"
163               "%^};"
164               "%^class %s_iterator {"
165               "%^   long offset;"
166               "%^   const GraphType::Link * cursor, * sentinel;"
167               "%^public:"
168               "%^   %s_iterator(const %s_set& s) : "
169               "%^      offset(s.offset), cursor(s.link.next),"
170               "%^          sentinel(&s.link) {}"
171               "%^   operator Bool () const { return cursor != sentinel; }"
172               "%^   %s operator * () const"
173               "%^       { return (%s)(((char *)cursor) - offset); }"
174               "%^   %s operator -> () const"
175               "%^       { return (%s)(((char *)cursor) - offset); }"
176               "%^   void operator ++ () { cursor = cursor->next; }"
177               "%^   void operator ++ (int) { cursor = cursor->next; }"
178               "%^};",
179               class_name, n->name(), n->name(), 
180               n->name(), n->name(),
181               n->name(), n->name(),
182               n->name(), n->name(),
183               n->name(), n->name(),
184               n->name(), n->name()
185              );
186       }
187    }
189    ////////////////////////////////////////////////////////////////////////////
190    // 
191    //  Generate the interface methods for the nodes
192    //
193    ////////////////////////////////////////////////////////////////////////////
194    {  for_each(NodeDef *, n, node_defs)
195          n->generate_interface(C);
196    }
198    ////////////////////////////////////////////////////////////////////////////
199    //  Generate the interface methods for the edges
200    ////////////////////////////////////////////////////////////////////////////
201    {  for_each(EdgeDef *, e, edge_defs)
202          e->generate_interface(C);
203    }
206 ///////////////////////////////////////////////////////////////////////////////
208 //  Method to generate the graph type implementation.
210 ///////////////////////////////////////////////////////////////////////////////
211 void GraphTypeDef::gen_class_implementation (CodeGen& C)
213    gen_init_graph(C);
214    gen_lookup_node(C);
215    gen_insert_node(C);
216    gen_remove_node(C);
219 void GraphTypeDef::gen_init_graph (CodeGen& C) {}
220 void GraphTypeDef::gen_lookup_node (CodeGen& C) {}
221 void GraphTypeDef::gen_insert_node (CodeGen& C) {}
222 void GraphTypeDef::gen_remove_node (CodeGen& C) {}