implemented and and or
This commit is contained in:
parent
6eb0e65d00
commit
525e300dec
@ -7,6 +7,43 @@ procedure Evaluate is
|
||||
Car: aliased Object_Pointer;
|
||||
Cdr: aliased Object_Pointer;
|
||||
|
||||
generic
|
||||
V: Object_Pointer;
|
||||
Opcode: Opcode_Type;
|
||||
procedure Generic_And_Or_Syntax;
|
||||
|
||||
procedure Generic_And_Or_Syntax is
|
||||
begin
|
||||
-- (and <test1> <test2> ...)
|
||||
-- (and (= 2 2) (> 2 1)) ==> #t
|
||||
-- (and (= 2 2) (< 2 1)) ==> #f
|
||||
-- (and (= 2 2) (< 2 1) (= 3 3)) ==> #f
|
||||
-- (and 1 2 'c '(f g)) ==> (f g)
|
||||
-- (and) ==> #t
|
||||
|
||||
Operand := Cdr; -- Skip "And"
|
||||
if Operand = Nil_Pointer then
|
||||
-- (and)
|
||||
Pop_Frame (Interp);
|
||||
Chain_Frame_Result (Interp, Interp.Stack, V);
|
||||
elsif not Is_Cons(Operand) or else Get_Last_Cdr(Operand) /= Nil_Pointer then
|
||||
-- (and . 10)
|
||||
-- (and 1 2 . 10)
|
||||
Ada.Text_IO.Put_LINE ("FUCKING cDR FOR DEFINE");
|
||||
raise Syntax_Error;
|
||||
else
|
||||
Set_Frame_Opcode (Interp.Stack, Opcode);
|
||||
Set_Frame_Operand (Interp.Stack, Get_Cdr(Operand)); -- <test2> onwards
|
||||
Clear_Frame_Result (Interp.Stack);
|
||||
|
||||
-- arrange to evaluate <test1>
|
||||
Push_Frame (Interp, Opcode_Evaluate_Object, Get_Car(Operand));
|
||||
end if;
|
||||
end Generic_And_Or_Syntax;
|
||||
|
||||
procedure Evaluate_And_Syntax is new Generic_And_Or_Syntax(True_Pointer, Opcode_Finish_And_Syntax);
|
||||
procedure Evaluate_Or_Syntax is new Generic_And_Or_Syntax(False_Pointer, Opcode_Finish_Or_Syntax);
|
||||
|
||||
procedure Evaluate_Define_Syntax is
|
||||
pragma Inline (Evaluate_Define_Syntax);
|
||||
begin
|
||||
@ -92,7 +129,7 @@ Ada.Text_IO.Put_Line ("NO ALTERNATE");
|
||||
end if;
|
||||
|
||||
-- Switch the current frame to execute action after <test> evaluation.
|
||||
Set_Frame_Opcode (Interp.Stack, Opcode_Finish_If);
|
||||
Set_Frame_Opcode (Interp.Stack, Opcode_Finish_If_Syntax);
|
||||
Set_Frame_Operand (Interp.Stack, Operand);
|
||||
|
||||
-- Arrange to evalaute the conditional
|
||||
@ -206,7 +243,7 @@ Ada.Text_IO.Put_Line ("NO ALTERNATE");
|
||||
raise Syntax_Error;
|
||||
end if;
|
||||
|
||||
Set_Frame_Opcode (Interp.Stack, Opcode_Finish_Let);
|
||||
Set_Frame_Opcode (Interp.Stack, Opcode_Finish_Let_Syntax);
|
||||
Set_Frame_Operand (Interp.Stack, Operand);
|
||||
|
||||
declare
|
||||
@ -303,7 +340,7 @@ Ada.Text_IO.Put_Line ("NO ALTERNATE");
|
||||
Cdr := Get_Car(Cdr); -- <expression>
|
||||
|
||||
-- Arrange to finish setting a variable after <expression> evaluation.
|
||||
Set_Frame_Opcode (Interp.Stack, Opcode_Finish_Set);
|
||||
Set_Frame_Opcode (Interp.Stack, Opcode_Finish_Set_Syntax);
|
||||
Set_Frame_Operand (Interp.Stack, Car);
|
||||
|
||||
-- Arrange to evalaute the value part
|
||||
@ -351,6 +388,9 @@ begin
|
||||
-- apply for special syntax objects.
|
||||
|
||||
case Car.Scode is
|
||||
when And_Syntax =>
|
||||
Evaluate_And_Syntax;
|
||||
|
||||
when Begin_Syntax =>
|
||||
|
||||
Operand := Cdr; -- Skip "begin"
|
||||
@ -387,6 +427,9 @@ begin
|
||||
when Let_Syntax =>
|
||||
Evaluate_Let_Syntax;
|
||||
|
||||
when Or_Syntax =>
|
||||
Evaluate_Or_Syntax;
|
||||
|
||||
when Quote_Syntax =>
|
||||
Evaluate_Quote_Syntax;
|
||||
|
||||
|
@ -77,6 +77,42 @@ procedure Execute (Interp: in out Interpreter_Record) is
|
||||
Pop_Tops (Interp, 3);
|
||||
end Evaluate_Group;
|
||||
|
||||
-- ----------------------------------------------------------------
|
||||
generic
|
||||
V: Object_Pointer;
|
||||
procedure Evaluate_Up_To;
|
||||
|
||||
procedure Evaluate_Up_To is
|
||||
X: aliased Object_Pointer;
|
||||
Y: aliased Object_Pointer;
|
||||
begin
|
||||
X := Get_Frame_Operand(Interp.Stack);
|
||||
Y := Get_Frame_Result(Interp.Stack);
|
||||
|
||||
-- Evaluate_And_Syntax/Evaluate-Or_Syntax has arranged to
|
||||
-- evaluate <test1>. Y must not be Nil_Pointer even at the
|
||||
-- first time this procedure is called,
|
||||
pragma Assert (Is_Cons(Y));
|
||||
pragma Assert (Get_Cdr(Y) = Nil_Pointer); -- ensure 1 resul
|
||||
Y := Get_Car(Y); -- actual result
|
||||
|
||||
if Y /= V and then Is_Cons(X) then
|
||||
-- The result is not what I look for.
|
||||
-- Yet there are still more tests to evaluate.
|
||||
Set_Frame_Operand (Interp.Stack, Get_Cdr(X));
|
||||
Clear_Frame_Result (Interp.Stack);
|
||||
Push_Frame (Interp, Opcode_Evaluate_Object, Get_Car(X));
|
||||
else
|
||||
-- Return the result of the last expression evaluated.
|
||||
Pop_Frame (Interp);
|
||||
Chain_Frame_Result (Interp, Interp.Stack, Y);
|
||||
end if;
|
||||
end Evaluate_Up_To;
|
||||
|
||||
procedure Finish_And_Syntax is new Evaluate_Up_To(False_Pointer);
|
||||
procedure Finish_Or_Syntax is new Evaluate_Up_To(True_Pointer);
|
||||
-- ----------------------------------------------------------------
|
||||
|
||||
procedure Finish_Define_Symbol is
|
||||
pragma Inline (Finish_Define_Symbol);
|
||||
X: aliased Object_Pointer;
|
||||
@ -100,8 +136,8 @@ procedure Execute (Interp: in out Interpreter_Record) is
|
||||
Pop_Tops (Interp, 2);
|
||||
end Finish_Define_Symbol;
|
||||
|
||||
procedure Finish_If is
|
||||
pragma Inline (Finish_If);
|
||||
procedure Finish_If_Syntax is
|
||||
pragma Inline (Finish_If_Syntax);
|
||||
X: aliased Object_Pointer;
|
||||
Y: aliased Object_Pointer;
|
||||
Z: aliased Object_Pointer;
|
||||
@ -133,17 +169,17 @@ procedure Execute (Interp: in out Interpreter_Record) is
|
||||
end if;
|
||||
|
||||
Pop_Tops (Interp, 2);
|
||||
end Finish_If;
|
||||
end Finish_If_Syntax;
|
||||
|
||||
procedure Finish_Let is
|
||||
pragma Inline (Finish_Let);
|
||||
procedure Finish_Let_Syntax is
|
||||
pragma Inline (Finish_Let_Syntax);
|
||||
begin
|
||||
ada.text_io.put_line ("Finish_Let");
|
||||
ada.text_io.put_line ("Finish_Let_Syntax");
|
||||
null;
|
||||
end Finish_Let;
|
||||
end Finish_Let_Syntax;
|
||||
|
||||
procedure Finish_Set is
|
||||
pragma Inline (Finish_Set);
|
||||
procedure Finish_Set_Syntax is
|
||||
pragma Inline (Finish_Set_Syntax);
|
||||
X: aliased Object_Pointer;
|
||||
Y: aliased Object_Pointer;
|
||||
begin
|
||||
@ -164,7 +200,7 @@ ada.text_io.put_line ("Finish_Let");
|
||||
Chain_Frame_Result (Interp, Interp.Stack, Y);
|
||||
|
||||
Pop_Tops (Interp, 2);
|
||||
end Finish_Set;
|
||||
end Finish_Set_Syntax;
|
||||
|
||||
procedure Evaluate is separate;
|
||||
procedure Apply is separate;
|
||||
@ -795,18 +831,30 @@ begin
|
||||
when Opcode_Finish_Define_Symbol =>
|
||||
Finish_Define_Symbol;
|
||||
|
||||
when Opcode_Finish_If =>
|
||||
Finish_If;
|
||||
-- Conditionals
|
||||
when Opcode_Finish_If_Syntax =>
|
||||
Finish_If_Syntax;
|
||||
--when Opcode_Finish_Cond_Syntax => -- Derived, Essential
|
||||
--when Opcode_Finish_Case_Syntax => -- Derived
|
||||
when Opcode_Finish_And_Syntax => -- Derived
|
||||
Finish_And_Syntax;
|
||||
when Opcode_Finish_Or_Syntax => -- Derived
|
||||
Finish_Or_Syntax;
|
||||
|
||||
when Opcode_Finish_Let =>
|
||||
Finish_Let;
|
||||
-- Assignments
|
||||
when Opcode_Finish_Set_Syntax =>
|
||||
Finish_Set_Syntax;
|
||||
|
||||
when Opcode_Finish_Set =>
|
||||
Finish_Set;
|
||||
-- Bindings
|
||||
when Opcode_Finish_Let_Syntax =>
|
||||
Finish_Let_Syntax;
|
||||
--when Opcode_Finish_Letast_Syntax =>
|
||||
--when Opcode_Finish_Letrec_Syntax =>
|
||||
|
||||
when Opcode_Apply =>
|
||||
Apply;
|
||||
|
||||
-- Reading
|
||||
when Opcode_Read_Object =>
|
||||
Read_Object;
|
||||
|
||||
|
@ -88,22 +88,24 @@ package body H2.Scheme is
|
||||
|
||||
subtype Moved_Object_Record is Object_Record (Moved_Object, 0);
|
||||
|
||||
subtype Opcode_Type is Object_Integer range 0 .. 14;
|
||||
subtype Opcode_Type is Object_Integer range 0 .. 16;
|
||||
Opcode_Exit: constant Opcode_Type := Opcode_Type'(0);
|
||||
Opcode_Evaluate_Result: constant Opcode_Type := Opcode_Type'(1);
|
||||
Opcode_Evaluate_Object: constant Opcode_Type := Opcode_Type'(2);
|
||||
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_If: constant Opcode_Type := Opcode_Type'(5);
|
||||
Opcode_Finish_Let: constant Opcode_Type := Opcode_Type'(6);
|
||||
Opcode_Finish_Set: constant Opcode_Type := Opcode_Type'(7);
|
||||
Opcode_Apply: constant Opcode_Type := Opcode_Type'(8);
|
||||
Opcode_Read_Object: constant Opcode_Type := Opcode_Type'(9);
|
||||
Opcode_Read_List: constant Opcode_Type := Opcode_Type'(10);
|
||||
Opcode_Read_List_Cdr: constant Opcode_Type := Opcode_Type'(11);
|
||||
Opcode_Read_List_End: constant Opcode_Type := Opcode_Type'(12);
|
||||
Opcode_Close_List: constant Opcode_Type := Opcode_Type'(13);
|
||||
Opcode_Close_Quote: constant Opcode_Type := Opcode_Type'(14);
|
||||
Opcode_Finish_And_Syntax: constant Opcode_Type := Opcode_Type'(4);
|
||||
Opcode_Finish_Define_Symbol: constant Opcode_Type := Opcode_Type'(5);
|
||||
Opcode_Finish_If_Syntax: constant Opcode_Type := Opcode_Type'(6);
|
||||
Opcode_Finish_Let_Syntax: constant Opcode_Type := Opcode_Type'(7);
|
||||
Opcode_Finish_Or_Syntax: constant Opcode_Type := Opcode_Type'(8);
|
||||
Opcode_Finish_Set_Syntax: constant Opcode_Type := Opcode_Type'(9);
|
||||
Opcode_Apply: constant Opcode_Type := Opcode_Type'(10);
|
||||
Opcode_Read_Object: constant Opcode_Type := Opcode_Type'(11);
|
||||
Opcode_Read_List: constant Opcode_Type := Opcode_Type'(12);
|
||||
Opcode_Read_List_Cdr: constant Opcode_Type := Opcode_Type'(13);
|
||||
Opcode_Read_List_End: constant Opcode_Type := Opcode_Type'(14);
|
||||
Opcode_Close_List: constant Opcode_Type := Opcode_Type'(15);
|
||||
Opcode_Close_Quote: constant Opcode_Type := Opcode_Type'(16);
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- COMMON OBJECTS
|
||||
@ -1222,6 +1224,7 @@ Ada.Text_IO.Put_Line ("Make_String...");
|
||||
-- environment. If no key is found, add a new pair
|
||||
-- This is mainly for define.
|
||||
pragma Assert (Is_Symbol(Key));
|
||||
pragma Assert (Is_Cons(Interp.Environment));
|
||||
|
||||
Arr := Find_In_Environment_List(Interp.Self, Get_Car(Interp.Environment), Key);
|
||||
if Arr /= null then
|
||||
|
Loading…
Reference in New Issue
Block a user