1
1
mirror of https://github.com/kanaka/mal.git synced 2024-09-21 10:37:58 +03:00
mal/ada/types.adb

167 lines
4.7 KiB
Ada
Raw Normal View History

2015-03-15 22:56:09 +03:00
with Ada.Characters.Latin_1;
with Ada.Text_IO;
2015-03-19 00:12:54 +03:00
with Ada.Unchecked_Deallocation;
2015-03-15 22:56:09 +03:00
package body Types is
package ACL renames Ada.Characters.Latin_1;
2015-03-17 01:48:48 +03:00
2015-03-23 01:37:42 +03:00
-- Smart Pointers section.
overriding procedure Adjust (Object : in out Smart_Pointer) is
begin
if Object.Pointer /= null then
Object.Pointer.Ref_Count := Object.Pointer.Ref_Count + 1;
end if;
end Adjust;
procedure Free is
new Ada.Unchecked_Deallocation (Mal_Type, Mal_Type_Accessor);
overriding procedure Finalize (Object : in out Smart_Pointer) is
begin
if Object.Pointer /= null then
Object.Pointer.Ref_Count := Object.Pointer.Ref_Count - 1;
if Object.Pointer.Ref_Count = 0 then
Free (Object.Pointer);
end if;
end if;
end Finalize;
function New_Ptr (Mal_Type : Mal_Type_Accessor) return Smart_Pointer is
begin
return Smart_Pointer'
(Ada.Finalization.Controlled with Pointer => Mal_Type);
end New_Ptr;
function Deref (Ptr : Smart_Pointer) return Mal_Type_Accessor is
begin
return Ptr.Pointer;
end Deref;
2015-03-17 01:48:48 +03:00
function Opening (LT : List_Types) return Character is
Res : Character;
begin
case LT is
when List_List =>
Res := '(';
when Vector_List =>
Res := '[';
when Hashed_List =>
Res := '{';
end case;
return Res;
end Opening;
function Closing (LT : List_Types) return Character is
Res : Character;
begin
case LT is
when List_List =>
Res := ')';
when Vector_List =>
Res := ']';
when Hashed_List =>
Res := '}';
end case;
return Res;
end Closing;
function Mal_Type_To_String (T : Mal_Type) return String is
2015-03-15 22:56:09 +03:00
use Ada.Strings.Unbounded;
begin
case T.Sym_Type is
when Int =>
declare
Res : String := Mal_Integer'Image (T.Int_Val);
2015-03-15 22:56:09 +03:00
begin
if Res (1) = ' ' then
return Res (2..Res'Last);
else
2015-03-17 01:48:48 +03:00
return Res;
end if;
end;
when Floating =>
declare
Res : String := Mal_Float'Image (T.Float_Val);
2015-03-17 01:48:48 +03:00
begin
if Res (1) = ' ' then
return Res (2..Res'Last);
else
return Res;
2015-03-15 22:56:09 +03:00
end if;
end;
when List =>
declare
UBS : Unbounded_String := Null_Unbounded_String;
C : Lists.Cursor;
use type Lists.Cursor;
First_Pass : Boolean := True;
begin
2015-03-17 01:48:48 +03:00
2015-03-15 22:56:09 +03:00
if Lists.Is_Empty (T.The_List) then
2015-03-17 01:48:48 +03:00
return Opening (T.List_Type) & Closing (T.List_Type);
2015-03-15 22:56:09 +03:00
end if;
2015-03-17 01:48:48 +03:00
2015-03-15 22:56:09 +03:00
C := Lists.First (T.The_List);
loop
if First_Pass then
First_Pass := False;
else
Append (UBS, " ");
end if;
2015-03-23 01:37:42 +03:00
UBStrings.Append (UBS, To_String (Deref (Lists.Element (C)).all));
2015-03-15 22:56:09 +03:00
exit when C = Lists.Last (T.The_List);
C := Lists.Next (C);
end loop;
2015-03-17 01:48:48 +03:00
return Opening (T.List_Type) &
To_String (UBS) &
Closing (T.List_Type);
2015-03-15 22:56:09 +03:00
end;
when Sym =>
return "" & T.Symbol;
when Str =>
-- The_String includes the quotation marks.
return To_String (T.The_String);
when Atom =>
return To_String (T.The_Atom);
2015-03-16 01:00:31 +03:00
when Unitary =>
case T.The_Function is
when Quote =>
2015-03-23 01:37:42 +03:00
return "(quote " & To_String (Deref (T.The_Operand).all) & ")";
2015-03-16 01:00:31 +03:00
when Unquote =>
2015-03-23 01:37:42 +03:00
return "(unquote " & To_String (Deref (T.The_Operand).all) & ")";
2015-03-16 01:00:31 +03:00
when Quasiquote =>
2015-03-23 01:37:42 +03:00
return "(quasiquote " & To_String (Deref (T.The_Operand).all) & ")";
2015-03-16 01:00:31 +03:00
when Splice_Unquote =>
return
2015-03-23 01:37:42 +03:00
"(splice-unquote " & To_String (Deref (T.The_Operand).all) & ")";
2015-03-20 01:19:13 +03:00
when Deref =>
return
2015-03-23 01:37:42 +03:00
"(deref " & To_String (Deref (T.The_Operand).all) & ")";
2015-03-16 01:00:31 +03:00
end case;
2015-03-19 00:12:54 +03:00
when Error =>
return To_String (T.Error_Msg);
2015-03-15 22:56:09 +03:00
end case;
end Mal_Type_To_String;
function To_String (T : Mal_Type) return String is
begin
2015-03-23 01:37:42 +03:00
if T.Meta /= Null_Smart_Pointer then
return "(with-meta " &
Mal_Type_To_String (T) & " " &
2015-03-23 01:37:42 +03:00
Mal_Type_To_String (Deref (T.Meta).all) & ")";
else
return Mal_Type_To_String (T);
end if;
2015-03-15 22:56:09 +03:00
end To_String;
2015-03-19 00:12:54 +03:00
2015-03-15 22:56:09 +03:00
end Types;