implemented syntax checking of 'do'
This commit is contained in:
		@ -358,24 +358,44 @@ procedure Evaluate is
 | 
			
		||||
	procedure Evaluate_Do_Syntax is
 | 
			
		||||
		pragma Inline (Evaluate_Do_Syntax);
 | 
			
		||||
		Synlist: Object_Pointer;
 | 
			
		||||
		Ptr1: Object_Pointer;
 | 
			
		||||
		Ptr2: Object_Pointer;
 | 
			
		||||
		Ptr3: Object_Pointer;
 | 
			
		||||
	begin
 | 
			
		||||
		-- (do <bindings> <clause> <body>)
 | 
			
		||||
		-- <bindings> should be of the form: ((<variable 1> <init 1> <step 1>) ...)
 | 
			
		||||
		-- <clause> should  be of the form: (<test> <expression> ...)
 | 
			
		||||
		-- <body> is zero or more expressions.
 | 
			
		||||
		--
 | 
			
		||||
		-- * evaluate <init>.
 | 
			
		||||
		-- * bind <variable> with the result.
 | 
			
		||||
		-- * evaluate <test>
 | 
			
		||||
		-- * if the result is false, evaluate <body>. evaluate <step>. 
 | 
			
		||||
		--   store it into <variable> and go back to evaluate <test>
 | 
			
		||||
		-- * if the result is true, evaluate <expression> and exit.
 | 
			
		||||
		-- 
 | 
			
		||||
		-- (let ((x '(1 3 5 7 9)))
 | 
			
		||||
		--     (do ((x x (cdr x))
 | 
			
		||||
		--          (sum 0 (+ sum (car x)))) ; <bindings>
 | 
			
		||||
		--          (sum 0 (+ sum (car x)))) ; <bindings> x and sum
 | 
			
		||||
		--         ((null? x) sum) ; <clause>. if <test> is true, exit do with sum.
 | 
			
		||||
		--     )
 | 
			
		||||
		-- )
 | 
			
		||||
		--
 | 
			
		||||
		-- (do ((i 0 (+ i 1)))
 | 
			
		||||
		--     ((= i 5) i)     
 | 
			
		||||
		--     (display i) ; <body> downwards
 | 
			
		||||
		-- (do (
 | 
			
		||||
		--         (i 0 (+ i 1)) ; i = 0, for each iteration, +1
 | 
			
		||||
		--         (j 0 (+ j 2)) ; j = 0, for each iteration, +2
 | 
			
		||||
		--     )
 | 
			
		||||
		--
 | 
			
		||||
		--     ((= i 5) i) ; exit returning i if i becomes 5 
 | 
			
		||||
		--
 | 
			
		||||
		--     (display (* i j)) ; evaluate these until it exits
 | 
			
		||||
		--     (newline)
 | 
			
		||||
		-- )
 | 
			
		||||
		--
 | 
			
		||||
		-- Infinite loop samples:
 | 
			
		||||
		--   (do () (#f) (display i))
 | 
			
		||||
		--   (do ((i 0)) (#f) (display i))
 | 
			
		||||
		--   (do ((i 0)) (#f) (display i))
 | 
			
		||||
		
 | 
			
		||||
		Synlist := Operand;
 | 
			
		||||
		Operand := Get_Cdr(Operand); -- Skip "do"
 | 
			
		||||
@ -383,9 +403,88 @@ procedure Evaluate is
 | 
			
		||||
		if (Interp.State and Force_Syntax_Check) /= 0 or else 
 | 
			
		||||
		   (Synlist.Flags and Syntax_Checked) = 0 then
 | 
			
		||||
 | 
			
		||||
			Ada.Text_IO.Put_LINE ("UNIMPLEMENTED");
 | 
			
		||||
			raise Evaluation_Error;
 | 
			
		||||
			Ptr1 := Operand; -- <bindings> list
 | 
			
		||||
			if not Is_Cons(Ptr1) then
 | 
			
		||||
				-- (do)
 | 
			
		||||
				-- (do . 10)
 | 
			
		||||
				Ada.Text_IO.Put_LINE ("NO BIDNIGNS FOR DO");
 | 
			
		||||
				raise Syntax_Error;
 | 
			
		||||
			end if;
 | 
			
		||||
 | 
			
		||||
			Ptr2 := Get_Car(Ptr1); -- <bindings>
 | 
			
		||||
			while Is_Cons(Ptr2) loop
 | 
			
		||||
				Ptr3 := Get_Car(Ptr2); -- <binding>
 | 
			
		||||
				if not Is_Cons(Ptr3) then
 | 
			
		||||
					-- (do (i) (#f))
 | 
			
		||||
					Ada.Text_IO.Put_Line ("INVALID BINDING FOR DO");
 | 
			
		||||
					raise Syntax_Error;
 | 
			
		||||
				end if;
 | 
			
		||||
				
 | 
			
		||||
				if not Is_Symbol(Get_Car(Ptr3)) then -- <variable>
 | 
			
		||||
					-- (do ((10 10)) (#f))
 | 
			
		||||
					Ada.Text_IO.Put_Line ("INVALID BINDING VARIABLE FOR DO");
 | 
			
		||||
					raise Syntax_Error;
 | 
			
		||||
				end if;
 | 
			
		||||
 | 
			
		||||
				Ptr3 := Get_Cdr(Ptr3); -- <init> cons
 | 
			
		||||
				if not Is_Cons(Ptr3) then
 | 
			
		||||
					-- (do ((i . 10)) (#f))
 | 
			
		||||
					Ada.Text_IO.Put_Line ("NO INIT IN DO BINDING");
 | 
			
		||||
					raise Syntax_Error;
 | 
			
		||||
				end if;
 | 
			
		||||
				-- Get_Car(Ptr3); -- <init>
 | 
			
		||||
				
 | 
			
		||||
				Ptr3 := Get_Cdr(Ptr3); -- <step> cons
 | 
			
		||||
				if Is_Cons(Ptr3) then
 | 
			
		||||
					-- Get_Car(Ptr3); -- <step>
 | 
			
		||||
					if Get_Cdr(Ptr3) /= Nil_Pointer then
 | 
			
		||||
						-- (do ((i 0 10 20)) ... )
 | 
			
		||||
						Ada.Text_IO.PUT_Line ("TOO MANY STEP EXPRESSIONS IN DO BINDING");
 | 
			
		||||
						raise Syntax_Error;
 | 
			
		||||
					end if;
 | 
			
		||||
				elsif Ptr3 /= Nil_Pointer then
 | 
			
		||||
					-- (do ((i 0 . 10)) ... )
 | 
			
		||||
					Ada.Text_IO.Put_Line ("FUCKING CDR in DO BIDNING");
 | 
			
		||||
					raise Syntax_Error;
 | 
			
		||||
				end if;
 | 
			
		||||
 | 
			
		||||
				Ptr2 := Get_Cdr(Ptr2);
 | 
			
		||||
			end loop;
 | 
			
		||||
			if Ptr2 /= Nil_Pointer then
 | 
			
		||||
				-- (do 10 . 10)
 | 
			
		||||
				-- (do 10 (#f))
 | 
			
		||||
				-- (do ((i 10) (j 20) . 10) (#f))
 | 
			
		||||
				Ada.Text_IO.Put_LINE ("INVALID BINDINGS FOR DO");
 | 
			
		||||
				raise Syntax_Error;
 | 
			
		||||
			end if;
 | 
			
		||||
			
 | 
			
		||||
			Ptr1 := Get_Cdr(Ptr1); -- <clause>
 | 
			
		||||
			if not Is_Cons(Ptr1) then
 | 
			
		||||
				-- (do ( (i 10) (j 20)))
 | 
			
		||||
				-- (do ( (i 10) (j 20)) . #f)
 | 
			
		||||
				Ada.Text_IO.Put_LINE ("NO CLAUSE FOR DO");
 | 
			
		||||
				raise Syntax_Error;
 | 
			
		||||
			end if;
 | 
			
		||||
			
 | 
			
		||||
			Ptr2 := Get_Car(Ptr1); -- <test> in clause;
 | 
			
		||||
			if not Is_Cons(Ptr2) then
 | 
			
		||||
				-- (do ( (i 10) (j 20)) #f)
 | 
			
		||||
				Ada.Text_IO.Put_Line ("INVALID CLAUSE TEST FOR DO");
 | 
			
		||||
				raise Syntax_Error;
 | 
			
		||||
			end if;
 | 
			
		||||
			if Get_Last_Cdr(Ptr2) /= Nil_Pointer then
 | 
			
		||||
				-- (do ( (i 10) (j 20)) (#f . 10))
 | 
			
		||||
				-- (do ( (i 10) (j 20)) (#f 20 . 10))
 | 
			
		||||
				Ada.Text_IO.Put_LINE ("FUCKING CDR IN CLAUSE FOR DO");
 | 
			
		||||
				raise Syntax_Error;
 | 
			
		||||
			end if;
 | 
			
		||||
 | 
			
		||||
			if Get_Last_Cdr(Ptr1) /= Nil_Pointer then
 | 
			
		||||
				-- (do ( (i 10) (j 20 10))  (#f 20) . 10)
 | 
			
		||||
				Ada.Text_IO.Put_LINE ("FUCKING CDR IN BODY FOR DO");
 | 
			
		||||
				raise Syntax_Error;
 | 
			
		||||
			end if;
 | 
			
		||||
			
 | 
			
		||||
			Synlist.Flags := Synlist.Flags or Syntax_Checked;
 | 
			
		||||
		end if; 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user