added experimental stream handling code
This commit is contained in:
parent
dcf676476f
commit
eac1df647a
@ -1,6 +1,9 @@
|
|||||||
with H2.Scheme;
|
with H2.Scheme;
|
||||||
|
with H2.Pool;
|
||||||
with Storage;
|
with Storage;
|
||||||
|
with Stream;
|
||||||
with Ada.Text_IO;
|
with Ada.Text_IO;
|
||||||
|
with Ada.Unchecked_Deallocation;
|
||||||
|
|
||||||
procedure scheme is
|
procedure scheme is
|
||||||
package S renames H2.Scheme;
|
package S renames H2.Scheme;
|
||||||
@ -10,12 +13,62 @@ procedure scheme is
|
|||||||
|
|
||||||
I: S.Object_Pointer;
|
I: S.Object_Pointer;
|
||||||
O: S.Object_Pointer;
|
O: S.Object_Pointer;
|
||||||
|
|
||||||
|
--String: aliased S.Object_String := "(car '(1 2 3))";
|
||||||
|
String: aliased S.Object_String := "((lambda (x y) (+ x y)) 9 7)";
|
||||||
|
String_Stream: Stream.String_Input_Stream_Record (String'Unchecked_Access);
|
||||||
|
--String_Stream: Stream.String_Input_Stream_Record := (Len => String'Length, Str => String, Pos => 0);
|
||||||
|
|
||||||
|
|
||||||
|
File_Name: aliased S.Object_String := "test.adb";
|
||||||
|
--File_Stream: Stream.File_Stream_Record (File_Name'Unchecked_Access);
|
||||||
|
--File_Stream: Stream.File_Stream_Record := (Name => File_Name'Unchecked_Access);
|
||||||
|
File_Stream: Stream.File_Stream_Record;
|
||||||
|
|
||||||
|
procedure Allocate_Stream (Interp: in out S.Interpreter_Record;
|
||||||
|
Name: access S.Object_String;
|
||||||
|
Result: in out S.Stream_Pointer) is
|
||||||
|
subtype FSR is Stream.File_Stream_Record;
|
||||||
|
type FSP is access all FSR;
|
||||||
|
package P is new H2.Pool (FSR, FSP);
|
||||||
|
|
||||||
|
X: FSP;
|
||||||
|
for X'Address use Result'Address;
|
||||||
|
pragma Import (Ada, X);
|
||||||
|
begin
|
||||||
|
X := P.Allocate (S.Get_Storage_Pool(Interp));
|
||||||
|
X.Name := Stream.Object_String_Pointer(Name);
|
||||||
|
end Allocate_Stream;
|
||||||
|
|
||||||
|
procedure Deallocate_Stream (Interp: in out S.Interpreter_Record;
|
||||||
|
Source: in out S.Stream_Pointer) is
|
||||||
|
subtype FSR is Stream.File_Stream_Record;
|
||||||
|
type FSP is access all FSR;
|
||||||
|
package P is new H2.Pool (FSR, FSP);
|
||||||
|
|
||||||
|
X: FSP;
|
||||||
|
for X'Address use Source'Address;
|
||||||
|
pragma Import (Ada, X);
|
||||||
|
begin
|
||||||
|
P.Deallocate (X, S.Get_Storage_Pool(Interp));
|
||||||
|
end Deallocate_Stream;
|
||||||
|
|
||||||
|
-- --procedure Dealloc_Stream is new Ada.Unchecked_Deallocation (Stream_Record'Class, Stream_Pointer);
|
||||||
|
-- --procedure Destroy_Stream (Stream: in out Stream_Pointer) renames Dealloc_Stream;
|
||||||
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Ada.Text_Io.Put_Line (S.Object_Word'Image(S.Object_Pointer_Bytes));
|
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, 2_000_000, Pool'Unchecked_Access);
|
||||||
--S.Open (SI, null);
|
--S.Open (SI, null);
|
||||||
|
|
||||||
|
File_Stream.Name := File_Name'Unchecked_Access;
|
||||||
|
S.Set_Input_Stream (SI, File_Stream); -- specify main input stream
|
||||||
|
--S.Set_Output_Stream (SI, Stream); -- specify main output stream.
|
||||||
|
S.Read (SI, I);
|
||||||
S.Make_Test_Object (SI, I);
|
S.Make_Test_Object (SI, I);
|
||||||
|
|
||||||
S.Evaluate (SI, I, O);
|
S.Evaluate (SI, I, O);
|
||||||
S.Print (SI, I);
|
S.Print (SI, I);
|
||||||
Ada.Text_IO.Put_Line ("-------------------------------------------");
|
Ada.Text_IO.Put_Line ("-------------------------------------------");
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
with "@abs_builddir@/../lib/libh2";
|
with "@abs_builddir@/../lib/libh2";
|
||||||
|
|
||||||
project H2_Scheme is
|
project Scheme is
|
||||||
|
|
||||||
for Main use ("scheme");
|
for Main use ("scheme");
|
||||||
|
|
||||||
@ -15,13 +15,15 @@ project H2_Scheme is
|
|||||||
for Source_Files use (
|
for Source_Files use (
|
||||||
"storage.ads",
|
"storage.ads",
|
||||||
"storage.adb",
|
"storage.adb",
|
||||||
|
"stream.ads",
|
||||||
|
"stream.adb",
|
||||||
"scheme.adb"
|
"scheme.adb"
|
||||||
);
|
);
|
||||||
for Object_Dir use "@ADA_OBJDIR@";
|
for Object_Dir use "@ADA_OBJDIR@";
|
||||||
|
|
||||||
package Compiler is
|
package Compiler is
|
||||||
for Default_Switches ("Ada") use (
|
for Default_Switches ("Ada") use (
|
||||||
"-gnata", "-gnato", "-gnatN", "-gnatwl",
|
"-gnata", "-gnato", "-gnatN", "-gnatwl", "-gnat95"
|
||||||
"-I@abs_srcdir@/../lib"
|
"-I@abs_srcdir@/../lib"
|
||||||
);
|
);
|
||||||
end Compiler;
|
end Compiler;
|
||||||
@ -30,6 +32,6 @@ project H2_Scheme is
|
|||||||
for Executable ("scheme.adb") use "h2scm";
|
for Executable ("scheme.adb") use "h2scm";
|
||||||
end Builder;
|
end Builder;
|
||||||
|
|
||||||
end H2_Scheme;
|
end Scheme;
|
||||||
|
|
||||||
|
|
||||||
|
87
cmd/stream.adb
Normal file
87
cmd/stream.adb
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
|
||||||
|
package body Stream is
|
||||||
|
|
||||||
|
------------------------------------------------------------------
|
||||||
|
|
||||||
|
procedure Open (Stream: in out String_Input_Stream_Record) is
|
||||||
|
begin
|
||||||
|
Ada.Text_IO.Put_Line ("OPEN STRING STREAM");
|
||||||
|
Stream.Pos := 0;
|
||||||
|
end Open;
|
||||||
|
|
||||||
|
procedure Close (Stream: in out String_Input_Stream_Record) is
|
||||||
|
begin
|
||||||
|
Ada.Text_IO.Put_Line ("CLOSE STRING STREAM");
|
||||||
|
Stream.Pos := Stream.Str'Last;
|
||||||
|
end Close;
|
||||||
|
|
||||||
|
procedure Read (Stream: in out String_Input_Stream_Record;
|
||||||
|
Data: out S.Object_String;
|
||||||
|
Last: out Standard.Natural) is
|
||||||
|
Avail: Standard.Natural;
|
||||||
|
begin
|
||||||
|
Avail := Stream.Str'Last - Stream.Pos;
|
||||||
|
if Avail <= 0 then
|
||||||
|
-- EOF
|
||||||
|
Last := Data'First - 1;
|
||||||
|
else
|
||||||
|
if Avail > Data'Length then
|
||||||
|
Avail := Data'Length;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
Data(Data'First .. Avail) := Stream.Str(Stream.Pos + 1..Stream.Pos + Avail);
|
||||||
|
Stream.Pos := Stream.Pos + Avail;
|
||||||
|
Last := Data'First + Avail - 1;
|
||||||
|
end if;
|
||||||
|
end Read;
|
||||||
|
|
||||||
|
procedure Write (Stream: in out String_Input_Stream_Record;
|
||||||
|
Data: out S.Object_String;
|
||||||
|
Last: out Standard.Natural) is
|
||||||
|
begin
|
||||||
|
--raise S.Stream_Error;
|
||||||
|
Last := Data'First - 1;
|
||||||
|
end Write;
|
||||||
|
|
||||||
|
------------------------------------------------------------------
|
||||||
|
|
||||||
|
procedure Open (Stream: in out File_Stream_Record) is
|
||||||
|
begin
|
||||||
|
Ada.Text_IO.Put_Line ("OPEN File STREAM");
|
||||||
|
Ada.Text_IO.Open (Stream.Handle, Ada.Text_IO.In_File, Stream.Name.all);
|
||||||
|
end Open;
|
||||||
|
|
||||||
|
procedure Close (Stream: in out File_Stream_Record) is
|
||||||
|
begin
|
||||||
|
Ada.Text_IO.Put_Line ("CLOSE File STREAM");
|
||||||
|
Ada.Text_IO.Close (Stream.Handle);
|
||||||
|
end Close;
|
||||||
|
|
||||||
|
procedure Read (Stream: in out File_Stream_Record;
|
||||||
|
Data: out S.Object_String;
|
||||||
|
Last: out Standard.Natural) is
|
||||||
|
begin
|
||||||
|
for I in Data'First .. Data'Last loop
|
||||||
|
begin
|
||||||
|
Ada.Text_IO.Get_Immediate (Stream.Handle, Data(I));
|
||||||
|
exception
|
||||||
|
when Ada.Text_IO.End_Error =>
|
||||||
|
Last := I - 1;
|
||||||
|
return;
|
||||||
|
-- other exceptions must be just raised to indicate errors
|
||||||
|
end;
|
||||||
|
end loop;
|
||||||
|
Last := Data'Last;
|
||||||
|
end Read;
|
||||||
|
|
||||||
|
procedure Write (Stream: in out File_Stream_Record;
|
||||||
|
Data: out S.Object_String;
|
||||||
|
Last: out Standard.Natural) is
|
||||||
|
begin
|
||||||
|
--raise S.Stream_Error;
|
||||||
|
Last := Data'First - 1;
|
||||||
|
end Write;
|
||||||
|
|
||||||
|
------------------------------------------------------------------
|
||||||
|
|
||||||
|
end Stream;
|
48
cmd/stream.ads
Normal file
48
cmd/stream.ads
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
with H2.Scheme;
|
||||||
|
with Ada.Text_IO;
|
||||||
|
|
||||||
|
package Stream is
|
||||||
|
|
||||||
|
package S renames H2.Scheme;
|
||||||
|
|
||||||
|
------------------------------------------------------------
|
||||||
|
type Object_String_Pointer is access all S.Object_String;
|
||||||
|
type String_Input_Stream_Record(Str: Object_String_Pointer) is new S.Stream_Record with record
|
||||||
|
Pos: Standard.Natural := 0;
|
||||||
|
end record;
|
||||||
|
|
||||||
|
--type String_Input_Stream_Record(Len: Standard.Natural) is new S.Stream_Record with record
|
||||||
|
-- Pos: Standard.Natural := 0;
|
||||||
|
-- Str: S.Object_String (1 .. Len) := (others => ' ');
|
||||||
|
--end record;
|
||||||
|
|
||||||
|
procedure Open (Stream: in out String_Input_Stream_Record);
|
||||||
|
procedure Close (Stream: in out String_Input_Stream_Record);
|
||||||
|
procedure Read (Stream: in out String_Input_Stream_Record;
|
||||||
|
Data: out S.Object_String;
|
||||||
|
Last: out Standard.Natural);
|
||||||
|
procedure Write (Stream: in out String_Input_Stream_Record;
|
||||||
|
Data: out S.Object_String;
|
||||||
|
Last: out Standard.Natural);
|
||||||
|
|
||||||
|
------------------------------------------------------------
|
||||||
|
--type File_Stream_Record(Name: Object_String_Pointer) is new S.Stream_Record with record
|
||||||
|
-- Handle: Ada.Text_IO.File_Type;
|
||||||
|
--end record;
|
||||||
|
|
||||||
|
type File_Stream_Record is new S.Stream_Record with record
|
||||||
|
Name: Object_String_Pointer;
|
||||||
|
Handle: Ada.Text_IO.File_Type;
|
||||||
|
end record;
|
||||||
|
|
||||||
|
procedure Open (Stream: in out File_Stream_Record);
|
||||||
|
procedure Close (Stream: in out File_Stream_Record);
|
||||||
|
procedure Read (Stream: in out File_Stream_Record;
|
||||||
|
Data: out S.Object_String;
|
||||||
|
Last: out Standard.Natural);
|
||||||
|
procedure Write (Stream: in out File_Stream_Record;
|
||||||
|
Data: out S.Object_String;
|
||||||
|
Last: out Standard.Natural);
|
||||||
|
|
||||||
|
end Stream;
|
||||||
|
|
@ -28,30 +28,30 @@ package body H2.Pool is
|
|||||||
end if;
|
end if;
|
||||||
end Allocate;
|
end Allocate;
|
||||||
|
|
||||||
function Allocate (Source: in Normal_Type;
|
-- function Allocate (Source: in Normal_Type;
|
||||||
Pool: in Storage_Pool_Pointer := null) return Pointer_Type is
|
-- Pool: in Storage_Pool_Pointer := null) return Pointer_Type is
|
||||||
P: Storage_Pool_Pointer;
|
-- P: Storage_Pool_Pointer;
|
||||||
begin
|
-- begin
|
||||||
if Pool = null then
|
-- if Pool = null then
|
||||||
P := Storage_Pool;
|
-- P := Storage_Pool;
|
||||||
else
|
-- else
|
||||||
P := Pool;
|
-- P := Pool;
|
||||||
end if;
|
-- end if;
|
||||||
|
--
|
||||||
if P = null then
|
-- if P = null then
|
||||||
return new Normal_Type'(Source);
|
-- return new Normal_Type'(Source);
|
||||||
else
|
-- else
|
||||||
declare
|
-- declare
|
||||||
type Pooled_Pointer is access Normal_Type;
|
-- type Pooled_Pointer is access Normal_Type;
|
||||||
for Pooled_Pointer'Storage_Pool use P.all;
|
-- for Pooled_Pointer'Storage_Pool use P.all;
|
||||||
function To_Pointer_Type is new Ada.Unchecked_Conversion (Pooled_Pointer, Pointer_Type);
|
-- function To_Pointer_Type is new Ada.Unchecked_Conversion (Pooled_Pointer, Pointer_Type);
|
||||||
Tmp: Pooled_Pointer;
|
-- Tmp: Pooled_Pointer;
|
||||||
begin
|
-- begin
|
||||||
Tmp := new Normal_Type'(Source);
|
-- Tmp := new Normal_Type'(Source);
|
||||||
return To_Pointer_Type (Tmp);
|
-- return To_Pointer_Type (Tmp);
|
||||||
end;
|
-- end;
|
||||||
end if;
|
-- end if;
|
||||||
end Allocate;
|
-- end Allocate;
|
||||||
|
|
||||||
procedure Deallocate (Target: in out Pointer_Type;
|
procedure Deallocate (Target: in out Pointer_Type;
|
||||||
Pool: in Storage_Pool_Pointer := null) is
|
Pool: in Storage_Pool_Pointer := null) is
|
||||||
|
@ -7,16 +7,17 @@
|
|||||||
--------------------------------------------------------------------
|
--------------------------------------------------------------------
|
||||||
|
|
||||||
generic
|
generic
|
||||||
type Normal_Type is private;
|
--type Normal_Type is private;
|
||||||
type Pointer_Type is access Normal_Type;
|
type Normal_Type is limited private;
|
||||||
|
type Pointer_Type is access all Normal_Type;
|
||||||
Storage_Pool: in Storage_Pool_Pointer := null;
|
Storage_Pool: in Storage_Pool_Pointer := null;
|
||||||
|
|
||||||
package H2.Pool is
|
package H2.Pool is
|
||||||
|
|
||||||
function Allocate (Pool: in Storage_Pool_Pointer := null) return Pointer_Type;
|
function Allocate (Pool: in Storage_Pool_Pointer := null) return Pointer_Type;
|
||||||
|
|
||||||
function Allocate (Source: in Normal_Type;
|
-- function Allocate (Source: in Normal_Type;
|
||||||
Pool: in Storage_Pool_Pointer := null) return Pointer_Type;
|
-- Pool: in Storage_Pool_Pointer := null) return Pointer_Type;
|
||||||
|
|
||||||
procedure Deallocate (Target: in out Pointer_Type;
|
procedure Deallocate (Target: in out Pointer_Type;
|
||||||
Pool: in Storage_Pool_Pointer := null);
|
Pool: in Storage_Pool_Pointer := null);
|
||||||
|
@ -22,17 +22,21 @@ package body H2.Scheme is
|
|||||||
type Heap_Element_Pointer is access all Heap_Element;
|
type Heap_Element_Pointer is access all Heap_Element;
|
||||||
for Heap_Element_Pointer'Size use Object_Pointer_Bits; -- ensure that it can be overlayed by an ObjectPointer
|
for Heap_Element_Pointer'Size use Object_Pointer_Bits; -- ensure that it can be overlayed by an ObjectPointer
|
||||||
|
|
||||||
|
|
||||||
type Thin_Heap_Element_Array is array (1 .. Heap_Size'Last) of Heap_Element;
|
type Thin_Heap_Element_Array is array (1 .. Heap_Size'Last) of Heap_Element;
|
||||||
type Thin_Heap_Element_Array_Pointer is access all Thin_Heap_Element_Array;
|
type Thin_Heap_Element_Array_Pointer is access all Thin_Heap_Element_Array;
|
||||||
for Thin_Heap_Element_Array_Pointer'Size use Object_Pointer_Bits;
|
for Thin_Heap_Element_Array_Pointer'Size use Object_Pointer_Bits;
|
||||||
|
|
||||||
subtype Opcode_Type is Object_Integer range 0 .. 5;
|
subtype Moved_Object_Record is Object_Record (Moved_Object, 0);
|
||||||
|
|
||||||
|
subtype Opcode_Type is Object_Integer range 0 .. 6;
|
||||||
Opcode_Exit: constant Opcode_Type := Opcode_Type'(0);
|
Opcode_Exit: constant Opcode_Type := Opcode_Type'(0);
|
||||||
Opcode_Evaluate_Object: constant Opcode_Type := Opcode_Type'(1);
|
Opcode_Evaluate_Object: constant Opcode_Type := Opcode_Type'(1);
|
||||||
Opcode_Evaluate_Group: constant Opcode_Type := Opcode_Type'(2);
|
Opcode_Evaluate_Group: constant Opcode_Type := Opcode_Type'(2);
|
||||||
Opcode_Evaluate_Syntax: constant Opcode_Type := Opcode_Type'(3);
|
Opcode_Evaluate_Syntax: constant Opcode_Type := Opcode_Type'(3);
|
||||||
Opcode_Evaluate_Procedure: constant Opcode_Type := Opcode_Type'(4);
|
Opcode_Evaluate_Procedure: constant Opcode_Type := Opcode_Type'(4);
|
||||||
Opcode_Apply: constant Opcode_Type := Opcode_Type'(5);
|
Opcode_Apply: constant Opcode_Type := Opcode_Type'(5);
|
||||||
|
Opcode_Read_Object: constant Opcode_Type := Opcode_Type'(6);
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- COMMON OBJECTS
|
-- COMMON OBJECTS
|
||||||
@ -58,13 +62,10 @@ package body H2.Scheme is
|
|||||||
Closure_Code_Index: constant Pointer_Object_Size := 1;
|
Closure_Code_Index: constant Pointer_Object_Size := 1;
|
||||||
Closure_Environment_Index: constant Pointer_Object_Size := 2;
|
Closure_Environment_Index: constant Pointer_Object_Size := 2;
|
||||||
|
|
||||||
Pair_Object_Size: constant Pointer_Object_Size := 3;
|
procedure Set_New_Location (Object: in Object_Pointer;
|
||||||
Pair_Key_Size: constant Pointer_Object_Size := 1;
|
Ptr: in Heap_Element_Pointer);
|
||||||
Pair_Value_Size: constant Pointer_Object_Size := 2;
|
procedure Set_New_Location (Object: in Object_Pointer;
|
||||||
Pair_Link_Size: constant Pointer_Object_Size := 3;
|
Ptr: in Object_Pointer);
|
||||||
|
|
||||||
procedure Set_New_Location (Object: in Object_Pointer; Ptr: in Heap_Element_Pointer);
|
|
||||||
procedure Set_New_Location (Object: in Object_Pointer; Ptr: in Object_Pointer);
|
|
||||||
pragma Inline (Set_New_Location);
|
pragma Inline (Set_New_Location);
|
||||||
|
|
||||||
function Get_New_Location (Object: in Object_Pointer) return Object_Pointer;
|
function Get_New_Location (Object: in Object_Pointer) return Object_Pointer;
|
||||||
@ -117,7 +118,6 @@ package body H2.Scheme is
|
|||||||
return Get_Pointer_Type(Pointer) = Object_Pointer_Type_Byte;
|
return Get_Pointer_Type(Pointer) = Object_Pointer_Type_Byte;
|
||||||
end Is_Byte;
|
end Is_Byte;
|
||||||
|
|
||||||
|
|
||||||
function Integer_To_Pointer (Int: in Object_Integer) return Object_Pointer is
|
function Integer_To_Pointer (Int: in Object_Integer) return Object_Pointer is
|
||||||
Pointer: Object_Pointer;
|
Pointer: Object_Pointer;
|
||||||
Word: Object_Word;
|
Word: Object_Word;
|
||||||
@ -389,7 +389,6 @@ package body H2.Scheme is
|
|||||||
-- object takes up the smallest space that a valid object can take. So
|
-- object takes up the smallest space that a valid object can take. So
|
||||||
-- it is safe to overlay it on any normal objects.
|
-- it is safe to overlay it on any normal objects.
|
||||||
procedure Set_New_Location (Object: in Object_Pointer; Ptr: in Heap_Element_Pointer) is
|
procedure Set_New_Location (Object: in Object_Pointer; Ptr: in Heap_Element_Pointer) is
|
||||||
subtype Moved_Object_Record is Object_Record (Moved_Object, 0);
|
|
||||||
Moved_Object: Moved_Object_Record;
|
Moved_Object: Moved_Object_Record;
|
||||||
for Moved_Object'Address use Object.all'Address;
|
for Moved_Object'Address use Object.all'Address;
|
||||||
-- pramga Import must not be specified here as I'm counting
|
-- pramga Import must not be specified here as I'm counting
|
||||||
@ -402,7 +401,6 @@ package body H2.Scheme is
|
|||||||
end Set_New_Location;
|
end Set_New_Location;
|
||||||
|
|
||||||
procedure Set_New_Location (Object: in Object_Pointer; Ptr: in Object_Pointer) is
|
procedure Set_New_Location (Object: in Object_Pointer; Ptr: in Object_Pointer) is
|
||||||
subtype Moved_Object_Record is Object_Record (Moved_Object, 0);
|
|
||||||
Moved_Object: Moved_Object_Record;
|
Moved_Object: Moved_Object_Record;
|
||||||
for Moved_Object'Address use Object.all'Address;
|
for Moved_Object'Address use Object.all'Address;
|
||||||
--pragma Import (Ada, Moved_Object); -- this must not be used.
|
--pragma Import (Ada, Moved_Object); -- this must not be used.
|
||||||
@ -419,14 +417,21 @@ package body H2.Scheme is
|
|||||||
Heap_Bytes: in Heap_Size) return Heap_Element_Pointer is
|
Heap_Bytes: in Heap_Size) return Heap_Element_Pointer is
|
||||||
Avail: Heap_Size;
|
Avail: Heap_Size;
|
||||||
Result: Heap_Element_Pointer;
|
Result: Heap_Element_Pointer;
|
||||||
|
Real_Bytes: Heap_Size := Heap_Bytes;
|
||||||
begin
|
begin
|
||||||
|
if Real_Bytes < Moved_Object_Record'Max_Size_In_Storage_Elements then
|
||||||
|
-- Guarantee the minimum object size to be greater than or
|
||||||
|
-- equal to the size of a moved object for GC to work.
|
||||||
|
Real_Bytes := Moved_Object_Record'Max_Size_In_Storage_Elements;
|
||||||
|
end if;
|
||||||
|
|
||||||
Avail := Heap.Size - Heap.Bound;
|
Avail := Heap.Size - Heap.Bound;
|
||||||
if Heap_Bytes > Avail then
|
if Real_Bytes > Avail then
|
||||||
return null;
|
return null;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
Result := Heap.Space(Heap.Bound + 1)'Unchecked_Access;
|
Result := Heap.Space(Heap.Bound + 1)'Unchecked_Access;
|
||||||
Heap.Bound := Heap.Bound + Heap_Bytes;
|
Heap.Bound := Heap.Bound + Real_Bytes;
|
||||||
return Result;
|
return Result;
|
||||||
end Allocate_Bytes_In_Heap;
|
end Allocate_Bytes_In_Heap;
|
||||||
|
|
||||||
@ -446,7 +451,7 @@ package body H2.Scheme is
|
|||||||
-- Target_Object_Record'Max_Size_In_Stroage_Elements were not
|
-- Target_Object_Record'Max_Size_In_Stroage_Elements were not
|
||||||
-- always correct. For example, for a character object containing
|
-- always correct. For example, for a character object containing
|
||||||
-- the string "lambda", Target_Object.all'Size returned 72 while
|
-- the string "lambda", Target_Object.all'Size returned 72 while
|
||||||
-- it's supposed to be 96.
|
-- it's supposed to be 96. Use Copy_Object_With_Size() below instead.
|
||||||
Target_Object.all := Source.all;
|
Target_Object.all := Source.all;
|
||||||
pragma Assert (Source.all'Size = Target_Object.all'Size);
|
pragma Assert (Source.all'Size = Target_Object.all'Size);
|
||||||
end Copy_Object;
|
end Copy_Object;
|
||||||
@ -1313,6 +1318,7 @@ Put_String (To_Thin_String_Pointer (Result));
|
|||||||
Heap := Pool.Allocate;
|
Heap := Pool.Allocate;
|
||||||
end;
|
end;
|
||||||
end loop;
|
end loop;
|
||||||
|
|
||||||
exception
|
exception
|
||||||
when others =>
|
when others =>
|
||||||
Deinitialize_Heap (Interp);
|
Deinitialize_Heap (Interp);
|
||||||
@ -1376,33 +1382,60 @@ Put_String (To_Thin_String_Pointer (Result));
|
|||||||
Interp.Root_Table := Nil_Pointer;
|
Interp.Root_Table := Nil_Pointer;
|
||||||
Interp.Symbol_Table := Nil_Pointer;
|
Interp.Symbol_Table := Nil_Pointer;
|
||||||
|
|
||||||
Interp.Line_Pos := Interp.Line'First - 1;
|
Interp.Input.Stream := null;
|
||||||
Interp.Line_Last := Interp.Line'First - 1;
|
Interp.IO := Interp.Input'Unchecked_Access;
|
||||||
|
|
||||||
-- TODO: disallow garbage collecion during initialization.
|
-- TODO: disallow garbage collecion during initialization.
|
||||||
|
Text_IO.Put_Line ("1111111111");
|
||||||
Initialize_Heap (Initial_Heap_Size);
|
Initialize_Heap (Initial_Heap_Size);
|
||||||
Interp.Mark := Make_Mark (Interp.Self, 0); -- to indicate the end of cons evluation
|
Interp.Mark := Make_Mark (Interp.Self, 0); -- to indicate the end of cons evluation
|
||||||
Interp.Root_Environment := Make_Environment (Interp.Self, Nil_Pointer);
|
Interp.Root_Environment := Make_Environment (Interp.Self, Nil_Pointer);
|
||||||
Interp.Environment := Interp.Root_Environment;
|
Interp.Environment := Interp.Root_Environment;
|
||||||
Make_Syntax_Objects;
|
Make_Syntax_Objects;
|
||||||
Make_Procedure_Objects;
|
Make_Procedure_Objects;
|
||||||
|
Text_IO.Put_Line ("99999");
|
||||||
|
|
||||||
exception
|
exception
|
||||||
when others =>
|
when others =>
|
||||||
Deinitialize_Heap (Interp);
|
Deinitialize_Heap (Interp);
|
||||||
end Open;
|
end Open;
|
||||||
|
|
||||||
|
procedure Close_Stream (Stream: in out Stream_Pointer) is
|
||||||
|
begin
|
||||||
|
Close (Stream.all);
|
||||||
|
Stream := null;
|
||||||
|
exception
|
||||||
|
when others =>
|
||||||
|
Stream := null; -- ignore exception
|
||||||
|
end Close_Stream;
|
||||||
|
|
||||||
|
procedure Close_All_Streams (Interp: in out Interpreter_Record) is
|
||||||
|
begin
|
||||||
|
-- TODO: close all cascaded streams if any.
|
||||||
|
if Interp.Input.Stream /= null then
|
||||||
|
Close_Stream (Interp.Input.Stream);
|
||||||
|
end if;
|
||||||
|
end Close_All_Streams;
|
||||||
|
|
||||||
procedure Close (Interp: in out Interpreter_Record) is
|
procedure Close (Interp: in out Interpreter_Record) is
|
||||||
begin
|
begin
|
||||||
|
Close_All_Streams (Interp);
|
||||||
Deinitialize_Heap (Interp);
|
Deinitialize_Heap (Interp);
|
||||||
end Close;
|
end Close;
|
||||||
|
|
||||||
|
function Get_Storage_Pool (Interp: in Interpreter_Record) return Storage_Pool_Pointer is
|
||||||
|
begin
|
||||||
|
return Interp.Storage_Pool;
|
||||||
|
end Get_Storage_Pool;
|
||||||
|
|
||||||
procedure Set_Option (Interp: in out Interpreter_Record;
|
procedure Set_Option (Interp: in out Interpreter_Record;
|
||||||
Option: in Option_Record) is
|
Option: in Option_Record) is
|
||||||
begin
|
begin
|
||||||
case Option.Kind is
|
case Option.Kind is
|
||||||
when Trait_Option =>
|
when Trait_Option =>
|
||||||
Interp.Trait := Option;
|
Interp.Trait := Option;
|
||||||
|
when Stream_Option =>
|
||||||
|
Interp.Stream := Option;
|
||||||
end case;
|
end case;
|
||||||
end Set_Option;
|
end Set_Option;
|
||||||
|
|
||||||
@ -1410,28 +1443,115 @@ Put_String (To_Thin_String_Pointer (Result));
|
|||||||
Option: in out Option_Record) is
|
Option: in out Option_Record) is
|
||||||
begin
|
begin
|
||||||
case Option.Kind is
|
case Option.Kind is
|
||||||
when Trait_Option =>
|
when Trait_Option =>
|
||||||
Option := Interp.Trait;
|
Option := Interp.Trait;
|
||||||
|
when Stream_Option =>
|
||||||
|
Option := Interp.Stream;
|
||||||
end case;
|
end case;
|
||||||
end Get_Option;
|
end Get_Option;
|
||||||
|
|
||||||
|
procedure Set_Input_Stream (Interp: in out Interpreter_Record;
|
||||||
|
Stream: in out Stream_Record'Class) is
|
||||||
|
begin
|
||||||
|
--Open (Stream, Interp);
|
||||||
|
Open (Stream);
|
||||||
|
|
||||||
|
-- if Open raised an exception, it wouldn't reach here.
|
||||||
|
-- so the existing stream still remains intact.
|
||||||
|
if Interp.Input.Stream /= null then
|
||||||
|
Close_Stream (Interp.Input.Stream);
|
||||||
|
end if;
|
||||||
|
|
||||||
|
--Interp.Input := IO_Record'(
|
||||||
|
-- Stream => Stream'Unchecked_Access,
|
||||||
|
-- Data => (others => ' '),
|
||||||
|
-- Pos => Interp.Input.Data'First - 1,
|
||||||
|
-- Last => Interp.Input.Data'First - 1,
|
||||||
|
-- Flags => 0
|
||||||
|
--);
|
||||||
|
Interp.Input.Stream := Stream'Unchecked_Access;
|
||||||
|
Interp.Input.Pos := Interp.Input.Data'First - 1;
|
||||||
|
Interp.Input.Last := Interp.Input.Data'First - 1;
|
||||||
|
Interp.Input.Flags := 0;
|
||||||
|
end Set_Input_Stream;
|
||||||
|
|
||||||
|
--procedure Set_Output_Stream (Interp: in out Interpreter_Record;
|
||||||
|
-- Stream: in out Stream_Record'Class) is
|
||||||
|
--begin
|
||||||
|
--
|
||||||
|
--end Set_Output_Stream;
|
||||||
|
|
||||||
|
procedure Start_Input_Stream (Interp: in out Interpreter_Record;
|
||||||
|
Name: access Object_String) is
|
||||||
|
package IO_Pool is new H2.Pool (IO_Record, IO_Pointer, Interp.Storage_Pool);
|
||||||
|
IO: IO_Pointer;
|
||||||
|
begin
|
||||||
|
IO := IO_Pool.Allocate;
|
||||||
|
begin
|
||||||
|
Interp.Stream.Allocate (Interp, Name, IO.Stream);
|
||||||
|
exception
|
||||||
|
when others =>
|
||||||
|
IO_Pool.Deallocate (IO);
|
||||||
|
raise;
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Open (IO.Stream.all);
|
||||||
|
exception
|
||||||
|
when others =>
|
||||||
|
Interp.Stream.Deallocate (Interp, IO.Stream);
|
||||||
|
IO_Pool.Deallocate (IO);
|
||||||
|
raise;
|
||||||
|
end;
|
||||||
|
IO.Pos := IO.Data'First - 1;
|
||||||
|
IO.Last := IO.Data'First - 1;
|
||||||
|
IO.Flags := 0;
|
||||||
|
|
||||||
|
IO.Next := Interp.IO;
|
||||||
|
Interp.IO := IO;
|
||||||
|
end Start_Input_Stream;
|
||||||
|
|
||||||
|
procedure Stop_Input_Stream (Interp: in out Interpreter_Record) is
|
||||||
|
package IO_Pool is new H2.Pool (IO_Record, IO_Pointer, Interp.Storage_Pool);
|
||||||
|
IO: IO_Pointer;
|
||||||
|
begin
|
||||||
|
pragma Assert (Interp.IO /= Interp.Input'Unchecked_Access);
|
||||||
|
IO := Interp.IO;
|
||||||
|
Interp.IO := IO.Next;
|
||||||
|
|
||||||
|
Interp.Stream.Deallocate (Interp, IO.Stream);
|
||||||
|
IO_Pool.Deallocate (IO);
|
||||||
|
end Stop_Input_Stream;
|
||||||
|
|
||||||
procedure Read (Interp: in out Interpreter_Record;
|
procedure Read (Interp: in out Interpreter_Record;
|
||||||
Result: out Object_Pointer) is
|
Result: out Object_Pointer) is
|
||||||
|
|
||||||
EOF_Error: exception;
|
End_Error: exception;
|
||||||
|
|
||||||
function Get_Character return Object_Character is
|
function Get_Character return Object_Character is
|
||||||
begin
|
begin
|
||||||
if Interp.Line_Pos >= Interp.Line_Last then
|
-- TODO: calculate Interp.Input.Row, Interp.Input.Column
|
||||||
if Text_IO.End_Of_File then
|
if Interp.Input.Pos >= Interp.Input.Last then
|
||||||
raise EOF_Error;
|
if Interp.Input.Flags /= 0 then
|
||||||
|
-- an error has occurred previously.
|
||||||
|
raise End_Error;
|
||||||
end if;
|
end if;
|
||||||
Text_IO.Get_Line (Interp.Line, Interp.Line_Last);
|
|
||||||
Interp.Line_Pos := Interp.Line'First - 1;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
Interp.Line_Pos := Interp.Line_Pos + 1;
|
Interp.Input.Pos := Interp.Input.Data'First - 1;
|
||||||
return Interp.Line(Interp.Line_Pos);
|
begin
|
||||||
|
Read (Interp.Input.Stream.all, Interp.Input.Data, Interp.Input.Last);
|
||||||
|
exception
|
||||||
|
when others =>
|
||||||
|
Interp.Input.Flags := Interp.Input.Flags and IO_Error_Occurred;
|
||||||
|
raise End_Error; -- TODO: change the exception name
|
||||||
|
end;
|
||||||
|
if Interp.Input.Last < Interp.Input.Data'First then
|
||||||
|
Interp.Input.Flags := Interp.Input.Flags and IO_End_Reached;
|
||||||
|
raise End_Error;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
Interp.Input.Pos := Interp.Input.Pos + 1;
|
||||||
|
return Interp.Input.Data(Interp.Input.Pos);
|
||||||
end Get_Character;
|
end Get_Character;
|
||||||
|
|
||||||
procedure Skip_Space is
|
procedure Skip_Space is
|
||||||
@ -1439,7 +1559,7 @@ Put_String (To_Thin_String_Pointer (Result));
|
|||||||
null;
|
null;
|
||||||
end Skip_Space;
|
end Skip_Space;
|
||||||
|
|
||||||
--function Get_Token is
|
--function Get_Token return Token_Type is
|
||||||
--begin
|
--begin
|
||||||
-- null;
|
-- null;
|
||||||
--end Get_Token;
|
--end Get_Token;
|
||||||
@ -1452,13 +1572,23 @@ Put_String (To_Thin_String_Pointer (Result));
|
|||||||
Stack: Object_Pointer;
|
Stack: Object_Pointer;
|
||||||
Opcode: Object_Integer;
|
Opcode: Object_Integer;
|
||||||
Operand: Object_Pointer;
|
Operand: Object_Pointer;
|
||||||
|
|
||||||
|
C: Object_Character;
|
||||||
begin
|
begin
|
||||||
--Opcode := 1;
|
--Opcode := 1;
|
||||||
--loop
|
--loop
|
||||||
-- case Opcode is
|
-- case Opcode is
|
||||||
-- when 1 =>
|
-- when 1 =>
|
||||||
--end loop;
|
--end loop;
|
||||||
null;
|
loop
|
||||||
|
C := Get_Character;
|
||||||
|
Text_IO.Put (C);
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
exception
|
||||||
|
when End_Error =>
|
||||||
|
TEXT_IO.New_Line;
|
||||||
|
Text_IO.Put_Line ("END OF INPUT...");
|
||||||
end Read;
|
end Read;
|
||||||
|
|
||||||
procedure Print (Interp: in out Interpreter_Record;
|
procedure Print (Interp: in out Interpreter_Record;
|
||||||
@ -1694,7 +1824,7 @@ Interp.Root_Table := Make_Symbol (Interp.Self, "lambda");
|
|||||||
|
|
||||||
--X := Make_Cons (Interp.Self, Nil_Pointer, Make_Cons (Interp.Self, Nil_Pointer, Integer_To_Pointer(TEN)));
|
--X := Make_Cons (Interp.Self, Nil_Pointer, Make_Cons (Interp.Self, Nil_Pointer, Integer_To_Pointer(TEN)));
|
||||||
--X := Make_Cons (Interp.Self, Nil_Pointer, Nil_Pointer);
|
--X := Make_Cons (Interp.Self, Nil_Pointer, Nil_Pointer);
|
||||||
Read (Interp, X);
|
--Read (Interp, X);
|
||||||
Print (Interp, X);
|
Print (Interp, X);
|
||||||
|
|
||||||
end Evaluatex;
|
end Evaluatex;
|
||||||
@ -2301,6 +2431,62 @@ Print (Interp, Operand);
|
|||||||
end case;
|
end case;
|
||||||
end Apply;
|
end Apply;
|
||||||
|
|
||||||
|
procedure Read_Object is
|
||||||
|
|
||||||
|
-- function Get_Character return Object_Character is
|
||||||
|
-- begin
|
||||||
|
-- if Interp.Line_Pos >= Interp.Line_Last then
|
||||||
|
-- if Text_IO.End_Of_File then
|
||||||
|
-- raise EOF_Error;
|
||||||
|
-- end if;
|
||||||
|
-- Text_IO.Get_Line (Interp.Line, Interp.Line_Last);
|
||||||
|
-- Interp.Line_Pos := Interp.Line'First - 1;
|
||||||
|
-- end if;
|
||||||
|
--
|
||||||
|
-- Interp.Line_Pos := Interp.Line_Pos + 1;
|
||||||
|
-- return Interp.Line(Interp.Line_Pos);
|
||||||
|
-- end Get_Character;
|
||||||
|
|
||||||
|
-- type Input_Object_Record is
|
||||||
|
-- end record;
|
||||||
|
-- Read (Input_Object_Record);
|
||||||
|
-- Write (Input_Object_Record);
|
||||||
|
-- Close (Input_Object_Record);
|
||||||
|
--
|
||||||
|
-- type Input_Object_Class_Pointer is access all Input_Object_Record'Class;
|
||||||
|
--
|
||||||
|
-- type Input_Record is record
|
||||||
|
-- Pos: Standard.Natural;
|
||||||
|
-- Last: Standard.Natural;
|
||||||
|
-- Buffer: Object_String (1 .. 1024);
|
||||||
|
-- Handle: Input_Object_Class_Pointer;
|
||||||
|
-- end record;
|
||||||
|
-- function Get_Character return Object_Character is
|
||||||
|
-- begin
|
||||||
|
-- if Interp.Input.Pos >= Interp.Input.Last then
|
||||||
|
-- Read (Interp.Input.Handle, Interp.Input.Buffer, Interp.Input.Last);
|
||||||
|
-- Interp.Input.Pos := Interp.Input.Buffer'First - 1;
|
||||||
|
-- end if;
|
||||||
|
--
|
||||||
|
-- Interp.Input.Pos := Interp.Input.Pos + 1;
|
||||||
|
-- return Interp.Input.Buffer(Interp.Input.Pos);
|
||||||
|
-- end Get_Character;
|
||||||
|
|
||||||
|
begin
|
||||||
|
null;
|
||||||
|
|
||||||
|
--if Interp.Input.Handle = null then
|
||||||
|
-- Interp.Input.Handle := Interp.Tio ("");
|
||||||
|
-- Interp.Input.Pos := 0;
|
||||||
|
-- Interp.Input.Last := 0;
|
||||||
|
--end if;
|
||||||
|
|
||||||
|
-- In Interp.Close()
|
||||||
|
-- if Interp.Input.Handle /= null then
|
||||||
|
-- Close (Interp.Input.Handle);
|
||||||
|
--end if;
|
||||||
|
end Read_Object;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
-- Stack frames looks like this upon initialization
|
-- Stack frames looks like this upon initialization
|
||||||
@ -2373,6 +2559,11 @@ Print (Interp, Operand);
|
|||||||
|
|
||||||
loop
|
loop
|
||||||
case Get_Frame_Opcode(Interp.Stack) is
|
case Get_Frame_Opcode(Interp.Stack) is
|
||||||
|
when Opcode_Exit =>
|
||||||
|
Result := Get_Frame_Return (Interp.Stack);
|
||||||
|
Pop_Frame;
|
||||||
|
exit;
|
||||||
|
|
||||||
when Opcode_Evaluate_Object =>
|
when Opcode_Evaluate_Object =>
|
||||||
Evaluate_Object;
|
Evaluate_Object;
|
||||||
|
|
||||||
@ -2388,10 +2579,8 @@ Print (Interp, Operand);
|
|||||||
when Opcode_Apply =>
|
when Opcode_Apply =>
|
||||||
Apply;
|
Apply;
|
||||||
|
|
||||||
when Opcode_Exit =>
|
when Opcode_Read_Object =>
|
||||||
Result := Get_Frame_Return (Interp.Stack);
|
Read_Object;
|
||||||
Pop_Frame;
|
|
||||||
exit;
|
|
||||||
end case;
|
end case;
|
||||||
end loop;
|
end loop;
|
||||||
|
|
||||||
@ -2405,6 +2594,13 @@ Print (Interp, Operand);
|
|||||||
-- TODO: restore envirronemtn frame???
|
-- TODO: restore envirronemtn frame???
|
||||||
end Evaluate;
|
end Evaluate;
|
||||||
|
|
||||||
|
procedure Run_Loop (Interp: in out Interpreter_Record;
|
||||||
|
Result: out Object_Pointer) is
|
||||||
|
-- standard read-eval-print loop
|
||||||
|
begin
|
||||||
|
null;
|
||||||
|
end Run_Loop;
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
function h2scm_open return Interpreter_Pointer;
|
function h2scm_open return Interpreter_Pointer;
|
||||||
|
@ -6,23 +6,62 @@
|
|||||||
-- # # # # # # # # # # #
|
-- # # # # # # # # # # #
|
||||||
-- # # # # # # # # # # # # #
|
-- # # # # # # # # # # # # #
|
||||||
-- ##### #### # # ###### # # ###### # # #######
|
-- ##### #### # # ###### # # ###### # # #######
|
||||||
|
--
|
||||||
|
-- Literal
|
||||||
|
-- Number: 1, 10
|
||||||
|
-- String: "hello"
|
||||||
|
--
|
||||||
|
-- Environment
|
||||||
|
-- The environment holds the key/value pairs.
|
||||||
|
--
|
||||||
|
-- Procedure
|
||||||
|
-- Some builtin-procedure objects are registered to the top-level environment
|
||||||
|
-- upon start-up. You can break the mapping between a name and a procedure
|
||||||
|
-- as it's in the normal environment.
|
||||||
|
--
|
||||||
|
-- Syntax Object
|
||||||
|
-- Some syntax objects are registered upon start-up. They are handled
|
||||||
|
-- very specially when the list containing one of them as the first argument
|
||||||
|
-- is evaluated.
|
||||||
|
--
|
||||||
|
-- Evaluation Rule
|
||||||
|
-- A literal object evaluates to itself. A Symbol object evaluates to
|
||||||
|
-- a value found in the environment. List evaluation is slightly more
|
||||||
|
-- complex. Each element of a list is evluated using the standard evaluation
|
||||||
|
-- rule. The first argument acts as a function and the rest of the arguments
|
||||||
|
-- are applied to the function. An element must evaluate to a closure to be
|
||||||
|
-- a function. The syntax object bypasses the normal evaluation rule and is
|
||||||
|
-- evaluated according to the object-specific rule.
|
||||||
|
--
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
with System;
|
with System;
|
||||||
with System.Storage_Pools;
|
with System.Storage_Pools;
|
||||||
|
|
||||||
|
|
||||||
with Ada.Unchecked_Conversion;
|
with Ada.Unchecked_Conversion;
|
||||||
-- TODO: delete these after debugging
|
-- TODO: delete these after debugging
|
||||||
with ada.text_io;
|
with ada.text_io;
|
||||||
with ada.wide_text_io;
|
with ada.wide_text_io;
|
||||||
with ada.integer_text_io;
|
with ada.integer_text_io;
|
||||||
with ada.long_integer_text_io;
|
with ada.long_integer_text_io;
|
||||||
--with system.address_image;
|
|
||||||
-- TODO: delete above after debugging
|
-- TODO: delete above after debugging
|
||||||
|
|
||||||
package H2.Scheme is
|
package H2.Scheme is
|
||||||
|
|
||||||
|
type Interpreter_Record is limited private;
|
||||||
|
type Interpreter_Pointer is access all Interpreter_Record;
|
||||||
|
|
||||||
|
-- -----------------------------------------------------------------------------
|
||||||
|
-- While I could define Heap_Element and Heap_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 Heap_Element is mod 2 ** System.Storage_Unit;
|
||||||
|
type Heap_Size is range 0 .. (2 ** (System.Word_Size - 1)) - 1;
|
||||||
|
|
||||||
|
-- -----------------------------------------------------------------------
|
||||||
|
|
||||||
-- An object pointer takes up as many bytes as a system word.
|
-- An object pointer takes up as many bytes as a system word.
|
||||||
Object_Pointer_Bits: constant := System.Word_Size;
|
Object_Pointer_Bits: constant := System.Word_Size;
|
||||||
Object_Pointer_Bytes: constant := Object_Pointer_Bits / System.Storage_Unit;
|
Object_Pointer_Bytes: constant := Object_Pointer_Bits / System.Storage_Unit;
|
||||||
@ -173,8 +212,8 @@ package H2.Scheme is
|
|||||||
-- Object payload:
|
-- Object payload:
|
||||||
-- I assume that the smallest payload is able to hold an
|
-- I assume that the smallest payload is able to hold an
|
||||||
-- object pointer by specifying the alignement attribute
|
-- object pointer by specifying the alignement attribute
|
||||||
-- to Object_Pointer_Bytes. this implementation will break
|
-- to Object_Pointer_Bytes and checking the minimum allocation
|
||||||
-- severely if this assumption is not correct.
|
-- size in Allocate_Bytes_In_Heap().
|
||||||
case Kind is
|
case Kind is
|
||||||
when Moved_Object =>
|
when Moved_Object =>
|
||||||
New_Pointer: Object_Pointer := null;
|
New_Pointer: Object_Pointer := null;
|
||||||
@ -248,26 +287,72 @@ package H2.Scheme is
|
|||||||
pragma Inline (Pointer_To_Byte);
|
pragma Inline (Pointer_To_Byte);
|
||||||
|
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
-- While I could define Heap_Element and Heap_Size to be
|
|
||||||
-- the subtype of Object_Byte and Object_Size each, they are not
|
|
||||||
-- logically the same thing.
|
type Stream_Record is abstract tagged limited null record;
|
||||||
-- subtype Storage_Element is Object_Byte;
|
|
||||||
-- subtype Storage_Count is Object_Size;
|
procedure Open (Stream: in out Stream_Record) is abstract;
|
||||||
type Heap_Element is mod 2 ** System.Storage_Unit;
|
|
||||||
type Heap_Size is range 0 .. (2 ** (System.Word_Size - 1)) - 1;
|
procedure Close (Stream: in out Stream_Record) is abstract;
|
||||||
|
|
||||||
|
procedure Read (Stream: in out Stream_Record;
|
||||||
|
Data: out Object_String;
|
||||||
|
Last: out Standard.Natural) is abstract;
|
||||||
|
|
||||||
|
procedure Write (Stream: in out Stream_Record;
|
||||||
|
Data: out Object_String;
|
||||||
|
Last: out Standard.Natural) is abstract;
|
||||||
|
|
||||||
|
type Stream_Pointer is access all Stream_Record'Class;
|
||||||
|
|
||||||
|
type Stream_Allocator is access
|
||||||
|
procedure (Interp: in out Interpreter_Record;
|
||||||
|
Name: access Object_String;
|
||||||
|
Result: out Stream_Pointer);
|
||||||
|
|
||||||
|
type Stream_Deallocator is access
|
||||||
|
procedure (Interp: in out Interpreter_Record;
|
||||||
|
Source: in out Stream_Pointer);
|
||||||
|
|
||||||
|
|
||||||
|
type IO_Flags is mod 2 ** 4;
|
||||||
|
IO_End_Reached: constant IO_Flags := IO_Flags'(2#0001#);
|
||||||
|
IO_Error_Occurred: constant IO_Flags := IO_Flags'(2#0001#);
|
||||||
|
|
||||||
|
type IO_Record;
|
||||||
|
type IO_Pointer is access all IO_Record;
|
||||||
|
|
||||||
|
type IO_Record is record
|
||||||
|
--type IO_Record is limited record
|
||||||
|
Stream: Stream_Pointer := null;
|
||||||
|
--Data: Object_String(1..2048) := (others => ' ');
|
||||||
|
Data: Object_String(1..5) := (others => ' ');
|
||||||
|
Last: Standard.Natural := 0;
|
||||||
|
Pos: Standard.Natural := 0;
|
||||||
|
Flags: IO_Flags := 0; -- EOF, ERROR
|
||||||
|
Next: IO_Pointer;
|
||||||
|
end record;
|
||||||
|
|
||||||
|
|
||||||
|
-- -----------------------------------------------------------------------------
|
||||||
|
|
||||||
type Trait_Mask is mod 2 ** System.Word_Size;
|
type Trait_Mask is mod 2 ** System.Word_Size;
|
||||||
No_Garbage_Collection: constant Trait_Mask := 2#0000_0000_0000_0001#;
|
No_Garbage_Collection: constant Trait_Mask := 2#0000_0000_0000_0001#;
|
||||||
No_Optimization: constant Trait_Mask := 2#0000_0000_0000_0010#;
|
No_Optimization: constant Trait_Mask := 2#0000_0000_0000_0010#;
|
||||||
|
|
||||||
type Option_Kind is (Trait_Option);
|
type Option_Kind is (Trait_Option, Stream_Option);
|
||||||
type Option_Record (Kind: Option_Kind) is record
|
type Option_Record (Kind: Option_Kind) is record
|
||||||
case Kind is
|
case Kind is
|
||||||
when Trait_Option =>
|
when Trait_Option =>
|
||||||
Trait_Bits: Trait_Mask := 0;
|
Trait_Bits: Trait_Mask := 0;
|
||||||
|
|
||||||
|
when Stream_Option =>
|
||||||
|
Allocate: Stream_Allocator := null;
|
||||||
|
Deallocate: Stream_Deallocator := null;
|
||||||
end case;
|
end case;
|
||||||
end record;
|
end record;
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
|
|
||||||
-- The nil/true/false object are represented by special pointer values.
|
-- The nil/true/false object are represented by special pointer values.
|
||||||
@ -297,26 +382,6 @@ package H2.Scheme is
|
|||||||
|
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
|
|
||||||
type Interpreter_Record is limited private;
|
|
||||||
|
|
||||||
type Interpreter_Text_IO_Record is abstract tagged null record;
|
|
||||||
|
|
||||||
procedure Open (IO: in out Interpreter_Text_IO_Record;
|
|
||||||
Name: in Object_String) is abstract;
|
|
||||||
|
|
||||||
procedure Close (IO: in out Interpreter_Text_IO_Record) is abstract;
|
|
||||||
|
|
||||||
procedure Read (IO: in out Interpreter_Text_IO_Record;
|
|
||||||
Data: in Object_String;
|
|
||||||
Last: in Standard.Natural) is abstract;
|
|
||||||
|
|
||||||
procedure Write (IO: in out Interpreter_Text_IO_Record;
|
|
||||||
Data: out Object_String;
|
|
||||||
Last: out Standard.Natural) is abstract;
|
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
procedure Make_Test_Object (Interp: in out Interpreter_Record; Result: out Object_Pointer);
|
procedure Make_Test_Object (Interp: in out Interpreter_Record; Result: out Object_Pointer);
|
||||||
|
|
||||||
procedure Open (Interp: in out Interpreter_Record;
|
procedure Open (Interp: in out Interpreter_Record;
|
||||||
@ -325,12 +390,7 @@ procedure Make_Test_Object (Interp: in out Interpreter_Record; Result: out Objec
|
|||||||
|
|
||||||
procedure Close (Interp: in out Interpreter_Record);
|
procedure Close (Interp: in out Interpreter_Record);
|
||||||
|
|
||||||
procedure Evaluate (Interp: in out Interpreter_Record;
|
function Get_Storage_Pool (Interp: in Interpreter_Record) return Storage_Pool_Pointer;
|
||||||
Source: in Object_Pointer;
|
|
||||||
Result: out Object_Pointer);
|
|
||||||
|
|
||||||
procedure Print (Interp: in out Interpreter_Record;
|
|
||||||
Source: in Object_Pointer);
|
|
||||||
|
|
||||||
procedure Set_Option (Interp: in out Interpreter_Record;
|
procedure Set_Option (Interp: in out Interpreter_Record;
|
||||||
Option: in Option_Record);
|
Option: in Option_Record);
|
||||||
@ -338,6 +398,22 @@ procedure Make_Test_Object (Interp: in out Interpreter_Record; Result: out Objec
|
|||||||
procedure Get_Option (Interp: in out Interpreter_Record;
|
procedure Get_Option (Interp: in out Interpreter_Record;
|
||||||
Option: in out Option_Record);
|
Option: in out Option_Record);
|
||||||
|
|
||||||
|
procedure Set_Input_Stream (Interp: in out Interpreter_Record;
|
||||||
|
Stream: in out Stream_Record'Class);
|
||||||
|
|
||||||
|
-- Source must be open for Read() to work.
|
||||||
|
procedure Read (Interp: in out Interpreter_Record;
|
||||||
|
Result: out Object_Pointer);
|
||||||
|
|
||||||
|
procedure Evaluate (Interp: in out Interpreter_Record;
|
||||||
|
Source: in Object_Pointer;
|
||||||
|
Result: out Object_Pointer);
|
||||||
|
|
||||||
|
procedure Print (Interp: in out Interpreter_Record;
|
||||||
|
Source: in Object_Pointer);
|
||||||
|
|
||||||
|
procedure Run_Loop (Interp: in out Interpreter_Record;
|
||||||
|
Result: out Object_Pointer);
|
||||||
|
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -361,12 +437,13 @@ private
|
|||||||
Next: Object_Pointer := Nil_Pointer;
|
Next: Object_Pointer := Nil_Pointer;
|
||||||
end record;
|
end record;
|
||||||
|
|
||||||
type Interpreter_Pointer is access all Interpreter_Record;
|
|
||||||
--type Interpreter_Record is tagged limited record
|
--type Interpreter_Record is tagged limited record
|
||||||
type Interpreter_Record is limited record
|
type Interpreter_Record is limited record
|
||||||
Self: Interpreter_Pointer := null;
|
--Self: Interpreter_Pointer := null;
|
||||||
|
Self: Interpreter_Pointer := Interpreter_Record'Unchecked_Access; -- Current instance's pointer
|
||||||
Storage_Pool: Storage_Pool_Pointer := null;
|
Storage_Pool: Storage_Pool_Pointer := null;
|
||||||
Trait: Option_Record(Trait_Option);
|
Trait: Option_Record(Trait_Option);
|
||||||
|
Stream: Option_Record(Stream_Option);
|
||||||
|
|
||||||
Heap: Heap_Pointer_Array := (others => null);
|
Heap: Heap_Pointer_Array := (others => null);
|
||||||
Current_Heap: Heap_Number := Heap_Number'First;
|
Current_Heap: Heap_Number := Heap_Number'First;
|
||||||
@ -380,9 +457,9 @@ private
|
|||||||
|
|
||||||
R: Register_Record;
|
R: Register_Record;
|
||||||
|
|
||||||
Line: Object_String(1..1024);
|
-- TODO: Buffer_Record needs to be stacked to handle "load".
|
||||||
Line_Last: Standard.Natural;
|
Input: aliased IO_Record;
|
||||||
Line_Pos: Standard.Natural;
|
IO: IO_Pointer := null;
|
||||||
end record;
|
end record;
|
||||||
|
|
||||||
end H2.Scheme;
|
end H2.Scheme;
|
||||||
|
@ -2,7 +2,7 @@ with System.Storage_Pools;
|
|||||||
|
|
||||||
package H2 is
|
package H2 is
|
||||||
|
|
||||||
subtype Character is Standard.Wide_Character;
|
--subtype Character is Standard.Wide_Character;
|
||||||
|
|
||||||
type Storage_Pool_Pointer is
|
type Storage_Pool_Pointer is
|
||||||
access all System.Storage_Pools.Root_Storage_Pool'Class;
|
access all System.Storage_Pools.Root_Storage_Pool'Class;
|
||||||
|
@ -22,7 +22,7 @@ project Lib is
|
|||||||
|
|
||||||
package Compiler is
|
package Compiler is
|
||||||
for Default_Switches ("Ada") use (
|
for Default_Switches ("Ada") use (
|
||||||
"-gnata", "-gnato", "-gnatN", "-gnatwl"
|
"-gnata", "-gnato", "-gnatN", "-gnatwl", "-gnat95"
|
||||||
);
|
);
|
||||||
end Compiler;
|
end Compiler;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user