added initial files
This commit is contained in:
commit
73b2ff2af1
7
Makefile.in
Normal file
7
Makefile.in
Normal file
@ -0,0 +1,7 @@
|
||||
all:
|
||||
cd @abs_builddir@/lib; make all
|
||||
cd @abs_builddir@/cmd; make all
|
||||
|
||||
clean:
|
||||
cd @abs_builddir@/lib; make clean
|
||||
cd @abs_builddir@/cmd; make clean
|
23
cmd/Makefile.in
Normal file
23
cmd/Makefile.in
Normal file
@ -0,0 +1,23 @@
|
||||
all: @abs_builddir@/@ADA_OBJDIR@
|
||||
#gnatmake -x -aP@abs_builddir@ -Pscheme
|
||||
gprbuild @abs_builddir@/scheme.gpr
|
||||
|
||||
install: install-exec install-data
|
||||
|
||||
install-data:
|
||||
|
||||
install-exec:
|
||||
|
||||
uninstall:
|
||||
|
||||
@abs_builddir@/@ADA_OBJDIR@:
|
||||
mkdir -p @abs_builddir@/@ADA_OBJDIR@
|
||||
|
||||
clean:
|
||||
rm -rf @abs_builddir@/@ADA_OBJDIR@
|
||||
rm -f @abs_builddir@/*.ali
|
||||
rm -f @abs_builddir@/*.so
|
||||
rm -f @abs_builddir@/*.a
|
||||
rm -f @abs_builddir@/*.cgpr
|
||||
|
||||
distclean: clean
|
52
cmd/scheme.adb
Normal file
52
cmd/scheme.adb
Normal file
@ -0,0 +1,52 @@
|
||||
with H2.Scheme;
|
||||
with Storage;
|
||||
with Ada.Text_IO;
|
||||
|
||||
procedure scheme is
|
||||
package S renames H2.Scheme;
|
||||
|
||||
Pool: aliased Storage.Global_Pool;
|
||||
SI: S.Interpreter_Record;
|
||||
|
||||
begin
|
||||
Ada.Text_Io.Put_Line (S.Object_Word'Image(S.Object_Pointer_Bytes));
|
||||
|
||||
S.Open (SI, 2_000_000, Pool'Unchecked_Access);
|
||||
--S.Open (SI, null);
|
||||
S.Evaluate (SI);
|
||||
S.Close (SI);
|
||||
|
||||
declare
|
||||
subtype x is S.Object_Record (S.Moved_Object, 0);
|
||||
subtype y is S.Object_Record (S.Pointer_Object, 1);
|
||||
subtype z is S.Object_Record (S.Character_Object, 1);
|
||||
subtype q is S.Object_Record (S.Byte_Object, 1);
|
||||
a: x;
|
||||
b: y;
|
||||
c: z;
|
||||
d: q;
|
||||
w: S.Object_Word;
|
||||
begin
|
||||
Ada.Text_Io.Put_Line (S.Object_Word'Image(w'Size));
|
||||
Ada.Text_Io.Put_Line (S.Object_Word'Image(S.Object_Word'Size));
|
||||
Ada.Text_IO.Put_Line ("------");
|
||||
Ada.Text_Io.Put_Line (S.Object_Word'Image(x'Size));
|
||||
Ada.Text_Io.Put_Line (S.Object_Word'Image(y'Size));
|
||||
Ada.Text_Io.Put_Line (S.Object_Word'Image(z'Size));
|
||||
Ada.Text_Io.Put_Line (S.Object_Word'Image(q'Size));
|
||||
Ada.Text_Io.Put_Line (S.Object_Word'Image(x'Max_Size_In_Storage_Elements));
|
||||
Ada.Text_Io.Put_Line (S.Object_Word'Image(y'Max_Size_In_Storage_Elements));
|
||||
Ada.Text_Io.Put_Line (S.Object_Word'Image(z'Max_Size_In_Storage_Elements));
|
||||
Ada.Text_Io.Put_Line (S.Object_Word'Image(q'Max_Size_In_Storage_Elements));
|
||||
Ada.Text_Io.Put_Line (S.Object_Word'Image(a'Size));
|
||||
Ada.Text_Io.Put_Line (S.Object_Word'Image(b'Size));
|
||||
Ada.Text_Io.Put_Line (S.Object_Word'Image(c'Size));
|
||||
Ada.Text_Io.Put_Line (S.Object_Word'Image(c'Size));
|
||||
Ada.Text_Io.Put_Line (S.Object_Integer'Image(S.Object_Integer'First));
|
||||
Ada.Text_Io.Put_Line (S.Object_Integer'Image(S.Object_Integer'Last));
|
||||
end;
|
||||
|
||||
Ada.Text_IO.Put_Line ("BYE...");
|
||||
|
||||
|
||||
end scheme;
|
35
cmd/scheme.gpr.in
Normal file
35
cmd/scheme.gpr.in
Normal file
@ -0,0 +1,35 @@
|
||||
|
||||
with "@abs_builddir@/../lib/libh2";
|
||||
|
||||
project H2_Scheme is
|
||||
|
||||
for Main use ("scheme");
|
||||
|
||||
for Exec_Dir use ".";
|
||||
|
||||
for Source_Dirs use (
|
||||
"@abs_builddir@/../lib",
|
||||
"@abs_builddir@",
|
||||
"@abs_srcdir@"
|
||||
);
|
||||
for Source_Files use (
|
||||
"storage.ads",
|
||||
"storage.adb",
|
||||
"scheme.adb"
|
||||
);
|
||||
for Object_Dir use "@ADA_OBJDIR@";
|
||||
|
||||
package Compiler is
|
||||
for Default_Switches ("Ada") use (
|
||||
"-gnata", "-gnato", "-gnatN", "-gnatwl",
|
||||
"-I@abs_srcdir@/../lib"
|
||||
);
|
||||
end Compiler;
|
||||
|
||||
package Builder is
|
||||
for Executable ("scheme.adb") use "h2scm";
|
||||
end Builder;
|
||||
|
||||
end H2_Scheme;
|
||||
|
||||
|
66
cmd/storage.adb
Normal file
66
cmd/storage.adb
Normal file
@ -0,0 +1,66 @@
|
||||
with System;
|
||||
--with System.Address_Image;
|
||||
|
||||
|
||||
with Ada.Text_IO;
|
||||
|
||||
package body Storage is
|
||||
|
||||
type Size_T is mod 2 ** System.Word_Size;
|
||||
|
||||
function Sys_Malloc (Size: Size_T) return System.Address;
|
||||
--pragma Import (C, Sys_Malloc, Link_Name => "malloc");
|
||||
pragma Import (Convention => C, Entity => Sys_Malloc, External_Name => "malloc");
|
||||
|
||||
procedure Sys_Free (Ptr: System.Address);
|
||||
--pragma Import (C, Sys_Free, Link_Name => "free");
|
||||
pragma Import (Convention => C, Entity => Sys_Free, External_Name => "free");
|
||||
|
||||
procedure Allocate (Pool: in out Global_Pool; Address : out System.Address; Size: in SSE.Storage_Count; Alignment: in SSE.Storage_Count) is
|
||||
tmp: System.Address;
|
||||
use type SSE.Storage_Count;
|
||||
begin
|
||||
Ada.Text_IO.Put_Line ("QSE.Global_Pool Allocating " & SSE.Storage_Count'Image (Size) & " " & SSE.Storage_Count'Image (((Size + Alignment - 1) / Alignment) * Alignment));
|
||||
tmp := Sys_Malloc (Size_T(((Size + Alignment - 1) / Alignment) * Alignment));
|
||||
if System."=" (tmp, System.Null_Address) then
|
||||
raise Storage_Error;
|
||||
else
|
||||
Address := tmp;
|
||||
--Ada.Text_IO.Put_Line ("QSE.Global_Pool Returning " & System.Address_Image (Address));
|
||||
end if;
|
||||
end Allocate;
|
||||
|
||||
procedure Deallocate (Pool: in out Global_Pool; Address : in System.Address; Size: in SSE.Storage_Count; Alignment: in SSE.Storage_Count) is
|
||||
begin
|
||||
Ada.Text_IO.Put_Line ("QSE.Global_Pool Deallocating ");
|
||||
--Ada.Text_IO.Put_Line ("QSE.Global_Pool Deallocating " & System.Address_Image (Address));
|
||||
Sys_Free (Address);
|
||||
end Deallocate;
|
||||
|
||||
function Storage_Size (Pool: in Global_Pool) return SSE.Storage_Count is
|
||||
begin
|
||||
Ada.Text_IO.Put_Line ("QSE.Global_Pool Storage_Size ");
|
||||
return SSE.Storage_Count'Last;
|
||||
end Storage_Size;
|
||||
|
||||
|
||||
-- TODO: find a better solution
|
||||
-- gnat 3.15p somehow looks for the rountines below when H2.Pool is used.
|
||||
-- let me put these routines here temporarily until i find a proper solution.
|
||||
procedure Allocate_315P (Pool: in out SSP.Root_Storage_Pool'Class; Address : out System.Address; Size: in SSE.Storage_Count; Alignment: in SSE.Storage_Count);
|
||||
pragma Export (Ada, Allocate_315P, "system__storage_pools__allocate");
|
||||
procedure Allocate_315P (Pool: in out SSP.Root_Storage_Pool'Class; Address : out System.Address; Size: in SSE.Storage_Count; Alignment: in SSE.Storage_Count) is
|
||||
begin
|
||||
ada.text_io.put_line ("system__storage_pools__allocate...");
|
||||
SSP.Allocate (Pool, Address, Size, Alignment);
|
||||
end Allocate_315P;
|
||||
|
||||
procedure Deallocate_315P (Pool: in out SSP.Root_Storage_Pool'Class; Address : in System.Address; Size: in SSE.Storage_Count; Alignment: in SSE.Storage_Count);
|
||||
pragma Export (Ada, Deallocate_315P, "system__storage_pools__deallocate");
|
||||
procedure Deallocate_315P (Pool: in out SSP.Root_Storage_Pool'Class; Address : in System.Address; Size: in SSE.Storage_Count; Alignment: in SSE.Storage_Count) is
|
||||
begin
|
||||
ada.text_io.put_line ("system__storage_pools__deallocate...");
|
||||
SSP.Deallocate (Pool, Address, Size, Alignment);
|
||||
end Deallocate_315P;
|
||||
end Storage;
|
||||
|
26
cmd/storage.ads
Normal file
26
cmd/storage.ads
Normal file
@ -0,0 +1,26 @@
|
||||
with System.Storage_Pools;
|
||||
with System.Storage_Elements;
|
||||
|
||||
package Storage is
|
||||
|
||||
package SSE renames System.Storage_Elements;
|
||||
package SSP renames System.Storage_Pools;
|
||||
|
||||
type Global_Pool is new SSP.Root_Storage_Pool with private;
|
||||
|
||||
procedure Allocate (Pool: in out Global_Pool;
|
||||
Address: out System.Address;
|
||||
Size: in SSE.Storage_Count;
|
||||
Alignment: in SSE.Storage_Count);
|
||||
|
||||
procedure Deallocate (Pool: in out Global_Pool;
|
||||
Address: in System.Address;
|
||||
Size: in SSE.Storage_Count;
|
||||
Alignment: in SSE.Storage_Count);
|
||||
|
||||
function Storage_Size (Pool: in Global_Pool) return SSE.Storage_Count;
|
||||
|
||||
private
|
||||
type Global_Pool is new SSP.Root_Storage_Pool with null record;
|
||||
|
||||
end Storage;
|
24
configure.ac
Normal file
24
configure.ac
Normal file
@ -0,0 +1,24 @@
|
||||
AC_INIT([H2], 0.1.0)
|
||||
dnl AM_INIT_AUTOMAKE
|
||||
AC_PROG_CC
|
||||
|
||||
AC_ARG_WITH([ada-objdir],
|
||||
[AS_HELP_STRING(--with-ada-objdir,specify ada object directory path)],
|
||||
[ada_objdir=$withval]
|
||||
)
|
||||
if test -n "$ada_objdir"
|
||||
then
|
||||
AC_SUBST(ADA_OBJDIR, "$ada_objdir")
|
||||
else
|
||||
AC_SUBST(ADA_OBJDIR, "objdir")
|
||||
fi
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
lib/Makefile
|
||||
lib/lib.gpr
|
||||
lib/libh2.gpr
|
||||
cmd/Makefile
|
||||
cmd/scheme.gpr
|
||||
])
|
||||
AC_OUTPUT
|
24
lib/Makefile.in
Normal file
24
lib/Makefile.in
Normal file
@ -0,0 +1,24 @@
|
||||
all: @abs_builddir@/@ADA_OBJDIR@
|
||||
#gnatmake -x -aP@abs_builddir@ -Plib
|
||||
gprbuild @abs_builddir@/lib.gpr
|
||||
|
||||
install: install-exec install-data
|
||||
|
||||
install-data:
|
||||
|
||||
install-exec:
|
||||
|
||||
uninstall:
|
||||
|
||||
@abs_builddir@/@ADA_OBJDIR@:
|
||||
mkdir -p @abs_builddir@/@ADA_OBJDIR@
|
||||
|
||||
clean:
|
||||
rm -rf @abs_builddir@/@ADA_OBJDIR@
|
||||
rm -f @abs_builddir@/*.ali
|
||||
rm -f @abs_builddir@/*.so
|
||||
rm -f @abs_builddir@/*.a
|
||||
rm -f @abs_builddir@/*.cgpr
|
||||
|
||||
|
||||
distclean: clean
|
86
lib/h2-pool.adb
Normal file
86
lib/h2-pool.adb
Normal file
@ -0,0 +1,86 @@
|
||||
with Ada.Unchecked_Conversion;
|
||||
with Ada.Unchecked_Deallocation;
|
||||
|
||||
package body H2.Pool is
|
||||
|
||||
function Allocate (Pool: in Storage_Pool_Pointer := null) return Pointer_Type is
|
||||
P: Storage_Pool_Pointer;
|
||||
|
||||
begin
|
||||
if Pool = null then
|
||||
P := Storage_Pool;
|
||||
else
|
||||
P := Pool;
|
||||
end if;
|
||||
|
||||
if P = null then
|
||||
return new Normal_Type;
|
||||
else
|
||||
declare
|
||||
type Pooled_Pointer is access Normal_Type;
|
||||
for Pooled_Pointer'Storage_Pool use P.all;
|
||||
function To_Pointer_Type is new Ada.Unchecked_Conversion (Pooled_Pointer, Pointer_Type);
|
||||
Tmp: Pooled_Pointer;
|
||||
begin
|
||||
Tmp := new Normal_Type;
|
||||
return To_Pointer_Type (Tmp);
|
||||
end;
|
||||
end if;
|
||||
end Allocate;
|
||||
|
||||
function Allocate (Source: in Normal_Type;
|
||||
Pool: in Storage_Pool_Pointer := null) return Pointer_Type is
|
||||
P: Storage_Pool_Pointer;
|
||||
begin
|
||||
if Pool = null then
|
||||
P := Storage_Pool;
|
||||
else
|
||||
P := Pool;
|
||||
end if;
|
||||
|
||||
if P = null then
|
||||
return new Normal_Type'(Source);
|
||||
else
|
||||
declare
|
||||
type Pooled_Pointer is access Normal_Type;
|
||||
for Pooled_Pointer'Storage_Pool use P.all;
|
||||
function To_Pointer_Type is new Ada.Unchecked_Conversion (Pooled_Pointer, Pointer_Type);
|
||||
Tmp: Pooled_Pointer;
|
||||
begin
|
||||
Tmp := new Normal_Type'(Source);
|
||||
return To_Pointer_Type (Tmp);
|
||||
end;
|
||||
end if;
|
||||
end Allocate;
|
||||
|
||||
procedure Deallocate (Target: in out Pointer_Type;
|
||||
Pool: in Storage_Pool_Pointer := null) is
|
||||
P: Storage_Pool_Pointer;
|
||||
begin
|
||||
if Pool = null then
|
||||
P := Storage_Pool;
|
||||
else
|
||||
P := Pool;
|
||||
end if;
|
||||
|
||||
if P = null then
|
||||
declare
|
||||
procedure Dealloc is new Ada.Unchecked_Deallocation (Normal_Type, Pointer_Type);
|
||||
begin
|
||||
Dealloc (Target);
|
||||
end;
|
||||
else
|
||||
declare
|
||||
type Pooled_Pointer is access Normal_Type;
|
||||
for Pooled_Pointer'Storage_Pool use P.all;
|
||||
function To_Pooled_Pointer is new Ada.Unchecked_Conversion (Pointer_Type, Pooled_Pointer);
|
||||
procedure Dealloc is new Ada.Unchecked_Deallocation (Normal_Type, Pooled_Pointer);
|
||||
Tmp: Pooled_Pointer := To_Pooled_Pointer (Target);
|
||||
begin
|
||||
Dealloc (Tmp);
|
||||
Target := null;
|
||||
end;
|
||||
end if;
|
||||
end Deallocate;
|
||||
|
||||
end H2.Pool;
|
25
lib/h2-pool.ads
Normal file
25
lib/h2-pool.ads
Normal file
@ -0,0 +1,25 @@
|
||||
--------------------------------------------------------------------
|
||||
-- Instantantiate this package before using. To allocate integers,
|
||||
--
|
||||
-- package Integer_Pool is new Pool (Integer, Integer_Pointer, Storage_Pool);
|
||||
--
|
||||
-- Integer_Pool.Allocate (10);
|
||||
--------------------------------------------------------------------
|
||||
|
||||
generic
|
||||
type Normal_Type is private;
|
||||
type Pointer_Type is access Normal_Type;
|
||||
Storage_Pool: in Storage_Pool_Pointer := null;
|
||||
|
||||
package H2.Pool is
|
||||
|
||||
function Allocate (Pool: in Storage_Pool_Pointer := null) return Pointer_Type;
|
||||
|
||||
function Allocate (Source: in Normal_Type;
|
||||
Pool: in Storage_Pool_Pointer := null) return Pointer_Type;
|
||||
|
||||
procedure Deallocate (Target: in out Pointer_Type;
|
||||
Pool: in Storage_Pool_Pointer := null);
|
||||
|
||||
end H2.Pool;
|
||||
|
1218
lib/h2-scheme.adb
Normal file
1218
lib/h2-scheme.adb
Normal file
File diff suppressed because it is too large
Load Diff
341
lib/h2-scheme.ads
Normal file
341
lib/h2-scheme.ads
Normal file
@ -0,0 +1,341 @@
|
||||
---------------------------------------------------------------------
|
||||
-- ##### # # #####
|
||||
-- # # #### # # ###### # # ###### # # # #
|
||||
-- # # # # # # ## ## # # # #
|
||||
-- ##### # ###### ##### # ## # ##### ##### ####### #####
|
||||
-- # # # # # # # # # # #
|
||||
-- # # # # # # # # # # # # #
|
||||
-- ##### #### # # ###### # # ###### # # #######
|
||||
---------------------------------------------------------------------
|
||||
|
||||
with System;
|
||||
with System.Storage_Pools;
|
||||
|
||||
|
||||
with Ada.Unchecked_Conversion;
|
||||
-- TODO: delete these after debugging
|
||||
with ada.text_io;
|
||||
with ada.wide_text_io;
|
||||
with ada.integer_text_io;
|
||||
with ada.long_integer_text_io;
|
||||
--with system.address_image;
|
||||
-- TODO: delete above after debugging
|
||||
|
||||
package H2.Scheme is
|
||||
|
||||
-- An object pointer takes up as many bytes as a system word.
|
||||
Object_Pointer_Bits: constant := System.Word_Size;
|
||||
Object_Pointer_Bytes: constant := Object_Pointer_Bits / System.Storage_Unit;
|
||||
|
||||
-- I use the lower 2 bits to indicate the type of an object pointer.
|
||||
-- A real object pointer is typically allocated on a word boundary.
|
||||
-- As a result, the lower 2 bits should always be 0. Using this
|
||||
-- property, I keep some other values at the lower 2 bits to indicate
|
||||
-- some other direct values like an integer or a character.
|
||||
Object_Pointer_Type_Bits: constant := 2;
|
||||
type Object_Pointer_Type is mod 2 ** Object_Pointer_Type_Bits;
|
||||
Object_Pointer_Type_Pointer: constant Object_Pointer_Type := 2#00#;
|
||||
Object_Pointer_Type_Integer: constant Object_Pointer_Type := 2#01#;
|
||||
Object_Pointer_Type_Character: constant Object_Pointer_Type := 2#10#;
|
||||
Object_Pointer_Type_Byte: constant Object_Pointer_Type := 2#11#;
|
||||
Object_Pointer_Type_Mask: constant Object_Pointer_Type := 2#11#;
|
||||
|
||||
type Object_Record;
|
||||
type Object_Pointer is access all Object_Record;
|
||||
for Object_Pointer'Size use Object_Pointer_Bits;
|
||||
|
||||
-- Object_Word is a numeric type as large as Object_Poinetr;
|
||||
type Object_Word is mod 2 ** Object_Pointer_Bits;
|
||||
for Object_Word'Size use Object_Pointer_Bits;
|
||||
|
||||
-- Object_Signed_Word is the signed version of Object_Word.
|
||||
-- Note Object_Word is a modular type while this is a signed range.
|
||||
type Object_Signed_Word is range -(2 ** (Object_Pointer_Bits - 1)) ..
|
||||
+(2 ** (Object_Pointer_Bits - 1)) - 1;
|
||||
for Object_Signed_Word'Size use Object_Pointer_Bits;
|
||||
|
||||
-- The actual number of bits for an integer the number of bits excluding
|
||||
-- the pointer type bits.
|
||||
Object_Integer_Bits: constant := Object_Pointer_Bits - Object_Pointer_Type_Bits;
|
||||
|
||||
-- Object_Integer represents the range of SmallInteger.
|
||||
-- It defines an integer that can be held in the upper Object_Integer_Bits
|
||||
-- bits. Conversion functions betwen Object_Integer and Object_Pointer
|
||||
-- use the highest 1 bit to represent the sign after shifting. So, the
|
||||
-- range is shrunk further by 1 bit, resulting in -2 in the foluma below.
|
||||
-- -----------------------------------------------------------------------
|
||||
-- type Object_Integer is range -(2 ** (Object_Integer_Bits - 2)) ..
|
||||
-- +(2 ** (Object_Integer_Bits - 2)) - 1;
|
||||
-- -----------------------------------------------------------------------
|
||||
-- If i don't include -(2 ** (Object_Integer_Bits - 1)) into the range,
|
||||
-- it can be extended to a larger range. That's because the excluded number
|
||||
-- conflicts with the highest sign bit during the conversion process.
|
||||
-- -----------------------------------------------------------------------
|
||||
type Object_Integer is range -(2 ** (Object_Integer_Bits - 1)) + 1 ..
|
||||
+(2 ** (Object_Integer_Bits - 1)) - 1;
|
||||
-- -----------------------------------------------------------------------
|
||||
-- What is a better choice? TODO: decide what to use
|
||||
-- -----------------------------------------------------------------------
|
||||
-- Let Object_Integer take up as large a space as Object_Pointer
|
||||
-- despite the actual range of Object_Integer.
|
||||
for Object_Integer'Size use Object_Pointer_Bits;
|
||||
|
||||
-- The Object_Size type defines the size of object payload.
|
||||
-- It is the number of payload items for each object kind.
|
||||
--type Object_Size is new Object_Word range 0 .. (2 ** (System.Word_Size - 1)) - 1;
|
||||
--type Object_Size is new Object_Word range 0 .. 1000; -- TODO: remove this line and uncommect the live above
|
||||
type Object_Size is new Object_Word;
|
||||
for Object_Size'Size use Object_Pointer_Bits; -- for GC
|
||||
|
||||
type Object_Byte is mod 2 ** System.Storage_Unit;
|
||||
for Object_Byte'Size use System.Storage_Unit;
|
||||
|
||||
--subtype Object_Character is Standard.Wide_Character;
|
||||
--subtype Object_String is Standard.Wide_String;
|
||||
--package Text_IO renames Ada.Wide_Text_IO;
|
||||
subtype Object_Character is Standard.Character;
|
||||
subtype Object_String is Standard.String;
|
||||
package Text_IO renames Ada.Text_IO;
|
||||
|
||||
type Object_Byte_Array is array (Object_Size range <>) of Object_Byte;
|
||||
type Object_Character_Array is array (Object_Size range <>) of Object_Character;
|
||||
type Object_Pointer_Array is array (Object_Size range <>) of Object_Pointer;
|
||||
type Object_Word_Array is array (Object_Size range <>) of Object_Word;
|
||||
|
||||
type Object_Kind is (
|
||||
Moved_Object, -- internal use only
|
||||
Pointer_Object,
|
||||
Character_Object,
|
||||
Byte_Object,
|
||||
Word_Object
|
||||
);
|
||||
for Object_Kind use (
|
||||
Moved_Object => 0,
|
||||
Pointer_Object => 1,
|
||||
Character_Object => 2,
|
||||
Byte_Object => 3,
|
||||
Word_Object => 4
|
||||
);
|
||||
|
||||
-- -----------------------------------------------------------------------
|
||||
|
||||
-- Object_Record contains the Flags field that can be used
|
||||
-- freely for management purpose. The Object_Flags type
|
||||
-- represents the value that can be stored in this field.
|
||||
type Object_Flags is mod 2 ** 4;
|
||||
Syntax_Object: constant Object_Flags := Object_Flags'(2#0001#);
|
||||
|
||||
type Syntax_Code is mod 2 ** 4;
|
||||
AND_SYNTAX: constant Syntax_Code := Syntax_Code'(0);
|
||||
BEGIN_SYNTAX: constant Syntax_Code := Syntax_Code'(0);
|
||||
CASE_SYNTAX: constant Syntax_Code := Syntax_Code'(0);
|
||||
COND_SYNTAX: constant Syntax_Code := Syntax_Code'(0);
|
||||
DEFINE_SYNTAX: constant Syntax_Code := Syntax_Code'(0);
|
||||
IF_SYNTAX: constant Syntax_Code := Syntax_Code'(0);
|
||||
LAMBDA_SYNTAX: constant Syntax_Code := Syntax_Code'(0);
|
||||
LET_SYNTAX: constant Syntax_Code := Syntax_Code'(0);
|
||||
LETAST_SYNTAX: constant Syntax_Code := Syntax_Code'(0);
|
||||
LETREC_SYNTAX: constant Syntax_Code := Syntax_Code'(0);
|
||||
OR_SYNTAX: constant Syntax_Code := Syntax_Code'(0);
|
||||
QUOTE_SYNTAX: constant Syntax_Code := Syntax_Code'(0);
|
||||
SET_SYNTAX: constant Syntax_Code := Syntax_Code'(0);
|
||||
|
||||
|
||||
type Object_Tag is (
|
||||
Unknown_Object,
|
||||
Cons_Object,
|
||||
String_Object,
|
||||
Symbol_Object,
|
||||
Number_Object,
|
||||
Array_Object,
|
||||
Table_Object,
|
||||
Lambda_Object,
|
||||
Continuation_Object,
|
||||
Frame_Object
|
||||
);
|
||||
|
||||
type Object_Record (Kind: Object_Kind; Size: Object_Size) is record
|
||||
Flags: Object_Flags := 0;
|
||||
Scode: Syntax_Code := 0;
|
||||
Tag: Object_Tag := Unknown_Object;
|
||||
|
||||
-- Object payload:
|
||||
-- I assume that the smallest payload is able to hold an
|
||||
-- object pointer by specifying the alignement attribute
|
||||
-- to Object_Pointer_Bytes. this implementation will break
|
||||
-- severely if this assumption is not correct.
|
||||
case Kind is
|
||||
when Moved_Object =>
|
||||
New_Pointer: Object_Pointer := null;
|
||||
when Pointer_Object =>
|
||||
Pointer_Slot: Object_Pointer_Array (1 .. Size) := (others => null);
|
||||
when Character_Object =>
|
||||
Character_Slot: Object_Character_Array (0 .. Size) := (others => Object_Character'First);
|
||||
when Byte_Object =>
|
||||
Byte_Slot: Object_Byte_Array (1 .. Size) := (others => 0);
|
||||
when Word_Object =>
|
||||
Word_Slot: Object_Word_Array (1 .. Size) := (others => 0);
|
||||
end case;
|
||||
end record;
|
||||
for Object_Record use record
|
||||
Kind at 0 range 0 .. 3; -- 4 bits (0 .. 15)
|
||||
Flags at 0 range 4 .. 7; -- 4 bits
|
||||
Scode at 0 range 8 .. 11; -- 4 bits (0 .. 15)
|
||||
Tag at 0 range 12 .. 15; -- 4 bits (0 .. 15)
|
||||
-- there are still some space unused in the first word. What can i do?
|
||||
end record;
|
||||
for Object_Record'Alignment use Object_Pointer_Bytes;
|
||||
|
||||
-- the following 3 size types are defined for limiting the object size range.
|
||||
subtype Empty_Object_Record is Object_Record (Byte_Object, 0);
|
||||
|
||||
-- the number of bytes in an object header. this is fixed in size
|
||||
Object_Header_Bytes: constant Object_Size := Empty_Object_Record'Max_Size_In_Storage_Elements;
|
||||
-- the largest number of bytes that an object can hold after the header
|
||||
Object_Payload_Max_Bytes: constant Object_Size := Object_Size'Last - Object_Header_Bytes;
|
||||
|
||||
-- the following types are defined to set the byte range of the object data.
|
||||
-- the upper bound is set to the maximum that don't cause overflow in calcuating the size in bits.
|
||||
-- the compiler doesn't seem to be able to return 'Size or 'Max_Size_In_Storage_Elements properly
|
||||
-- when the number of bits calculated overflows.
|
||||
subtype Byte_Object_Size is Object_Size range
|
||||
Object_Size'First .. (Object_Payload_Max_Bytes / (Object_Byte'Max_Size_In_Storage_Elements * System.Storage_Unit));
|
||||
subtype Character_Object_Size is Object_Size range
|
||||
Object_Size'First .. (Object_Payload_Max_Bytes / (Object_Character'Max_Size_In_Storage_Elements * System.Storage_Unit));
|
||||
subtype Pointer_Object_Size is Object_Size range
|
||||
Object_Size'First .. (Object_Payload_Max_Bytes / (Object_Pointer'Max_Size_In_Storage_Elements * System.Storage_Unit));
|
||||
subtype Word_Object_Size is Object_Size range
|
||||
Object_Size'First .. (Object_Payload_Max_Bytes / (Object_Word'Max_Size_In_Storage_Elements * System.Storage_Unit));
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- Various pointer classification and conversion procedures
|
||||
-- -----------------------------------------------------------------------------
|
||||
function Is_Pointer (Pointer: in Object_Pointer) return Standard.Boolean;
|
||||
function Is_Special_Pointer (Pointer: in Object_Pointer) return Standard.Boolean;
|
||||
function Is_Normal_Pointer (Pointer: in Object_Pointer) return Standard.Boolean;
|
||||
function Is_Integer (Pointer: in Object_Pointer) return Standard.Boolean;
|
||||
function Is_Character (Pointer: in Object_Pointer) return Standard.Boolean;
|
||||
function Is_Byte (Pointer: in Object_Pointer) return Standard.Boolean;
|
||||
|
||||
function Integer_To_Pointer (Int: in Object_Integer) return Object_Pointer;
|
||||
function Character_To_Pointer (Char: in Object_Character) return Object_Pointer;
|
||||
function Byte_To_Pointer (Byte: in Object_Byte) return Object_Pointer;
|
||||
|
||||
function Pointer_To_Integer (Pointer: in Object_Pointer) return Object_Integer;
|
||||
function Pointer_To_Character (Pointer: in Object_Pointer) return Object_Character;
|
||||
function Pointer_To_Byte (Pointer: in Object_Pointer) return Object_Byte;
|
||||
|
||||
pragma Inline (Is_Special_Pointer);
|
||||
pragma Inline (Is_Pointer);
|
||||
pragma Inline (Is_Integer);
|
||||
pragma Inline (Is_Character);
|
||||
pragma Inline (Integer_To_Pointer);
|
||||
pragma Inline (Character_To_Pointer);
|
||||
pragma Inline (Byte_To_Pointer);
|
||||
pragma Inline (Pointer_To_Integer);
|
||||
pragma Inline (Pointer_To_Character);
|
||||
pragma Inline (Pointer_To_Byte);
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- While I could define Memory_Element and Memory_Size to be
|
||||
-- the subtype of Object_Byte and Object_Size each, they are not
|
||||
-- logically the same thing.
|
||||
-- subtype Storage_Element is Object_Byte;
|
||||
-- subtype Storage_Count is Object_Size;
|
||||
type Memory_Element is mod 2 ** System.Storage_Unit;
|
||||
type Memory_Size is range 0 .. (2 ** (System.Word_Size - 1)) - 1;
|
||||
|
||||
type Interpreter_Record is limited private;
|
||||
|
||||
type Trait_Mask is mod 2 ** System.Word_Size;
|
||||
No_Garbage_Collection: constant Trait_Mask := 2 ** 0;
|
||||
|
||||
type Option_Kind is (Trait_Option);
|
||||
type Option_Record (Kind: Option_Kind) is record
|
||||
case Kind is
|
||||
when Trait_Option =>
|
||||
Trait_Bits: Trait_Mask := 0;
|
||||
end case;
|
||||
end record;
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
|
||||
-- The nil/true/false object are represented by special pointer values.
|
||||
-- The special values are defined under the assumption that actual objects
|
||||
-- are never allocated on one of these addresses. Addresses of 0, 4, 8 are
|
||||
-- very low, making the assumption pretty safe.
|
||||
Nil_Word: constant Object_Word := 2#0000#; -- 0
|
||||
--Nil_Pointer: constant Object_Pointer;
|
||||
--for Nil_Pointer'Address use Nil_Word'Address;
|
||||
--pragma Import (Ada, Nil_Pointer);
|
||||
|
||||
True_Word: constant Object_Word := 2#0100#; -- 4
|
||||
--True_Pointer: constant Object_Pointer;
|
||||
--for True_Pointer'Address use True_Word'Address;
|
||||
--pragma Import (Ada, True_Pointer);
|
||||
|
||||
False_Word: constant Object_Word := 2#1000#; -- 8
|
||||
--False_Pointer: constant Object_Pointer;
|
||||
--for False_Pointer'Address use False_Word'Address;
|
||||
--pragma Import (Ada, False_Pointer);
|
||||
|
||||
function Object_Word_To_Pointer is new Ada.Unchecked_Conversion (Object_Word, Object_Pointer);
|
||||
function Object_Pointer_To_Word is new Ada.Unchecked_Conversion (Object_Pointer, Object_Word);
|
||||
Nil_Pointer: constant Object_Pointer := Object_Word_To_Pointer (Nil_Word);
|
||||
True_Pointer: constant Object_Pointer := Object_Word_To_Pointer (True_Word);
|
||||
False_Pointer: constant Object_Pointer := Object_Word_To_Pointer (False_Word);
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
|
||||
procedure Open (Interp: in out Interpreter_Record;
|
||||
Initial_Heap_Size:in Memory_Size;
|
||||
Storage_Pool: in Storage_Pool_Pointer := null);
|
||||
|
||||
procedure Close (Interp: in out Interpreter_Record);
|
||||
|
||||
procedure Evaluate (Interp: in out Interpreter_Record);
|
||||
|
||||
procedure Set_Option (Interp: in out Interpreter_Record;
|
||||
Option: in Option_Record);
|
||||
|
||||
procedure Get_Option (Interp: in out Interpreter_Record;
|
||||
Option: in out Option_Record);
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
|
||||
private
|
||||
type Heap_Array is array (Memory_Size range <>) of aliased Memory_Element;
|
||||
|
||||
type Heap_Record (Size: Memory_Size) is record
|
||||
Space: Heap_Array (1 .. Size) := (others => 0);
|
||||
Bound: Memory_Size := 0;
|
||||
end record;
|
||||
for Heap_Record'Alignment use Object_Pointer_Bytes;
|
||||
type Heap_Pointer is access all Heap_Record;
|
||||
|
||||
type Heap_Number is mod 2 ** 1;
|
||||
type Heap_Pointer_Array is Array (Heap_Number'First .. Heap_Number'Last) of Heap_Pointer;
|
||||
|
||||
type Register_Record is limited record
|
||||
Code: Object_Pointer := Nil_Pointer;
|
||||
Envir: Object_Pointer := Nil_Pointer;
|
||||
Args: Object_Pointer := Nil_Pointer;
|
||||
Next: Object_Pointer := Nil_Pointer;
|
||||
end record;
|
||||
|
||||
type Interpreter_Record is limited record
|
||||
Storage_Pool: Storage_Pool_Pointer := null;
|
||||
Trait: Option_Record (Trait_Option);
|
||||
|
||||
Heap: Heap_Pointer_Array := (others => null);
|
||||
Current_Heap: Heap_Number := Heap_Number'First;
|
||||
|
||||
Root_Table: Object_Pointer := Nil_Pointer;
|
||||
Symbol_Table: Object_Pointer := Nil_Pointer;
|
||||
Environment: Object_Pointer := Nil_Pointer;
|
||||
Stack: Object_Pointer := Nil_Pointer;
|
||||
|
||||
R: Register_Record;
|
||||
end record;
|
||||
|
||||
end H2.Scheme;
|
10
lib/h2.ads
Normal file
10
lib/h2.ads
Normal file
@ -0,0 +1,10 @@
|
||||
with System.Storage_Pools;
|
||||
|
||||
package H2 is
|
||||
|
||||
subtype Character is Standard.Wide_Character;
|
||||
|
||||
type Storage_Pool_Pointer is
|
||||
access all System.Storage_Pools.Root_Storage_Pool'Class;
|
||||
|
||||
end H2;
|
33
lib/lib.gpr.in
Normal file
33
lib/lib.gpr.in
Normal file
@ -0,0 +1,33 @@
|
||||
project Lib is
|
||||
|
||||
for Source_Dirs use ("@abs_srcdir@");
|
||||
for Library_Name use "h2";
|
||||
for Library_Kind use "dynamic";
|
||||
for Library_Dir use ".";
|
||||
--for Library_Src_Dir use ".";
|
||||
for Object_Dir use "@ADA_OBJDIR@";
|
||||
|
||||
for Source_Files use (
|
||||
"h2.ads",
|
||||
"h2-pool.adb",
|
||||
"h2-pool.ads",
|
||||
"h2-scheme.adb",
|
||||
"h2-scheme.ads"
|
||||
);
|
||||
for Library_Interface use (
|
||||
"h2",
|
||||
"h2.pool",
|
||||
"h2.scheme"
|
||||
);
|
||||
|
||||
package Compiler is
|
||||
for Default_Switches ("Ada") use (
|
||||
"-gnata", "-gnato", "-gnatN", "-gnatwl"
|
||||
);
|
||||
end Compiler;
|
||||
|
||||
--package Install is
|
||||
-- for Prefix use "@prefix@";
|
||||
--end Install;
|
||||
end Lib;
|
||||
|
10
lib/libh2.gpr.in
Normal file
10
lib/libh2.gpr.in
Normal file
@ -0,0 +1,10 @@
|
||||
project LibH2 is
|
||||
|
||||
for Library_Name use "h2";
|
||||
for Library_Kind use "dynamic";
|
||||
for Library_Dir use "@abs_builddir@";
|
||||
for Source_Files use ();
|
||||
for Externally_Built use "true";
|
||||
|
||||
end LibH2;
|
||||
|
Loading…
Reference in New Issue
Block a user