enhanced checks in lambda processing
This commit is contained in:
		@ -15,12 +15,16 @@ procedure Apply is
 | 
			
		||||
		Ptr: Object_Pointer := Args;
 | 
			
		||||
		A: Object_Pointer;
 | 
			
		||||
	begin
 | 
			
		||||
		if Ptr = Nil_Pointer or else Get_Cdr(Ptr) /= Nil_Pointer then
 | 
			
		||||
		if not Is_Cons(Ptr) or else Get_Cdr(Ptr) /= Nil_Pointer then
 | 
			
		||||
Ada.Text_IO.Put_Line ("WRONG NUMBER OF ARGUMETNS FOR CAR"); 
 | 
			
		||||
			raise Syntax_Error;
 | 
			
		||||
		end if;
 | 
			
		||||
 | 
			
		||||
		A := Get_Car(Ptr); -- the first argument
 | 
			
		||||
		if not Is_Cons(A) then
 | 
			
		||||
Ada.Text_IO.Put_Line ("EXPECTED CONS-CELL FOR CAR"); 
 | 
			
		||||
			raise Evaluation_Error;
 | 
			
		||||
		end if;
 | 
			
		||||
 | 
			
		||||
		Pop_Frame (Interp); -- Done with the current frame
 | 
			
		||||
		Chain_Frame_Result (Interp, Interp.Stack, Get_Car(A));
 | 
			
		||||
@ -30,12 +34,16 @@ Ada.Text_IO.Put_Line ("WRONG NUMBER OF ARGUMETNS FOR CAR");
 | 
			
		||||
		Ptr: Object_Pointer := Args;
 | 
			
		||||
		A: Object_Pointer;
 | 
			
		||||
	begin
 | 
			
		||||
		if Ptr = Nil_Pointer or else Get_Cdr(Ptr) /= Nil_Pointer then
 | 
			
		||||
		if not Is_Cons(Ptr) or else Get_Cdr(Ptr) /= Nil_Pointer then
 | 
			
		||||
Ada.Text_IO.Put_Line ("WRONG NUMBER OF ARGUMETNS FOR CDR"); 
 | 
			
		||||
			raise Syntax_Error;
 | 
			
		||||
		end if;
 | 
			
		||||
 | 
			
		||||
		A := Get_Car(Ptr); -- the first argument
 | 
			
		||||
		if not Is_Cons(A) then
 | 
			
		||||
Ada.Text_IO.Put_Line ("EXPECTED CONS-CELL FOR CDR"); 
 | 
			
		||||
			raise Evaluation_Error;
 | 
			
		||||
		end if;
 | 
			
		||||
 | 
			
		||||
		Pop_Frame (Interp); -- Done with the current frame
 | 
			
		||||
		Chain_Frame_Result (Interp, Interp.Stack, Get_Cdr(A));
 | 
			
		||||
@ -46,7 +54,7 @@ Ada.Text_IO.Put_Line ("WRONG NUMBER OF ARGUMETNS FOR CDR");
 | 
			
		||||
		A: Object_Pointer;
 | 
			
		||||
		B: Object_Pointer;
 | 
			
		||||
	begin
 | 
			
		||||
		if Ptr = Nil_Pointer or else Get_Cdr(Ptr) = Nil_Pointer or else Get_Cdr(Get_Cdr(Ptr)) /= Nil_Pointer  then
 | 
			
		||||
		if not Is_Cons(Ptr) or else not Is_Cons(Get_Cdr(Ptr)) or else Get_Cdr(Get_Cdr(Ptr)) /= Nil_Pointer  then
 | 
			
		||||
Ada.Text_IO.Put_Line ("WRONG NUMBER OF ARGUMETNS FOR CONS"); 
 | 
			
		||||
			raise Syntax_Error;
 | 
			
		||||
		end if;
 | 
			
		||||
@ -64,12 +72,16 @@ Ada.Text_IO.Put_Line ("WRONG NUMBER OF ARGUMETNS FOR CONS");
 | 
			
		||||
		A: Object_Pointer;
 | 
			
		||||
		B: Object_Pointer;
 | 
			
		||||
	begin
 | 
			
		||||
		if Ptr = Nil_Pointer or else Get_Cdr(Ptr) = Nil_Pointer or else Get_Cdr(Get_Cdr(Ptr)) /= Nil_Pointer  then
 | 
			
		||||
		if not Is_Cons(Ptr) or else not Is_Cons(Get_Cdr(Ptr)) or else Get_Cdr(Get_Cdr(Ptr)) /= Nil_Pointer  then
 | 
			
		||||
