1
1
mirror of https://github.com/kanaka/mal.git synced 2024-11-11 00:52:44 +03:00
mal/ada/envs.adb

147 lines
3.7 KiB
Ada
Raw Normal View History

2015-04-05 22:27:47 +03:00
with Ada.Text_IO;
2015-04-19 20:08:51 +03:00
with Types;
2015-04-02 01:36:29 +03:00
with Unchecked_Deallocation;
package body Envs is
2015-04-19 20:08:51 +03:00
function Is_Null (E : Env_Handle) return Boolean is
use Smart_Pointers;
begin
return E = Null_Env_Handle;
2015-04-19 20:08:51 +03:00
end Is_Null;
function New_Env (Outer : Env_Handle := Null_Env_Handle) return Env_Handle is
2015-04-19 20:08:51 +03:00
use Smart_Pointers;
Level : Natural;
begin
if Is_Null (Outer) then
Level := 0;
else
Level := Deref (Outer).Level + 1;
end if;
if Debug then
Ada.Text_IO.Put_Line
("Envs: Creating at level " & Natural'Image (Level));
end if;
return Env_Handle (Smart_Pointers.New_Ptr (new Env'
(Base_Class with The_Map => String_Mal_Hash.Empty_Map,
Outer_Env => Outer,
Level => Level)));
end New_Env;
procedure Set
(E : Env_Handle;
Key : String;
Elem : Smart_Pointers.Smart_Pointer) is
begin
if Debug then
Ada.Text_IO.Put_Line
("Envs: Setting " & Key &
" to " & Types.Deref (Elem).To_String &
" at level " & Natural'Image (Deref (E).Level));
end if;
2015-04-02 01:36:29 +03:00
String_Mal_Hash.Include
2015-04-19 20:08:51 +03:00
(Container => Deref (E).The_Map,
2015-04-02 01:36:29 +03:00
Key => Ada.Strings.Unbounded.To_Unbounded_String (Key),
2015-04-19 20:08:51 +03:00
New_Item => Elem);
2015-04-02 23:40:22 +03:00
end Set;
2015-04-02 01:36:29 +03:00
2015-04-05 22:27:47 +03:00
2015-04-19 20:08:51 +03:00
function Get (E : Env_Handle; Key: String)
return Smart_Pointers.Smart_Pointer is
use String_Mal_Hash;
C : Cursor;
2015-04-05 22:27:47 +03:00
2015-04-19 20:08:51 +03:00
begin
if Debug then
Ada.Text_IO.Put_Line
("Envs: Finding " & Key &
" at level " & Natural'Image (Deref (E).Level));
end if;
2015-04-05 22:27:47 +03:00
2015-04-19 20:08:51 +03:00
C := Find (Deref (E).The_Map,
Ada.Strings.Unbounded.To_Unbounded_String (Key));
2015-04-05 22:27:47 +03:00
2015-04-19 20:08:51 +03:00
if C = No_Element then
if Is_Null (Deref (E).Outer_Env) then
raise Not_Found;
2015-04-05 22:27:47 +03:00
else
2015-04-19 20:08:51 +03:00
return Get (Deref (E).Outer_Env, Key);
2015-04-05 22:27:47 +03:00
end if;
2015-04-19 20:08:51 +03:00
else
return Element (C);
end if;
2015-04-05 22:27:47 +03:00
2015-04-02 23:40:22 +03:00
end Get;
2015-04-02 01:36:29 +03:00
2015-04-22 23:27:43 +03:00
procedure Set_Outer
(E : Env_Handle; Outer_Env : Env_Handle) is
begin
-- Attempt to avoid making loops.
if Deref (E).Level /= 0 then
Deref (E).Outer_Env := Outer_Env;
end if;
end Set_Outer;
function To_String (E : Env_Handle) return String is
use String_Mal_Hash, Ada.Strings.Unbounded;
C : Cursor;
Res : Unbounded_String;
begin
C := First (Deref (E).The_Map);
while C /= No_Element loop
Append (Res, Key (C) & " => " & Types.To_String (Types.Deref (Element (C)).all) & ", ");
C := Next (C);
end loop;
return To_String (Res);
end To_String;
2015-04-19 20:08:51 +03:00
-- Sym and Exprs are lists. Bind Sets Keys in Syms to the corresponding
-- expression in Exprs. Returns true if all the parameters were bound.
function Bind (Env : Env_Handle; Syms, Exprs : Types.List_Mal_Type)
return Boolean is
2015-04-19 20:08:51 +03:00
use Types;
S, Expr : List_Mal_Type;
First_Sym : Sym_Ptr;
2015-04-19 20:08:51 +03:00
begin
S := Syms;
Expr := Exprs;
2015-04-26 21:28:22 +03:00
while not Is_Null (S) loop
First_Sym := Deref_Sym (Car (S));
if First_Sym.Get_Sym = "&" then
2015-04-26 21:28:22 +03:00
S := Deref_List (Cdr (S)).all;
First_Sym := Deref_Sym (Car (S));
Set (Env, First_Sym.Get_Sym, New_List_Mal_Type (Expr));
return True;
2015-04-26 21:28:22 +03:00
end if;
Set (Env, First_Sym.Get_Sym, Car (Expr));
2015-04-19 20:08:51 +03:00
S := Deref_List (Cdr (S)).all;
2015-04-26 21:28:22 +03:00
exit when Is_Null (Expr);
2015-04-19 20:08:51 +03:00
Expr := Deref_List (Cdr (Expr)).all;
2015-04-19 20:08:51 +03:00
end loop;
return Is_Null (S);
2015-04-19 20:08:51 +03:00
end Bind;
function Deref (SP : Env_Handle) return Env_Ptr is
begin
return Env_Ptr (Smart_Pointers.Deref (Smart_Pointers.Smart_Pointer (SP)));
end Deref;
2015-04-02 01:36:29 +03:00
end Envs;