summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/packrat-graphs.adb104
-rw-r--r--src/packrat-graphs.ads4
2 files changed, 102 insertions, 6 deletions
diff --git a/src/packrat-graphs.adb b/src/packrat-graphs.adb
index 1cc21b3..f32c628 100644
--- a/src/packrat-graphs.adb
+++ b/src/packrat-graphs.adb
@@ -97,6 +97,14 @@ package body Packrat.Graphs is
+ function Is_Nothing
+ (This : in Node)
+ return Boolean is
+ begin
+ return This.Kind = Null_Node;
+ end Is_Nothing;
+
+
function Is_Leaf
(This : in Node)
return Boolean is
@@ -825,19 +833,103 @@ package body Packrat.Graphs is
- procedure Append
+ procedure Add_Nodes
(Container : in out Graph;
- Addition : in Graph) is
+ Addition : in Node_Vectors.Vector;
+ Mapping : out Index_Maps.Map) is
+ begin
+ Mapping := Index_Maps.Empty_Map;
+ for C in Addition.Iterate loop
+ Mapping.Insert (Node_Vectors.To_Index (C), Container.Add_Place);
+ if Container.Add_Place > Container.Node_List.Last_Index then
+ Container.Node_List.Append (Node_Vectors.Element (C));
+ else
+ Container.Node_List.Replace_Element (Container.Add_Place, Node_Vectors.Element (C));
+ end if;
+ while Container.Add_Place <= Container.Node_List.Last_Index and then
+ not Is_Nothing (Container.Node_List.Element (Container.Add_Place))
+ loop
+ Container.Add_Place := Container.Add_Place + 1;
+ end loop;
+ end loop;
+ end Add_Nodes;
+
+
+ procedure Add_Edges
+ (Container : in out Graph;
+ Addition : in Graph;
+ Mapping : in Index_Maps.Map)
+ is
+ Targets : Index_Vectors.Vector := Index_Vectors.Empty_Vector;
begin
- null;
+ -- Up edges
+ for E in Addition.Up_Edges.Iterate loop
+ Targets.Clear;
+ for T of Edge_Up_Maps.Element (E) loop
+ Targets.Append (Mapping.Element (T));
+ end loop;
+ Container.Up_Edges.Insert
+ (Mapping.Element (Edge_Up_Maps.Key (E)), Targets);
+ end loop;
+
+ -- Down edges
+ for E in Addition.Down_Edges.Iterate loop
+ Targets.Clear;
+ for T of Edge_Down_Maps.Element (E) loop
+ Targets.Append (Mapping.Element (T));
+ end loop;
+ Container.Down_Edges.Insert
+ ((Mapping.Element (Edge_Down_Maps.Key (E).From), Edge_Down_Maps.Key (E).Choice),
+ Targets);
+ end loop;
+
+ -- Choices
+ for C in Addition.Choices.Iterate loop
+ Container.Choices.Insert
+ (Mapping.Element (Choice_Maps.Key (C)), Choice_Maps.Element (C));
+ end loop;
+ end Add_Edges;
+
+
+ procedure Append
+ (Container : in out Graph;
+ Addition : in Graph)
+ is
+ Mapping : Index_Maps.Map;
+ begin
+ -- Add the nodes and edges from the addition to the graph,
+ -- making sure to handle the conversion of the index each node
+ -- is stored at. If index conversion wasn't required this bit would
+ -- be much simpler.
+ Add_Nodes (Container, Addition.Node_List, Mapping);
+ Add_Edges (Container, Addition, Mapping);
+
+ -- Append the root list of the addition to the graph
+ for R of Addition.Root_List loop
+ Container.Root_List.Append (Mapping.Element (R));
+ end loop;
end Append;
procedure Prepend
(Container : in out Graph;
- Addition : in Graph) is
- begin
- null;
+ Addition : in Graph)
+ is
+ Mapping : Index_Maps.Map;
+ Converted_Roots : Index_Vectors.Vector := Index_Vectors.Empty_Vector;
+ begin
+ -- Add the nodes and edges from the addition to the graph,
+ -- making sure to handle the conversion of the index each node
+ -- is stored at. If index conversion wasn't required this bit would
+ -- be much simpler.
+ Add_Nodes (Container, Addition.Node_List, Mapping);
+ Add_Edges (Container, Addition, Mapping);
+
+ -- Prepend the root list of the addition to the graph
+ for R of Addition.Root_List loop
+ Converted_Roots.Append (Mapping.Element (R));
+ end loop;
+ Container.Root_List.Prepend (Converted_Roots);
end Prepend;
diff --git a/src/packrat-graphs.ads b/src/packrat-graphs.ads
index 76be2e4..5074485 100644
--- a/src/packrat-graphs.ads
+++ b/src/packrat-graphs.ads
@@ -469,6 +469,10 @@ private
(Index_Type => Positive,
Element_Type => Node_Index);
+ package Index_Maps is new Ada.Containers.Ordered_Maps
+ (Key_Type => Node_Index,
+ Element_Type => Node_Index);
+