Ada.Text_IO.Put_Line ("WRONG NUMBER OF ARGUMETNS FOR SET-CAR!"); 
 | 
			
		||||
			raise Syntax_Error;
 | 
			
		||||
		end if;
 | 
			
		||||
 | 
			
		||||
		A := Get_Car(Ptr); -- the first argument
 | 
			
		||||
		if not Is_Cons(A) then
 | 
			
		||||
Ada.Text_IO.Put_Line ("EXPECTED CONS-CELL FOR Setcar"); 
 | 
			
		||||
			raise Evaluation_Error;
 | 
			
		||||
		end if;
 | 
			
		||||
		B := Get_Car(Get_Cdr(Ptr)); -- the second argument
 | 
			
		||||
		Set_Car (A, B); -- change car
 | 
			
		||||
 | 
			
		||||
@ -82,12 +94,16 @@ Ada.Text_IO.Put_Line ("WRONG NUMBER OF ARGUMETNS FOR SET-CAR!");
 | 
			
		||||
		A: Object_Pointer;
 | 
			
		||||
		B: Object_Pointer;
 | 
			
		||||
	begin
 | 
			
		||||
		if Ptr = Nil_Pointer or else Get_Cdr(Ptr) = Nil_Pointer or else Get_Cdr(Get_Cdr(Ptr)) /= Nil_Pointer  then
 | 
			
		||||
		if not Is_Cons(Ptr) or else not Is_Cons(Get_Cdr(Ptr)) or else Get_Cdr(Get_Cdr(Ptr)) /= Nil_Pointer  then
 | 
			
		||||
Ada.Text_IO.Put_Line ("WRONG NUMBER OF ARGUMETNS FOR SET-CDR!"); 
 | 
			
		||||
			raise Syntax_Error;
 | 
			
		||||
		end if;
 | 
			
		||||
 | 
			
		||||
		A := Get_Car(Ptr); -- the first argument
 | 
			
		||||
		if not Is_Cons(A) then
 | 
			
		||||
Ada.Text_IO.Put_Line ("EXPECTED CONS-CELL FOR Setcdr"); 
 | 
			
		||||
			raise Evaluation_Error;
 | 
			
		||||
		end if;
 | 
			
		||||
		B := Get_Car(Get_Cdr(Ptr)); -- the second argument
 | 
			
		||||
		Set_Cdr (A, B); -- change cdr
 | 
			
		||||
 | 
			
		||||
@ -103,7 +119,7 @@ Ada.Text_IO.Put_Line ("WRONG NUMBER OF ARGUMETNS FOR SET-CDR!");
 | 
			
		||||
		Num: Object_Integer := 0; -- TODO: support BIGNUM
 | 
			
		||||
		Car: Object_Pointer;
 | 
			
		||||
	begin
 | 
			
		||||
		while Ptr /= Nil_Pointer loop
 | 
			
		||||
		while Is_Cons(Ptr) loop
 | 
			
		||||
			-- TODO: check if car is an integer or bignum or something else.
 | 
			
		||||
			--       if something else, error
 | 
			
		||||
			Car := Get_Car(Ptr);
 | 
			
		||||
@ -124,7 +140,7 @@ Ada.Text_IO.Put ("NOT INTEGER FOR ADD"); Print (Interp, Car);
 | 
			
		||||
		Num: Object_Integer := 0; -- TODO: support BIGNUM
 | 
			
		||||
		Car: Object_Pointer;
 | 
			
		||||
	begin
 | 
			
		||||
		if Ptr /= Nil_Pointer then
 | 
			
		||||
		if Is_Cons(Ptr) then
 | 
			
		||||
			Car := Get_Car(Ptr);
 | 
			
		||||
			if not Is_Integer(Car) then
 | 
			
		||||
				raise Evaluation_Error;
 | 
			
		||||
