From 554d2ab14921c48d628b0ffa86cc7492836477ac Mon Sep 17 00:00:00 2001
From: Jed Barber <jjbarber@y7mail.com>
Date: Fri, 11 Jan 2019 14:23:49 +1100
Subject: Restructured Lexer combinators to use record return type

---
 src/packrat-lexer-combinators.adb | 160 +++++++++++++++-----------------------
 src/packrat-lexer-combinators.ads | 152 ++++++++++++++----------------------
 src/packrat-lexer.adb             |  58 ++++++++++++++
 src/packrat-lexer.ads             |  54 +++++++++++--
 src/packrat.ads                   |   2 +-
 5 files changed, 229 insertions(+), 197 deletions(-)
 create mode 100644 src/packrat-lexer.adb

diff --git a/src/packrat-lexer-combinators.adb b/src/packrat-lexer-combinators.adb
index 1d51262..7dccede 100644
--- a/src/packrat-lexer-combinators.adb
+++ b/src/packrat-lexer-combinators.adb
@@ -4,46 +4,38 @@ package body Packrat.Lexer.Combinators is
 
 
     function Sequence
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result is
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result is
     begin
-        return Failure;
+        return Fail_Result;
     end Sequence;
 
 
     function Count
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result is
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result is
     begin
-        return Failure;
+        return Fail_Result;
     end Count;
 
 
     function Many
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result is
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result is
     begin
-        return Failure;
+        return Fail_Result;
     end Many;
 
 
     function Many_Until
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result is
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result is
     begin
-        return Failure;
+        return Fail_Result;
     end Many_Until;
 
 
@@ -51,90 +43,74 @@ package body Packrat.Lexer.Combinators is
 
 
     function Satisfy
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result is
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result is
     begin
-        return Failure;
+        return Fail_Result;
     end Satisfy;
 
 
     function Satisfy_With
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result is
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result is
     begin
-        return Failure;
+        return Fail_Result;
     end Satisfy_With;
 
 
     function Match
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result is
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result is
     begin
-        return Failure;
+        return Fail_Result;
     end Match;
 
 
     function Match_With
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result is
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result is
     begin
-        return Failure;
+        return Fail_Result;
     end Match_With;
 
 
     function Multimatch
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result is
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result is
     begin
-        return Failure;
+        return Fail_Result;
     end Multimatch;
 
 
     function Take
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result is
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result is
     begin
-        return Failure;
+        return Fail_Result;
     end Take;
 
 
     function Take_While
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result is
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result is
     begin
-        return Failure;
+        return Fail_Result;
     end Take_While;
 
 
     function Take_Until
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result is
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result is
     begin
-        return Failure;
+        return Fail_Result;
     end Take_Until;
 
 
@@ -142,46 +118,38 @@ package body Packrat.Lexer.Combinators is
 
 
     function Line_Start
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result is
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result is
     begin
-        return Failure;
+        return Fail_Result;
     end Line_Start;
 
 
     function Line_End
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result is
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result is
     begin
-        return Failure;
+        return Fail_Result;
     end Line_End;
 
 
     function Input_Start
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result is
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result is
     begin
-        return Failure;
+        return Fail_Result;
     end Input_Start;
 
 
     function Input_End
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result is
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result is
     begin
-        return Failure;
+        return Fail_Result;
     end Input_End;
 
 
diff --git a/src/packrat-lexer-combinators.ads b/src/packrat-lexer-combinators.ads
index b346b0a..b690a63 100644
--- a/src/packrat-lexer-combinators.ads
+++ b/src/packrat-lexer-combinators.ads
@@ -7,59 +7,45 @@ package Packrat.Lexer.Combinators is
     generic
         Params : in Combinator_Array;
     function Sequence
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result;
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result;
 
     generic
         with function Param
-               (Input  : in     Element_Array;
-                Start  : in     Positive;
-                Length :    out Natural;
-                Value  :    out Element_Array)
-            return Result;
+               (Input : in Element_Array;
+                Start : in Positive)
+            return Combinator_Result;
         Number : in Positive;
     function Count
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result;
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result;
 
     generic
         with function Param
-               (Input  : in     Element_Array;
-                Start  : in     Positive;
-                Length :    out Natural;
-                Value  :    out Element_Array)
-            return Result;
+               (Input : in Element_Array;
+                Start : in Positive)
+            return Combinator_Result;
         Minimum : in Natural := 0;
     function Many
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result;
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result;
 
     generic
         with function Param
-               (Input  : in     Element_Array;
-                Start  : in     Positive;
-                Length :    out Natural;
-                Value  :    out Element_Array)
-            return Result;
+               (Input : in Element_Array;
+                Start : in Positive)
+            return Combinator_Result;
         with function Test
                (Item : in Element)
             return Boolean;
         Minimum : in Natural := 0;
     function Many_Until
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result;
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result;
 
 
 
