made let* continuation-friendly
This commit is contained in:
@ -240,6 +240,55 @@ procedure Execute (Interp: in out Interpreter_Record) is
|
||||
end if;
|
||||
end Do_Let_Binding;
|
||||
|
||||
procedure Do_Letast_Binding is
|
||||
pragma Inline (Do_Letast_Binding);
|
||||
O: aliased Object_Pointer;
|
||||
Envir: Object_Pointer;
|
||||
begin
|
||||
-- Perform binding in the parent environment.
|
||||
Set_Current_Environment (Interp, Get_Frame_Intermediate(Interp.Stack), Get_Frame_Result(Interp.Stack));
|
||||
|
||||
O := Get_Frame_Operand(Interp.Stack);
|
||||
|
||||
-- Say, <bindings> is ((x 2) (y 2)).
|
||||
-- Get_Car(O) is (x 2).
|
||||
-- To get x, Get_Car(Get_Car(O))
|
||||
-- To get 2, Get_Car(Get_Cdr(Get_Car(O)))
|
||||
if Is_Cons(O) then
|
||||
Push_Top (Interp, O'Unchecked_Access);
|
||||
|
||||
Envir := Make_Environment(Interp.Self, Get_Frame_Environment(Interp.Stack));
|
||||
Set_Frame_Environment (Interp.Stack, Envir);
|
||||
|
||||
Reload_Frame (Interp, Opcode_Evaluate_Object, Get_Car(Get_Cdr(Get_Car(O))));
|
||||
Push_Subframe_With_Intermediate (Interp, Opcode_Letast_Binding, Get_Cdr(O), Get_Car(Get_Car(O)));
|
||||
|
||||
Pop_Tops (Interp, 1);
|
||||
else
|
||||
--envir := get_frame_environment(interp.stack);
|
||||
--declare
|
||||
--w: object_word;
|
||||
--for w'address use envir'address;
|
||||
--begin
|
||||
--ada.text_io.put_line ("i$$$$$$$$$$$$$$$$$$$$$$$$44 ENVIR => " & object_word'image(w));
|
||||
--print (interp, envir);
|
||||
--end;
|
||||
-- Get the final environment
|
||||
Envir := Get_Frame_Environment(Interp.Stack);
|
||||
|
||||
-- Get <body> stored in the Opcode_Grouped_Call frame
|
||||
-- pushed in Evalute_Letast_Syntax().
|
||||
O := Get_Frame_Operand(Get_Frame_Parent(Interp.Stack));
|
||||
|
||||
Pop_Frame (Interp); -- Current frame
|
||||
pragma Assert (Get_Frame_Opcode(Interp.Stack) = Opcode_Grouped_Call);
|
||||
|
||||
-- Refresh the Opcode_Grouped_Call frame pushed in Evaluate_Letast_Syntax()
|
||||
-- with the final environment.
|
||||
Reload_Frame_With_Environment (Interp, Opcode_Grouped_Call, O, Envir);
|
||||
end if;
|
||||
end Do_Letast_Binding;
|
||||
|
||||
procedure Do_Letrec_Binding is
|
||||
pragma Inline (Do_Letrec_Binding);
|
||||
O: aliased Object_Pointer;
|
||||
@ -265,57 +314,6 @@ procedure Execute (Interp: in out Interpreter_Record) is
|
||||
end if;
|
||||
end Do_Letrec_Binding;
|
||||
|
||||
procedure Do_Letast_Binding is
|
||||
pragma Inline (Do_Letast_Binding);
|
||||
X: Object_Pointer;
|
||||
begin
|
||||
X := Get_Frame_Operand(Interp.Stack); -- <bindings> and onward
|
||||
|
||||
-- Don't call this procedure if <bindings> is empty. The caller must ensure this
|
||||
pragma Assert (Is_Cons(X));
|
||||
|
||||
Set_Frame_Opcode (Interp.Stack, Opcode_Letast_Binding_Finish);
|
||||
Push_Frame (Interp, Opcode_Evaluate_Object, Get_Car(Get_Cdr(Get_Car(X))));
|
||||
end Do_Letast_Binding;
|
||||
|
||||
procedure Do_Letast_Binding_Finish is
|
||||
pragma Inline (Do_Letast_Binding_Finish);
|
||||
X: aliased Object_Pointer;
|
||||
Envir: aliased Object_Pointer;
|
||||
begin
|
||||
Push_Top (Interp, X'Unchecked_Access);
|
||||
Push_Top (Interp, Envir'Unchecked_Access);
|
||||
|
||||
X := Get_Frame_Operand(Interp.Stack); -- <bindings> and onward
|
||||
|
||||
-- Update the environment while evaluating <bindings>
|
||||
|
||||
-- Push a new environment for each binding.
|
||||
Envir := Make_Environment(Interp.Self, Get_Frame_Environment(Interp.Stack));
|
||||
Set_Frame_Environment (Interp.Stack, Envir);
|
||||
Set_Current_Environment (Interp, Get_Car(Get_Car(X)), Get_Frame_Result(Interp.Stack));
|
||||
|
||||
X := Get_Cdr(X); -- next binding
|
||||
if Is_Cons(X) then
|
||||
-- More bingings to evaluate
|
||||
Set_Frame_Operand (Interp.Stack, X);
|
||||
Clear_Frame_Result (Interp.Stack);
|
||||
|
||||
-- the next evaluation must be done in the environment where the
|
||||
-- current binding has been made.
|
||||
Push_Frame (Interp, Opcode_Evaluate_Object, Get_Car(Get_Cdr(Get_Car(X))));
|
||||
else
|
||||
-- No more bingings left
|
||||
Pop_Frame (Interp); -- Done
|
||||
|
||||
-- Update the environment of the Let_Finish frame.
|
||||
--pragma Assert (Get_Frame_Opcode(Interp.Stack) = Opcode_Let_Finish);
|
||||
Set_Frame_Environment (Interp.Stack, Envir);
|
||||
end if;
|
||||
|
||||
Pop_Tops (Interp, 2);
|
||||
end Do_Letast_Binding_Finish;
|
||||
|
||||
-- --------------------------------------------------------------------
|
||||
|
||||
procedure Do_Set_Finish is
|
||||
@ -915,9 +913,6 @@ ada.text_io.put_line (Opcode_Type'Image(Get_Frame_Opcode(Interp.Stack)));
|
||||
when Opcode_Letast_Binding =>
|
||||
Do_Letast_Binding;
|
||||
|
||||
when Opcode_Letast_Binding_Finish =>
|
||||
Do_Letast_Binding_Finish;
|
||||
|
||||
when Opcode_Letrec_Binding =>
|
||||
Do_Letrec_Binding;
|
||||
|
||||
|
Reference in New Issue
Block a user