@ -132,7 +148,7 @@ Ada.Text_IO.Put ("NOT INTEGER FOR ADD"); Print (Interp, Car);
 | 
			
		||||
			Num := Pointer_To_Integer(Car);
 | 
			
		||||
 | 
			
		||||
			Ptr := Get_Cdr(Ptr);
 | 
			
		||||
			while Ptr /= Nil_Pointer loop
 | 
			
		||||
			while Is_Cons(Ptr) loop
 | 
			
		||||
				-- TODO: check if car is an integer or bignum or something else.
 | 
			
		||||
				--       if something else, error
 | 
			
		||||
				Car := Get_Car(Ptr);
 | 
			
		||||
@ -153,7 +169,7 @@ Ada.Text_IO.Put ("NOT INTEGER FOR ADD"); Print (Interp, Car);
 | 
			
		||||
		Num: Object_Integer := 1; -- TODO: support BIGNUM
 | 
			
		||||
		Car: Object_Pointer;
 | 
			
		||||
	begin
 | 
			
		||||
		while Ptr /= Nil_Pointer loop
 | 
			
		||||
		while Is_Cons(Ptr) loop
 | 
			
		||||
			-- TODO: check if car is an integer or bignum or something else.
 | 
			
		||||
			--       if something else, error
 | 
			
		||||
			Car := Get_Car(Ptr);
 | 
			
		||||
@ -174,7 +190,7 @@ Ada.Text_IO.Put ("NOT INTEGER FOR MULTIPLY"); Print (Interp, Car);
 | 
			
		||||
		Num: Object_Integer := 1; -- TODO: support BIGNUM
 | 
			
		||||
		Car: Object_Pointer;
 | 
			
		||||
	begin
 | 
			
		||||
		while Ptr /= Nil_Pointer loop
 | 
			
		||||
		while Is_Cons(Ptr) loop
 | 
			
		||||
			-- TODO: check if car is an integer or bignum or something else.
 | 
			
		||||
			--       if something else, error
 | 
			
		||||
			Car := Get_Car(Ptr);
 | 
			
		||||