@@ -69,11 +55,9 @@ package Packrat.Lexer.Combinators is
                (Item : in Element)
             return Boolean;
     function Satisfy
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result;
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result;
 
     generic
         with function Test
@@ -83,20 +67,16 @@ package Packrat.Lexer.Combinators is
                (From : in Element)
             return Element;
     function Satisfy_With
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result;
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result;
 
     generic
         Item : in Element;
     function Match
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result;
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result;
 
     generic
         Item : in Element;
@@ -104,51 +84,41 @@ package Packrat.Lexer.Combinators is
                (From : in Element)
             return Element;
     function Match_With
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result;
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result;
 
     generic
         Items : in Element_Array;
     function Multimatch
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result;
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result;
 
     generic
         Number : in Positive := 1;
     function Take
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result;
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result;
 
     generic
         with function Test
                (Item : in Element)
             return Boolean;
     function Take_While
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result;
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result;
 
     generic
         with function Test
                (Item : in Element)
             return Boolean;
     function Take_Until
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result;
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result;
 
 
 
@@ -156,36 +126,28 @@ package Packrat.Lexer.Combinators is
     generic
         EOL_Item : in Element;
     function Line_Start
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result;
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result;
 
     generic
         EOL_Item : in Element;
     function Line_End
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result;
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result;
 
     function Input_Start
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result;
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result;
 
     generic
         EOF_Item : in Element;
     function Input_End
-           (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result;
+           (Input : in Element_Array;
+            Start : in Positive)
+        return Combinator_Result;
 
 
 end Packrat.Lexer.Combinators;
diff --git a/src/packrat-lexer.adb b/src/packrat-lexer.adb
new file mode 100644
index 0000000..f93b65b
--- /dev/null
+++ b/src/packrat-lexer.adb
@@ -0,0 +1,58 @@
+
+
+package body Packrat.Lexer is
+
+
+    procedure Initialize
+           (This : in out Combinator_Result) is
+    begin
+        null;
+    end Initialize;
+
+
+    procedure Adjust
+           (This : in out Combinator_Result) is
+    begin
+        null;
+    end Adjust;
+
+
+    procedure Finalize
+           (This : in out Combinator_Result) is
+    begin
+        null;
+    end Finalize;
+
+
+
+
+
+    function Create_Result
+           (Length : in Natural;
+            Status : in Result_Status;
+            Value  : in Element_Array)
+        return Combinator_Result is
+    begin
+        return Fail_Result;
+    end Create_Result;
+
+
+    function Join
+           (Left, Right : in Combinator_Result)
+        return Combinator_Result is
+    begin
+        return Fail_Result;
+    end Join;
+
+
+    function Is_Failure
+           (This : in Combinator_Result)
+        return Boolean is
+    begin
+        return True;
+    end Is_Failure;
+
+
+end Packrat.Lexer;
+
+
diff --git a/src/packrat-lexer.ads b/src/packrat-lexer.ads
index 611a407..81c9d2a 100644
--- a/src/packrat-lexer.ads
+++ b/src/packrat-lexer.ads
@@ -11,20 +11,64 @@ generic
 package Packrat.Lexer is
 
 
+    type Combinator_Result is private;
+
     type Combinator is access function
            (Input  : in     Element_Array;
-            Start  : in     Positive;
-            Length :    out Natural;
-            Value  :    out Element_Array)
-        return Result;
-
+            Start  : in     Positive)
+        return Combinator_Result;
 
     type Combinator_Array is array (Positive range <>) of Combinator;
 
 
+    Fail_Result : constant Combinator_Result;
+
+
+    function Create_Result
+           (Length : in Natural;
+            Status : in Result_Status;
+            Value  : in Element_Array)
+        return Combinator_Result;
+
+    function Join
+           (Left, Right : in Combinator_Result)
+        return Combinator_Result;
+
+    function Is_Failure
+           (This : in Combinator_Result)
+        return Boolean;
+
+
 private
 
 
+    type Element_Array_Access is access Element_Array;
+
+
+    type Combinator_Result is new Ada.Finalization.Controlled with record
+        Length : Natural;
+        Status : Result_Status;
+        Value  : Element_Array_Access;
+    end record;
+
+
+    overriding procedure Initialize
+           (This : in out Combinator_Result);
+
+    overriding procedure Adjust
+           (This : in out Combinator_Result);
+
+    overriding procedure Finalize
+           (This : in out Combinator_Result);
+
+
+    Fail_Result : constant Combinator_Result :=
+       (Ada.Finalization.Controlled with
+        Length => 0,
+        Status => Failure,
+        Value  => null);
+
+
 end Packrat.Lexer;
 
 
diff --git a/src/packrat.ads b/src/packrat.ads
index 467c463..41035fc 100644
--- a/src/packrat.ads
+++ b/src/packrat.ads
@@ -9,7 +9,7 @@ with
 package Packrat is
 
 
-    type Result is (Failure, Partial, Success);
+    type Result_Status is (Failure, Partial, Success);
 
 
     Parser_Error : exception;
-- 
cgit