implemented set!
This commit is contained in:
parent
af588f1430
commit
78436b78f4
@ -208,36 +208,34 @@ Ada.Text_IO.Put ("NOT INTEGER FOR MULTIPLY"); Print (Interp, Car);
|
|||||||
Fbody := Get_Closure_Code(Func);
|
Fbody := Get_Closure_Code(Func);
|
||||||
pragma Assert (Is_Cons(Fbody)); -- the reader must ensure this.
|
pragma Assert (Is_Cons(Fbody)); -- the reader must ensure this.
|
||||||
|
|
||||||
Param := Get_Car(Fbody); -- Parameter list
|
Param := Get_Car(Fbody); -- Formal argument list
|
||||||
--Arg := Get_Car(Args); -- Actual argument list
|
|
||||||
Arg := Args; -- Actual argument list
|
Arg := Args; -- Actual argument list
|
||||||
|
|
||||||
Fbody := Get_Cdr (Fbody); -- Real function body
|
Fbody := Get_Cdr(Fbody); -- Real function body
|
||||||
pragma Assert (Is_Cons(Fbody)); -- the reader must ensure this as wel..
|
pragma Assert (Is_Cons(Fbody)); -- the reader must ensure this as wel..
|
||||||
|
|
||||||
while Is_Cons(Param) loop
|
while Is_Cons(Param) loop
|
||||||
|
|
||||||
if not Is_Cons(Arg) then
|
if not Is_Cons(Arg) then
|
||||||
Ada.Text_IO.Put_Line (">>>> Too few arguments <<<<");
|
Ada.Text_IO.Put_Line (">>>> Too few arguments <<<<");
|
||||||
raise Evaluation_Error;
|
raise Evaluation_Error;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
-- Insert the key/value pair into the environment
|
-- Insert the key/value pair into the environment
|
||||||
Set_Environment (Interp, Get_Car(Param), Get_Car(Arg));
|
Put_Environment (Interp, Get_Car(Param), Get_Car(Arg));
|
||||||
|
|
||||||
Param := Get_Cdr(Param);
|
Param := Get_Cdr(Param);
|
||||||
Arg := Get_Cdr(Arg);
|
Arg := Get_Cdr(Arg);
|
||||||
end loop;
|
end loop;
|
||||||
|
|
||||||
-- Perform cosmetic checks for the parameter list
|
-- Perform cosmetic checks for the parameter list
|
||||||
if Param /= Nil_Pointer then
|
--if Param /= Nil_Pointer then -- this check handled in reading (lambda ...)
|
||||||
Ada.Text_IO.Put_Line (">>> GARBAGE IN PARAMETER LIST <<<");
|
-- Ada.Text_IO.Put_Line (">>> GARBAGE IN PARAMETER LIST <<<");
|
||||||
raise Syntax_Error;
|
-- raise Syntax_Error;
|
||||||
end if;
|
--end if;
|
||||||
|
|
||||||
-- Perform cosmetic checks for the argument list
|
-- Perform cosmetic checks for the argument list
|
||||||
if Is_Cons(Arg) then
|
if Is_Cons(Arg) then
|
||||||
Ada.Text_IO.Put_Line (">>>> Two many arguments <<<<");
|
Ada.Text_IO.Put_Line (">>>> TOO MANY ARGUMETNS FOR CLOSURE <<<<");
|
||||||
raise Evaluation_Error;
|
raise Evaluation_Error;
|
||||||
elsif Arg /= Nil_Pointer then
|
elsif Arg /= Nil_Pointer then
|
||||||
Ada.Text_IO.Put_Line (">>> GARBAGE IN ARGUMENT LIST <<<");
|
Ada.Text_IO.Put_Line (">>> GARBAGE IN ARGUMENT LIST <<<");
|
||||||
|
@ -17,6 +17,7 @@ procedure Evaluate is
|
|||||||
if not Is_Cons(Operand) or else not Is_Cons(Get_Cdr(Operand)) then
|
if not Is_Cons(Operand) or else not Is_Cons(Get_Cdr(Operand)) then
|
||||||
-- e.g) (define)
|
-- e.g) (define)
|
||||||
-- (define . 10)
|
-- (define . 10)
|
||||||
|
-- (define x . 10)
|
||||||
Ada.Text_IO.Put_LINE ("TOO FEW ARGUMENTS FOR DEFINE");
|
Ada.Text_IO.Put_LINE ("TOO FEW ARGUMENTS FOR DEFINE");
|
||||||
raise Syntax_Error;
|
raise Syntax_Error;
|
||||||
end if;
|
end if;
|
||||||
@ -52,9 +53,9 @@ procedure Evaluate is
|
|||||||
begin
|
begin
|
||||||
-- (if <test> <consequent>)
|
-- (if <test> <consequent>)
|
||||||
-- (if <test> <consequent> <alternate>)
|
-- (if <test> <consequent> <alternate>)
|
||||||
-- (if (> 3 2) 'yes)
|
-- e.g) (if (> 3 2) 'yes)
|
||||||
-- (if (> 3 2) 'yes 'no)
|
-- (if (> 3 2) 'yes 'no)
|
||||||
-- (if (> 3 2) (- 3 2) (+ 3 2))
|
-- (if (> 3 2) (- 3 2) (+ 3 2))
|
||||||
Operand := Cdr; -- Skip "if"
|
Operand := Cdr; -- Skip "if"
|
||||||
if Not Is_Cons(Operand) then
|
if Not Is_Cons(Operand) then
|
||||||
-- e.g) (if)
|
-- e.g) (if)
|
||||||
@ -101,8 +102,9 @@ Ada.Text_IO.Put_Line ("NO ALTERNATE");
|
|||||||
procedure Evaluate_Lambda_Syntax is
|
procedure Evaluate_Lambda_Syntax is
|
||||||
pragma Inline (Evaluate_Lambda_Syntax);
|
pragma Inline (Evaluate_Lambda_Syntax);
|
||||||
begin
|
begin
|
||||||
-- (lambda (x y) (+ x y));
|
-- (lambda <formals> <body>)
|
||||||
Operand := Cdr; -- Skip "lambda"
|
-- (lambda (x y) (+ x y));
|
||||||
|
Operand := Cdr; -- Skip "lambda". cons cell pointing to <formals>
|
||||||
if not Is_Cons(Operand) then
|
if not Is_Cons(Operand) then
|
||||||
-- e.g) (lambda)
|
-- e.g) (lambda)
|
||||||
-- (lambda . 10)
|
-- (lambda . 10)
|
||||||
@ -110,17 +112,31 @@ Ada.Text_IO.Put_Line ("NO ALTERNATE");
|
|||||||
raise Syntax_Error;
|
raise Syntax_Error;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
if not Is_Cons(Get_Car(Operand)) then
|
Car := Get_Car(Operand); -- <formals>
|
||||||
Ada.Text_IO.Put_Line ("INVALID PARRAMETER LIST");
|
if not Is_Cons(Car) then
|
||||||
|
Ada.Text_IO.Put_Line ("INVALID FORMALS FOR LAMBDA");
|
||||||
raise Syntax_Error;
|
raise Syntax_Error;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
--Print (Interp, Get_Cdr(Operand));
|
Cdr := Get_Last_Cdr(Car);
|
||||||
if not Is_Cons(Get_Cdr(Operand)) then
|
if Cdr /= Nil_Pointer then
|
||||||
|
-- (lambda (x y . z) ...)
|
||||||
|
Ada.Text_IO.Put_Line ("FUCKING CDR IN FORMALS FOR LAMBDA");
|
||||||
|
raise Syntax_Error;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
Cdr := Get_Cdr(Operand); -- cons cell containing <body>
|
||||||
|
if not Is_Cons(Cdr) then
|
||||||
Ada.Text_IO.Put_Line ("NO BODY");
|
Ada.Text_IO.Put_Line ("NO BODY");
|
||||||
raise Syntax_Error;
|
raise Syntax_Error;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
|
if Get_Last_Cdr(Cdr) /= Nil_Pointer then
|
||||||
|
-- (lambda (x y) (+ x y) . 99)
|
||||||
|
Ada.Text_IO.Put_Line ("FUCKING CDR IN BODY FOR LAMBDA");
|
||||||
|
raise Syntax_Error;
|
||||||
|
end if;
|
||||||
|
|
||||||
declare
|
declare
|
||||||
Closure: Object_Pointer;
|
Closure: Object_Pointer;
|
||||||
begin
|
begin
|
||||||
@ -147,6 +163,43 @@ Ada.Text_IO.Put_Line ("NO ALTERNATE");
|
|||||||
Chain_Frame_Result (Interp, Interp.Stack, Get_Car(Operand));
|
Chain_Frame_Result (Interp, Interp.Stack, Get_Car(Operand));
|
||||||
end Evaluate_Quote_Syntax;
|
end Evaluate_Quote_Syntax;
|
||||||
|
|
||||||
|
procedure Evaluate_Set_Syntax is
|
||||||
|
pragma Inline (Evaluate_Set_Syntax);
|
||||||
|
begin
|
||||||
|
-- (set! <variable> <expression>)
|
||||||
|
-- e.g) (set! x 10)
|
||||||
|
|
||||||
|
Operand := Cdr; -- Skip "set!"
|
||||||
|
|
||||||
|
if not Is_Cons(Operand) or else not Is_Cons(Get_Cdr(Operand)) then
|
||||||
|
-- e.g) (set!)
|
||||||
|
-- (set . 10)
|
||||||
|
-- (set x . 10)
|
||||||
|
Ada.Text_IO.Put_LINE ("TOO FEW ARGUMENTS FOR SET");
|
||||||
|
raise Syntax_Error;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
Car := Get_Car(Operand); -- <variable>
|
||||||
|
Cdr := Get_Cdr(Operand); -- cons cell to <expression>
|
||||||
|
if Is_Symbol(Car) then
|
||||||
|
if Get_Cdr(Cdr) /= Nil_Pointer then
|
||||||
|
Ada.Text_IO.Put_LINE ("TOO MANY ARGUMENTS FOR set!");
|
||||||
|
raise Syntax_Error;
|
||||||
|
end if;
|
||||||
|
Cdr := Get_Car(Cdr); -- <expression>
|
||||||
|
|
||||||
|
-- Arrange to finish setting a variable after <expression> evaluation.
|
||||||
|
Set_Frame_Opcode (Interp.Stack, Opcode_Finish_Set);
|
||||||
|
Set_Frame_Operand (Interp.Stack, Car);
|
||||||
|
|
||||||
|
-- Arrange to evalaute the value part
|
||||||
|
Push_Frame (Interp, Opcode_Evaluate_Object, Cdr);
|
||||||
|
else
|
||||||
|
Ada.Text_IO.Put_LINE ("INVALID SYMBOL AFTER SET!");
|
||||||
|
raise Syntax_Error;
|
||||||
|
end if;
|
||||||
|
end Evaluate_Set_Syntax;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Push_Top (Interp, Operand'Unchecked_Access);
|
Push_Top (Interp, Operand'Unchecked_Access);
|
||||||
Push_Top (Interp, Car'Unchecked_Access);
|
Push_Top (Interp, Car'Unchecked_Access);
|
||||||
@ -220,6 +273,9 @@ begin
|
|||||||
when Quote_Syntax =>
|
when Quote_Syntax =>
|
||||||
Evaluate_Quote_Syntax;
|
Evaluate_Quote_Syntax;
|
||||||
|
|
||||||
|
when Set_Syntax => -- set!
|
||||||
|
Evaluate_Set_Syntax;
|
||||||
|
|
||||||
when others =>
|
when others =>
|
||||||
Ada.Text_IO.Put_Line ("Unknown syntax");
|
Ada.Text_IO.Put_Line ("Unknown syntax");
|
||||||
--Set_Frame_Opcode (Interp.Stack, Opcode_Evaluate_Syntax); -- Switch to syntax evaluation
|
--Set_Frame_Opcode (Interp.Stack, Opcode_Evaluate_Syntax); -- Switch to syntax evaluation
|
||||||
@ -242,6 +298,12 @@ begin
|
|||||||
Cdr := Get_Cdr(Operand);
|
Cdr := Get_Cdr(Operand);
|
||||||
else
|
else
|
||||||
-- last cons
|
-- last cons
|
||||||
|
if Cdr /= Nil_Pointer then
|
||||||
|
-- The last CDR is not Nil.
|
||||||
|
Ada.Text_IO.Put_Line ("WARNING: $$$$$$$$$$$$$$$$$$$$$..FUCKING CDR.....................OPTIMIZATIN $$$$");
|
||||||
|
raise Syntax_Error;
|
||||||
|
end if;
|
||||||
|
|
||||||
Operand := Reverse_Cons(Get_Frame_Result(Interp.Stack));
|
Operand := Reverse_Cons(Get_Frame_Result(Interp.Stack));
|
||||||
Clear_Frame_Result (Interp.Stack);
|
Clear_Frame_Result (Interp.Stack);
|
||||||
Set_Frame_Opcode (Interp.Stack, Opcode_Apply);
|
Set_Frame_Opcode (Interp.Stack, Opcode_Apply);
|
||||||
|
@ -91,7 +91,7 @@ Ada.Text_IO.PUt_Line ("FINISH DEFINE SYMBOL");
|
|||||||
pragma Assert (Is_Symbol(X));
|
pragma Assert (Is_Symbol(X));
|
||||||
pragma Assert (Get_Cdr(Get_Frame_Result(Interp.Stack)) = Nil_Pointer);
|
pragma Assert (Get_Cdr(Get_Frame_Result(Interp.Stack)) = Nil_Pointer);
|
||||||
|
|
||||||
Set_Environment (Interp, X, Y);
|
Put_Environment (Interp, X, Y);
|
||||||
|
|
||||||
Pop_Frame (Interp); -- Done
|
Pop_Frame (Interp); -- Done
|
||||||
Chain_Frame_Result (Interp, Interp.Stack, Y);
|
Chain_Frame_Result (Interp, Interp.Stack, Y);
|
||||||
@ -134,6 +134,32 @@ Ada.Text_IO.PUt_Line ("FINISH IF");
|
|||||||
Pop_Tops (Interp, 2);
|
Pop_Tops (Interp, 2);
|
||||||
end Finish_If;
|
end Finish_If;
|
||||||
|
|
||||||
|
procedure Finish_Set is
|
||||||
|
pragma Inline (Finish_Set);
|
||||||
|
X: aliased Object_Pointer;
|
||||||
|
Y: aliased Object_Pointer;
|
||||||
|
begin
|
||||||
|
Ada.Text_IO.PUt_Line ("FINISH Set");
|
||||||
|
Push_Top (Interp, X'Unchecked_Access);
|
||||||
|
Push_Top (Interp, Y'Unchecked_Access);
|
||||||
|
|
||||||
|
X := Get_Frame_Operand(Interp.Stack); -- symbol
|
||||||
|
Y := Get_Car(Get_Frame_Result(Interp.Stack)); -- value
|
||||||
|
pragma Assert (Is_Symbol(X));
|
||||||
|
pragma Assert (Get_Cdr(Get_Frame_Result(Interp.Stack)) = Nil_Pointer);
|
||||||
|
|
||||||
|
if Set_Environment(Interp.Self, X, Y) = null then
|
||||||
|
Ada.Text_IO.PUt_LINE ("ERROR: UNBOUND SYMBOL");
|
||||||
|
raise Evaluation_Error;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
Pop_Frame (Interp); -- Done
|
||||||
|
Chain_Frame_Result (Interp, Interp.Stack, Y);
|
||||||
|
|
||||||
|
Pop_Tops (Interp, 2);
|
||||||
|
end Finish_Set;
|
||||||
|
|
||||||
|
|
||||||
procedure Evaluate is separate;
|
procedure Evaluate is separate;
|
||||||
procedure Apply is separate;
|
procedure Apply is separate;
|
||||||
|
|
||||||
@ -762,6 +788,9 @@ begin
|
|||||||
when Opcode_Finish_If =>
|
when Opcode_Finish_If =>
|
||||||
Finish_If;
|
Finish_If;
|
||||||
|
|
||||||
|
when Opcode_Finish_Set =>
|
||||||
|
Finish_Set;
|
||||||
|
|
||||||
when Opcode_Apply =>
|
when Opcode_Apply =>
|
||||||
Apply;
|
Apply;
|
||||||
|
|
||||||
|
@ -80,20 +80,21 @@ package body H2.Scheme is
|
|||||||
|
|
||||||
subtype Moved_Object_Record is Object_Record (Moved_Object, 0);
|
subtype Moved_Object_Record is Object_Record (Moved_Object, 0);
|
||||||
|
|
||||||
subtype Opcode_Type is Object_Integer range 0 .. 12;
|
subtype Opcode_Type is Object_Integer range 0 .. 13;
|
||||||
Opcode_Exit: constant Opcode_Type := Opcode_Type'(0);
|
Opcode_Exit: constant Opcode_Type := Opcode_Type'(0);
|
||||||
Opcode_Evaluate_Result: constant Opcode_Type := Opcode_Type'(1);
|
Opcode_Evaluate_Result: constant Opcode_Type := Opcode_Type'(1);
|
||||||
Opcode_Evaluate_Object: constant Opcode_Type := Opcode_Type'(2);
|
Opcode_Evaluate_Object: constant Opcode_Type := Opcode_Type'(2);
|
||||||
Opcode_Evaluate_Group: constant Opcode_Type := Opcode_Type'(3); -- (begin ...) and closure apply
|
Opcode_Evaluate_Group: constant Opcode_Type := Opcode_Type'(3); -- (begin ...) and closure apply
|
||||||
Opcode_Finish_Define_Symbol: constant Opcode_Type := Opcode_Type'(4);
|
Opcode_Finish_Define_Symbol: constant Opcode_Type := Opcode_Type'(4);
|
||||||
Opcode_Finish_If: constant Opcode_Type := Opcode_Type'(5);
|
Opcode_Finish_If: constant Opcode_Type := Opcode_Type'(5);
|
||||||
Opcode_Apply: constant Opcode_Type := Opcode_Type'(6);
|
Opcode_Finish_Set: constant Opcode_Type := Opcode_Type'(6);
|
||||||
Opcode_Read_Object: constant Opcode_Type := Opcode_Type'(7);
|
Opcode_Apply: constant Opcode_Type := Opcode_Type'(7);
|
||||||
Opcode_Read_List: constant Opcode_Type := Opcode_Type'(8);
|
Opcode_Read_Object: constant Opcode_Type := Opcode_Type'(8);
|
||||||
Opcode_Read_List_Cdr: constant Opcode_Type := Opcode_Type'(9);
|
Opcode_Read_List: constant Opcode_Type := Opcode_Type'(9);
|
||||||
Opcode_Read_List_End: constant Opcode_Type := Opcode_Type'(10);
|
Opcode_Read_List_Cdr: constant Opcode_Type := Opcode_Type'(10);
|
||||||
Opcode_Close_List: constant Opcode_Type := Opcode_Type'(11);
|
Opcode_Read_List_End: constant Opcode_Type := Opcode_Type'(11);
|
||||||
Opcode_Close_Quote: constant Opcode_Type := Opcode_Type'(12);
|
Opcode_Close_List: constant Opcode_Type := Opcode_Type'(12);
|
||||||
|
Opcode_Close_Quote: constant Opcode_Type := Opcode_Type'(13);
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- COMMON OBJECTS
|
-- COMMON OBJECTS
|
||||||
@ -990,6 +991,17 @@ end if;
|
|||||||
Source.Pointer_Slot(Cons_Cdr_Index) := Value;
|
Source.Pointer_Slot(Cons_Cdr_Index) := Value;
|
||||||
end Set_Cdr;
|
end Set_Cdr;
|
||||||
|
|
||||||
|
function Get_Last_Cdr (Source: in Object_Pointer) return Object_Pointer is
|
||||||
|
pragma Assert (Is_Cons(Source));
|
||||||
|
Ptr: Object_Pointer := Source;
|
||||||
|
begin
|
||||||
|
loop
|
||||||
|
Ptr := Get_Cdr(Ptr);
|
||||||
|
exit when not Is_Cons(Ptr);
|
||||||
|
end loop;
|
||||||
|
return Ptr;
|
||||||
|
end Get_Last_Cdr;
|
||||||
|
|
||||||
function Reverse_Cons (Source: in Object_Pointer;
|
function Reverse_Cons (Source: in Object_Pointer;
|
||||||
Last_Cdr: in Object_Pointer := Nil_Pointer) return Object_Pointer is
|
Last_Cdr: in Object_Pointer := Nil_Pointer) return Object_Pointer is
|
||||||
pragma Assert (Is_Cons(Source));
|
pragma Assert (Is_Cons(Source));
|
||||||
@ -1151,7 +1163,24 @@ Ada.Text_IO.Put_Line ("Make_String...");
|
|||||||
return null; -- not found. note that it's not Nil_Pointer.
|
return null; -- not found. note that it's not Nil_Pointer.
|
||||||
end Find_In_Environment_List;
|
end Find_In_Environment_List;
|
||||||
|
|
||||||
procedure Set_Environment (Interp: in out Interpreter_Record;
|
function Set_Environment (Interp: access Interpreter_Record;
|
||||||
|
Key: in Object_Pointer;
|
||||||
|
Value: in Object_Pointer) return Object_Pointer is
|
||||||
|
Arr: Object_Pointer;
|
||||||
|
begin
|
||||||
|
pragma Assert (Is_Symbol(Key));
|
||||||
|
|
||||||
|
Arr := Find_In_Environment_List(Interp, Get_Car(Interp.Environment), Key);
|
||||||
|
if Arr = null then
|
||||||
|
return null;
|
||||||
|
else
|
||||||
|
-- overwrite an existing pair
|
||||||
|
Arr.Pointer_Slot(2) := Value;
|
||||||
|
return Value;
|
||||||
|
end if;
|
||||||
|
end Set_Environment;
|
||||||
|
|
||||||
|
procedure Put_Environment (Interp: in out Interpreter_Record;
|
||||||
Key: in Object_Pointer;
|
Key: in Object_Pointer;
|
||||||
Value: in Object_Pointer) is
|
Value: in Object_Pointer) is
|
||||||
Arr: Object_Pointer;
|
Arr: Object_Pointer;
|
||||||
@ -1182,8 +1211,7 @@ Ada.Text_IO.Put_Line ("Make_String...");
|
|||||||
-- overwrite an existing pair
|
-- overwrite an existing pair
|
||||||
Arr.Pointer_Slot(2) := Value;
|
Arr.Pointer_Slot(2) := Value;
|
||||||
end if;
|
end if;
|
||||||
|
end Put_Environment;
|
||||||
end Set_Environment;
|
|
||||||
|
|
||||||
function Get_Environment (Interp: access Interpreter_Record;
|
function Get_Environment (Interp: access Interpreter_Record;
|
||||||
Key: in Object_Pointer) return Object_Pointer is
|
Key: in Object_Pointer) return Object_Pointer is
|
||||||
@ -1261,7 +1289,7 @@ Ada.Text_IO.Put_Line ("Make_String...");
|
|||||||
-- Link it to the top environement
|
-- Link it to the top environement
|
||||||
pragma Assert (Interp.Environment = Interp.Root_Environment);
|
pragma Assert (Interp.Environment = Interp.Root_Environment);
|
||||||
pragma Assert (Get_Environment (Interp.Self, Symbol) = null);
|
pragma Assert (Get_Environment (Interp.Self, Symbol) = null);
|
||||||
Set_Environment (Interp.all, Symbol, Proc);
|
Put_Environment (Interp.all, Symbol, Proc);
|
||||||
|
|
||||||
Pop_Tops (Interp.all, 2);
|
Pop_Tops (Interp.all, 2);
|
||||||
return Proc;
|
return Proc;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user