diff options
Diffstat (limited to 'src/packrat-lexer.adb')
-rw-r--r-- | src/packrat-lexer.adb | 91 |
1 files changed, 81 insertions, 10 deletions
diff --git a/src/packrat-lexer.adb b/src/packrat-lexer.adb index f93b65b..0b0f571 100644 --- a/src/packrat-lexer.adb +++ b/src/packrat-lexer.adb @@ -1,8 +1,17 @@ +with + + Ada.Unchecked_Deallocation; + + package body Packrat.Lexer is + procedure Free_Array is new Ada.Unchecked_Deallocation + (Object => Element_Array, Name => Element_Array_Access); + + procedure Initialize (This : in out Combinator_Result) is begin @@ -13,14 +22,24 @@ package body Packrat.Lexer is procedure Adjust (This : in out Combinator_Result) is begin - null; + if This.Value /= null then + declare + New_Array : Element_Array_Access := + new Element_Array (1 .. This.Value.all'Length); + begin + New_Array.all := This.Value.all; + This.Value := New_Array; + end; + end if; end Adjust; procedure Finalize (This : in out Combinator_Result) is begin - null; + if This.Value /= null then + Free_Array (This.Value); + end if; end Finalize; @@ -31,26 +50,78 @@ package body Packrat.Lexer is (Length : in Natural; Status : in Result_Status; Value : in Element_Array) - return Combinator_Result is + return Combinator_Result + is + This : Combinator_Result; begin - return Fail_Result; + This.Length := Length; + This.Status := Status; + This.Value := new Element_Array (1 .. Value'Length); + This.Value.all := Value; + return This; end Create_Result; function Join (Left, Right : in Combinator_Result) - return Combinator_Result is + return Combinator_Result + is + Merge : Combinator_Result; + Left_Valsize, Right_Valsize, Total_Valsize : Natural; begin - return Fail_Result; + if Left.Value /= null then + Left_Valsize := Left.Value.all'Length; + else + Left_Valsize := 0; + end if; + if Right.Value /= null then + Right_Valsize := Right.Value.all'Length; + else + Right_Valsize := 0; + end if; + Total_Valsize := Left_Valsize + Right_Valsize; + + if Left.Status = Success then + Merge.Length := Left.Length + Right.Length; + Merge.Status := Right.Status; + if Total_Valsize /= 0 or Right.Status /= Failure then + Merge.Value := new Element_Array (1 .. Total_Valsize); + if Left_Valsize /= 0 then + Merge.Value.all (1 .. Left_Valsize) := Left.Value.all; + end if; + if Right_Valsize /= 0 then + Merge.Value.all (Left_Valsize + 1 .. Total_Valsize) := Right.Value.all; + end if; + end if; + return Merge; + else + return Left; + end if; end Join; - function Is_Failure + function "=" + (Left, Right : in Combinator_Result) + return Boolean + is + Null_Check : Boolean := + Left.Value = null and Right.Value = null; + Value_Check : Boolean := + Left.Value /= null and then Right.Value /= null and then + Left.Value.all = Right.Value.all; + begin + return Left.Length = Right.Length and + Left.Status = Right.Status and + (Null_Check or Value_Check); + end "="; + + + function Status (This : in Combinator_Result) - return Boolean is + return Result_Status is begin - return True; - end Is_Failure; + return This.Status; + end Status; end Packrat.Lexer; |