@ -192,12 +208,12 @@ Ada.Text_IO.Put ("NOT INTEGER FOR MULTIPLY"); Print (Interp, Car);
 | 
			
		||||
 | 
			
		||||
	procedure Apply_Closure is
 | 
			
		||||
		Fbody: aliased Object_Pointer;
 | 
			
		||||
		Param: aliased Object_Pointer;
 | 
			
		||||
		Arg: aliased Object_Pointer;
 | 
			
		||||
		Formal: aliased Object_Pointer;
 | 
			
		||||
		Actual: aliased Object_Pointer;
 | 
			
		||||
	begin
 | 
			
		||||
		Push_Top (Interp, Fbody'Unchecked_Access);
 | 
			
		||||
		Push_Top (Interp, Param'Unchecked_Access);
 | 
			
		||||
		Push_Top (Interp, Arg'Unchecked_Access);
 | 
			
		||||
		Push_Top (Interp, Formal'Unchecked_Access);
 | 
			
		||||
		Push_Top (Interp, Actual'Unchecked_Access);
 | 
			
		||||
 | 
			
		||||
		-- For a closure created of "(lambda (x y) (+ x y) (* x y))"
 | 
			
		||||
		-- Get_Closure_Code(Func) returns "((x y) (+ x y) (* x y))"
 | 
			
		||||
@ -206,47 +222,47 @@ Ada.Text_IO.Put ("NOT INTEGER FOR MULTIPLY"); Print (Interp, Car);
 | 
			
		||||
		Interp.Environment := Make_Environment (Interp.Self, Get_Closure_Environment(Func));
 | 
			
		||||
 | 
			
		||||
		Fbody := Get_Closure_Code(Func);
 | 
			
		||||
		pragma Assert (Is_Cons(Fbody)); -- the reader must ensure this.
 | 
			
		||||
		pragma Assert (Is_Cons(Fbody)); -- the lambda evaluator must ensure this.
 | 
			
		||||
 | 
			
		||||
		Param := Get_Car(Fbody); -- Formal argument list
 | 
			
		||||
		Arg := Args; -- Actual argument list
 | 
			
		||||
		Formal := Get_Car(Fbody); -- Formal argument list
 | 
			
		||||
		Actual := Args; -- Actual argument list
 | 
			
		||||
 | 
			
		||||
		Fbody := Get_Cdr(Fbody); -- Real function body
 | 
			
		||||
		pragma Assert (Is_Cons(Fbody)); -- the lambda evaluator must ensure this.
 | 
			
		||||
 | 
			
		||||
		if Is_Symbol(Param) then
 | 
			
		||||
		if Is_Symbol(Formal) then
 | 
			
		||||
			-- Closure made of a lambda expression with a single formal argument
 | 
			
		||||
			-- e.g) (lambda x (car x))
 | 
			
		||||
			-- Apply the whole actual argument list to the closure.
 | 
			
		||||
Print (Interp, Arg);
 | 
			
		||||
			Put_Environment (Interp, Param, Arg);
 | 
			
		||||
			Put_Environment (Interp, Formal, Actual);
 | 
			
		||||
		else
 | 
			
		||||
			while Is_Cons(Param) loop
 | 
			
		||||
				if not Is_Cons(Arg) then
 | 
			
		||||
					Ada.Text_IO.Put_Line (">>>> Too few arguments <<<<");	
 | 
			
		||||
			while Is_Cons(Formal) loop
 | 
			
		||||
				if not Is_Cons(Actual) then
 | 
			
		||||
					Ada.Text_IO.Put_Line (">>>> Too few arguments for CLOSURE <<<<");	
 | 
			
		||||
					raise Evaluation_Error;
 | 
			
		||||
				end if;
 | 
			
		||||
 | 
			
		||||
				-- Insert the key/value pair into the environment
 | 
			
		||||
				Put_Environment (Interp, Get_Car(Param), Get_Car(Arg));
 | 
			
		||||
				Put_Environment (Interp, Get_Car(Formal), Get_Car(Actual));
 | 
			
		||||
 | 
			
		||||
				Param := Get_Cdr(Param);
 | 
			
		||||
				Arg := Get_Cdr(Arg);
 | 
			
		||||
				Formal := Get_Cdr(Formal);
 | 
			
		||||
				Actual := Get_Cdr(Actual);
 | 
			
		||||
			end loop;
 | 
			
		||||
 | 
			
		||||
			-- Perform cosmetic checks for the parameter list
 | 
			
		||||
			if Param /= Nil_Pointer then 
 | 
			
		||||
				Ada.Text_IO.Put_Line (">>> GARBAGE IN PARAMETER LIST <<<");
 | 
			
		||||
				raise Syntax_Error;
 | 
			
		||||
			end if;
 | 
			
		||||
			if Is_Symbol(Formal) then
 | 
			
		||||
				-- The last formal argument to the closure is in a CDR.
 | 
			
		||||
				-- Assign the remaining actual arguments to the last formal argument
 | 
			
		||||
				-- e.g) ((lambda (x y . z) z) 1 2 3 4 5)
 | 
			
		||||
				Put_Environment (Interp, Formal, Actual);
 | 
			
		||||
			else
 | 
			
		||||
				-- The lambda evaluator must ensure all formal arguments are symbols.
 | 
			
		||||
				pragma Assert (Formal = Nil_Pointer); 
 | 
			
		||||
 | 
			
		||||
			-- Perform cosmetic checks for the argument list
 | 
			
		||||
			if Is_Cons(Arg) then
 | 
			
		||||
				Ada.Text_IO.Put_Line (">>>> TOO MANY ARGUMETNS FOR CLOSURE  <<<<");	
 | 
			
		||||
				raise Evaluation_Error;
 | 
			
		||||
			elsif Arg /= Nil_Pointer then	
 | 
			
		||||
				Ada.Text_IO.Put_Line (">>> GARBAGE IN ARGUMENT LIST <<<");
 | 
			
		||||
				raise Syntax_Error;
 | 
			
		||||
				if Actual /= Nil_Pointer then	
 | 
			
		||||
					Ada.Text_IO.Put_Line (">>>> TOO MANY ARGUMETNS FOR CLOSURE  <<<<");	
 | 
			
		||||
					raise Evaluation_Error;
 | 
			
		||||
				end if;
 | 
			
		||||
			end if;
 | 
			
		||||
		end if;
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
@ -119,18 +119,34 @@ Ada.Text_IO.Put_Line ("NO ALTERNATE");
 | 
			
		||||
			-- (lambda x ...)
 | 
			
		||||
			null;	
 | 
			
		||||
		elsif Is_Cons(Car) then 
 | 
			
		||||
			Cdr := Car;
 | 
			
		||||
			loop
 | 
			
		||||
				Cdr := Get_Cdr(Cdr);
 | 
			
		||||
				exit when not Is_Cons(Cdr);
 | 
			
		||||
			declare
 | 
			
		||||
				Formals: Object_Pointer := Car;
 | 
			
		||||
				V: Object_Pointer;
 | 
			
		||||
			begin
 | 
			
		||||
				Cdr := Formals;
 | 
			
		||||
				loop
 | 
			
		||||
					Car := Get_Car(Cdr); -- <formal argument>
 | 
			
		||||
					if not Is_Symbol(Car) then
 | 
			
		||||
						Ada.Text_IO.Put_Line ("WRONG FORMAL FOR LAMBDA");
 | 
			
		||||
						raise Syntax_Error;
 | 
			
		||||
					end if;
 | 
			
		||||
 | 
			
		||||
				Car := Get_Car(Cdr);	
 | 
			
		||||
				if not Is_Symbol(Car) then
 | 
			
		||||
					Ada.Text_IO.Put_Line ("WRONG FORMALS FOR LAMBDA");
 | 
			
		||||
					raise Syntax_Error;
 | 
			
		||||
				end if;
 | 
			
		||||
-- TODO: Check duplicate symbol names???
 | 
			
		||||
			end loop;
 | 
			
		||||
					V := Formals;
 | 
			
		||||
					loop
 | 
			
		||||
						exit when V = Cdr;
 | 
			
		||||
 | 
			
		||||
						if Get_Car(V) = Car then
 | 
			
		||||
							Ada.Text_IO.Put_Line ("DUPLICATE FORMAL FOR LAMBDA");
 | 
			
		||||
							raise Syntax_Error;
 | 
			
		||||
						end if;
 | 
			
		||||
 | 
			
		||||
						V := Get_Cdr(V);
 | 
			
		||||
					end loop;
 | 
			
		||||
 | 
			
		||||
					Cdr := Get_Cdr(Cdr);
 | 
			
		||||
					exit when not Is_Cons(Cdr);
 | 
			
		||||
				end loop;
 | 
			
		||||
			end;
 | 
			
		||||
 | 
			
		||||
			if Cdr /= Nil_Pointer and then not Is_Symbol(Cdr) then
 | 
			
		||||
				Ada.Text_IO.Put_Line ("FUCKING CDR IN FORMALS FOR LAMBDA");
 | 
			
		||||
 | 
			
		||||
@ -1668,19 +1668,12 @@ Ada.Text_IO.Put_Line ("Make_String...");
 | 
			
		||||
 | 
			
		||||
-- TODO: disallow garbage collecion during initialization.
 | 
			
		||||
		Initialize_Heap (Initial_Heap_Size);
 | 
			
		||||
ada.text_io.put_line ("kkkkkkkkkkkkkk");
 | 
			
		||||
		Interp.Mark := Make_Mark(Interp.Self, 0); -- to indicate the end of cons evaluation
 | 
			
		||||
ada.text_io.put_line ("xxxxxxxxxxxxxx");
 | 
			
		||||
		Interp.Root_Environment := Make_Environment(Interp.Self, Nil_Pointer);
 | 
			
		||||
ada.text_io.put_line ("zzzzzzzzzzzzzzzzzz");
 | 
			
		||||
		Interp.Environment := Interp.Root_Environment;
 | 
			
		||||
		Make_Syntax_Objects;
 | 
			
		||||
print (interp, interp.mark);
 | 
			
		||||
ada.text_io.put_line ("zzzzzzzzzzzzzzzzzz 00");
 | 
			
		||||
		Make_Procedure_Objects;
 | 
			
		||||
ada.text_io.put_line ("zzzzzzzzzzzzzzzzzz 00--00");
 | 
			
		||||
		Make_Common_Symbol_Objects;
 | 
			
		||||
ada.text_io.put_line ("zzzzzzzzzzzzzzzzzz 11");
 | 
			
		||||
 | 
			
		||||
	exception
 | 
			
		||||
		when others =>
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user