| 
									
										
										
										
											2021-11-07 17:32:50 +00:00
										 |  |  | with H3.Utf8; | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | package body H3.Compilers is | 
					
						
							| 
									
										
										
										
											2021-11-07 17:32:50 +00:00
										 |  |  | 	type Char_Array is array(System_Index range<>) of Standard.Character; | 
					
						
							|  |  |  | 	package Utf8 is new H3.Utf8(Standard.Character, S.Rune, Char_Array, S.Rune_Array); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-31 16:03:11 +00:00
										 |  |  | 	LB_EOF: constant S.Rune_Array := (R.V.Left_Arrow,R.V.UC_E,R.V.UC_O,R.V.UC_F,R.V.Right_Arrow); -- <EOF>
 | 
					
						
							| 
									
										
										
										
											2021-11-28 17:00:17 +00:00
										 |  |  | 	LB_EOL: constant S.Rune_Array := (R.V.Left_Arrow,R.V.UC_E,R.V.UC_O,R.V.UC_L,R.V.Right_Arrow); -- <EOL>
 | 
					
						
							| 
									
										
										
										
											2021-11-07 17:32:50 +00:00
										 |  |  | 	LB_XINCLUDE: constant S.Rune_Array := (R.V.Number_Sign,R.V.LC_I,R.V.LC_N,R.V.LC_C,R.V.LC_L,R.V.LC_U,R.V.LC_D,R.V.LC_E); -- #include
 | 
					
						
							| 
									
										
										
										
											2021-12-01 17:06:30 +00:00
										 |  |  | 	LB_CLASS: constant S.Rune_Array := (R.V.LC_C,R.V.LC_L,R.V.LC_A,R.V.LC_S,R.V.LC_S); -- class
 | 
					
						
							|  |  |  | 	LB_FUN: constant S.Rune_Array := (R.V.LC_F,R.V.LC_U,R.V.LC_N); -- fun
 | 
					
						
							|  |  |  | 	LB_END: constant S.Rune_Array := (R.V.LC_E,R.V.LC_N,R.V.LC_D); -- end
 | 
					
						
							|  |  |  | 	LB_IF: constant S.Rune_Array := (R.V.LC_I,R.V.LC_F); -- if
 | 
					
						
							|  |  |  | 	LB_ELIF: constant S.Rune_Array := (R.V.LC_E,R.V.LC_L,R.V.LC_I,R.V.LC_F); -- elif
 | 
					
						
							|  |  |  | 	LB_ELSE: constant S.Rune_Array := (R.V.LC_E,R.V.LC_L,R.V.LC_S,R.V.LC_E); -- else
 | 
					
						
							|  |  |  | 	LB_WHILE: constant S.Rune_Array := (R.V.LC_W,R.V.LC_H,R.V.LC_I,R.V.LC_L,R.V.LC_E); -- while
 | 
					
						
							|  |  |  | 	LB_BREAK: constant S.Rune_Array := (R.V.LC_B,R.V.LC_R,R.V.LC_E,R.V.LC_A,R.V.LC_K); -- break
 | 
					
						
							|  |  |  | 	LB_CONTINUE: constant S.Rune_Array := (R.V.LC_C,R.V.LC_O,R.V.LC_N,R.V.LC_T,R.V.LC_I,R.V.LC_N,R.V.LC_U,R.V.LC_E); -- continue
 | 
					
						
							|  |  |  | 	LB_TRY: constant S.Rune_Array := (R.V.LC_T,R.V.LC_R,R.V.LC_Y); -- try
 | 
					
						
							|  |  |  | 	LB_CATCH: constant S.Rune_Array := (R.V.LC_C,R.V.LC_A,R.V.LC_T,R.V.LC_T,R.V.LC_H); -- catch
 | 
					
						
							|  |  |  | 	LB_RAISE: constant S.Rune_Array := (R.V.LC_R,R.V.LC_A,R.V.LC_I,R.V.LC_S,R.V.LC_E); -- raise
 | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	procedure Dump_Token (Tk: in Token) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Ada.Text_IO.Put (Tk.Id'Img); | 
					
						
							|  |  |  | 		Ada.Text_IO.Put (": "); | 
					
						
							|  |  |  | 		Ada.Text_IO.Put_Line (Standard.String(Utf8.From_Unicode_String(Tk.Buf.To_Rune_Array))); | 
					
						
							|  |  |  | 	end Dump_Token; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Dump_Rune (Code: in R.Code) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		if R.Is_Eof(Code) then | 
					
						
							|  |  |  | 			Ada.Text_IO.Put_Line ("EOF"); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			Ada.Text_IO.Put_Line (R.To_Rune(Code)'Img); | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 	end Dump_Rune; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-12 23:31:25 +00:00
										 |  |  | 	-- -------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Start_Token (C: in out Compiler) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		C.Tk.Id := TK_EOF; -- indicate the token id is not set yet
 | 
					
						
							|  |  |  | 		-- TODO: store token location.
 | 
					
						
							|  |  |  | 		S.Clear (C.Tk.Buf); | 
					
						
							|  |  |  | 	end Start_Token; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Start_Token (C: in out Compiler; Ch: in R.Rune) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Start_Token (C); | 
					
						
							|  |  |  | 		S.Append (C.Tk.Buf, Ch); | 
					
						
							|  |  |  | 	end Start_Token; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Start_Token (C: in out Compiler; Code: in R.Code) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Start_Token (C, R.To_Rune(Code)); | 
					
						
							|  |  |  | 	end Start_Token; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Start_Token (C: in out Compiler; Str: in S.Rune_Array) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Start_Token (C); | 
					
						
							|  |  |  | 		S.Append (C.Tk.Buf, Str); | 
					
						
							|  |  |  | 	end Start_Token; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Feed_Token (C: in out Compiler; Ch: in R.Rune) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		S.Append (C.Tk.Buf, Ch); | 
					
						
							|  |  |  | 	end Feed_Token; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Feed_Token (C: in out Compiler; Code: in R.Code) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Feed_Token(C, R.To_Rune(Code)); | 
					
						
							|  |  |  | 	end Feed_Token; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 	procedure Set_Lexer_State (C: in out Compiler; State: in Lexer_State) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		C.Lx.State := State; | 
					
						
							| 
									
										
										
										
											2021-11-12 23:31:25 +00:00
										 |  |  | 		Start_Token (C); -- empty the token buffer
 | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 	end Set_Lexer_State; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-12 23:31:25 +00:00
										 |  |  | 	procedure Switch_Lexer_State (C: in out Compiler; State: in Lexer_State) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		C.Lx.State := State; | 
					
						
							|  |  |  | 		-- don't reset the token buffer;
 | 
					
						
							|  |  |  | 	end Switch_Lexer_State; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 	procedure Set_Lexer_State (C: in out Compiler; State: in Lexer_State; Ch: in R.Rune) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		-- change the lexer state while storing the first character in the token buffer.
 | 
					
						
							|  |  |  | 		C.Lx.State := State; | 
					
						
							| 
									
										
										
										
											2021-11-12 23:31:25 +00:00
										 |  |  | 		Start_Token (C, Ch); | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 	end Set_Lexer_State; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Set_Lexer_State (C: in out Compiler; State: in Lexer_State; Code: in R.Code) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Set_Lexer_State (C, State, R.To_Rune(Code)); | 
					
						
							|  |  |  | 	end Set_Lexer_State; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-12 23:31:25 +00:00
										 |  |  | 	procedure Got_Token (C: in out Compiler); -- defined further down
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure End_Token (C: in out Compiler; Id: in Token_Id) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		C.Tk.Id := Id; | 
					
						
							|  |  |  | 		Got_Token (C); | 
					
						
							|  |  |  | 		Set_Lexer_State (C, LX_START); | 
					
						
							|  |  |  | 	end End_Token; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure End_Token (C: in out Compiler; Id: in Token_Id; Ch: in R.Rune) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		S.Append (C.Tk.Buf, Ch); | 
					
						
							|  |  |  | 		C.Tk.Id := Id; | 
					
						
							|  |  |  | 		Got_Token (C); | 
					
						
							|  |  |  | 		Set_Lexer_State (C, LX_START); | 
					
						
							|  |  |  | 	end End_Token; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure End_Token (C: in out Compiler; Id: in Token_Id; Code: in R.Code) is | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 		End_Token (C, Id, R.To_Rune(Code)); | 
					
						
							| 
									
										
										
										
											2021-11-12 23:31:25 +00:00
										 |  |  | 	end End_Token; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	-- -------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 	procedure Set_Parse_State (C: in out Compiler; Code: in Parse_State_Code) is | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 		C.Prs.States(C.Prs.Top).Current := Code; | 
					
						
							|  |  |  | 	end Set_Parse_State; | 
					
						
							| 
									
										
										
										
											2021-10-31 16:03:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 	procedure Push_Parse_State (C: in out Compiler; Code: in Parse_State_Code) is | 
					
						
							|  |  |  | 		Top: System_Index; | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		if C.Prs.Top = C.Prs.States'Last then | 
					
						
							|  |  |  | 			raise Syntax_Error with "parse state stack exhausted"; | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Top := C.Prs.Top + 1; | 
					
						
							|  |  |  | 		declare | 
					
						
							|  |  |  | 			S: Parse_State renames C.Prs.States(Top); | 
					
						
							|  |  |  | 		begin | 
					
						
							|  |  |  | 			S.Current := Code; | 
					
						
							|  |  |  | 		end; | 
					
						
							|  |  |  | 		C.Prs.Top := Top; | 
					
						
							| 
									
										
										
										
											2021-12-05 16:13:36 +00:00
										 |  |  | --ada.text_io.put_line ("Push_Parse_State " & Code'Img);
 | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 	end Push_Parse_State; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Pop_Parse_State (C: in out Compiler) is | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2021-12-05 16:13:36 +00:00
										 |  |  | --ada.text_io.put_line ("Pop_Parse_State " & C.Prs.States(C.Prs.Top).Current'Img);
 | 
					
						
							|  |  |  | 		C.Prs.Top := C.Prs.Top - 1; | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 	end Pop_Parse_State; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	-- -------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Push_Inclusion (C: in out Compiler; Name: in S.Rune_Array) is | 
					
						
							| 
									
										
										
										
											2021-11-14 15:07:41 +00:00
										 |  |  | 		Top: System_Index; | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		if C.Inc.Top = C.Inc.Streams'Last then | 
					
						
							|  |  |  | 			raise Syntax_Error with "inclusion depth too deep"; | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Top := C.Inc.Top + 1; | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 		declare | 
					
						
							|  |  |  | 			S: Stream renames C.Inc.Streams(Top); | 
					
						
							| 
									
										
										
										
											2021-11-14 15:07:41 +00:00
										 |  |  | 		begin | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 			Ada.Text_IO.Open (S.Handle, Ada.Text_IO.In_File, Standard.String(Utf8.From_Unicode_String(Name))); | 
					
						
							|  |  |  | 			S.Prs_Level := C.Prs.Top; -- this is the parse state level of this include directive.
 | 
					
						
							| 
									
										
										
										
											2021-11-14 15:07:41 +00:00
										 |  |  | 		end; | 
					
						
							|  |  |  | 		C.Inc.Top := Top; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 		-- Switch the parse state to handle the terminator
 | 
					
						
							|  |  |  | 		-- after the new pushed state has been popped out.
 | 
					
						
							|  |  |  | 		Set_Parse_State (C, PS_INCLUDE_TERMINATOR); | 
					
						
							| 
									
										
										
										
											2021-11-14 15:07:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 		-- Let the inner content be handled at the state as the include directive is seen.
 | 
					
						
							|  |  |  | 		Push_Parse_State (C, C.Prs.States(C.Prs.Top - 1).Current); | 
					
						
							|  |  |  | 	end Push_Inclusion; | 
					
						
							| 
									
										
										
										
											2021-11-14 15:07:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-05 16:13:36 +00:00
										 |  |  | 	procedure Pop_Inclusion (C: in out Compiler; Check: in Boolean) is | 
					
						
							| 
									
										
										
										
											2021-11-14 15:07:41 +00:00
										 |  |  | 	begin | 
					
						
							|  |  |  | 		Ada.Text_IO.Close (C.Inc.Streams(C.Inc.Top).Handle); | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 		if Check then | 
					
						
							|  |  |  | 			if C.Prs.Top /= C.Inc.Streams(C.Inc.Top).Prs_Level + 1 then | 
					
						
							| 
									
										
										
										
											2021-12-05 16:13:36 +00:00
										 |  |  | ada.text_io.put_line (">>>>>>>>>>> UNBALANCED INCLUSION CONTEXT..." & C.Prs.Top'Img & "  " & C.Inc.Streams(C.Inc.Top).Prs_Level'Img); | 
					
						
							|  |  |  | 					raise Syntax_Error with "unbalanced inclusion content"; | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 			end if; | 
					
						
							|  |  |  | 		end if; | 
					
						
							| 
									
										
										
										
											2021-11-14 15:07:41 +00:00
										 |  |  | 		C.Inc.Top := C.Inc.Top - 1; | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 		Pop_Parse_State (C); | 
					
						
							|  |  |  | 	end Pop_Inclusion; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-01 17:06:30 +00:00
										 |  |  | 	-- -------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2021-12-03 06:38:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-01 17:06:30 +00:00
										 |  |  | 	procedure Parse_Ident (C: in out Compiler) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		if C.Tk.Buf.Equals(LB_CLASS) then | 
					
						
							|  |  |  | 			Push_Parse_State (C, PS_CLASS_1); | 
					
						
							|  |  |  | 		elsif C.Tk.Buf.Equals(LB_FUN) then | 
					
						
							| 
									
										
										
										
											2021-12-03 06:38:20 +00:00
										 |  |  | 			Push_Parse_State (C, PS_FUN_1); | 
					
						
							| 
									
										
										
										
											2021-12-01 17:06:30 +00:00
										 |  |  | 		else | 
					
						
							|  |  |  | 			-- probably a command name or a variable name?
 | 
					
						
							| 
									
										
										
										
											2021-12-03 06:38:20 +00:00
										 |  |  | 			Push_Parse_State (C, PS_PLAIN_STATEMENT_START); | 
					
						
							| 
									
										
										
										
											2021-12-05 16:13:36 +00:00
										 |  |  | 			C.Prs.States(C.Prs.Top).Data := ( | 
					
						
							|  |  |  | 				Code => PD_STATEMENT, | 
					
						
							|  |  |  | 				Stmt_Starter => C.Tk.Buf | 
					
						
							|  |  |  | 			);  | 
					
						
							| 
									
										
										
										
											2021-12-01 17:06:30 +00:00
										 |  |  | 		end if; | 
					
						
							|  |  |  |  	end Parse_Ident; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Parse_Class_1 (C: in out Compiler) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		null; | 
					
						
							|  |  |  | 	end Parse_Class_1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Parse_Class_2 (C: in out Compiler) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		null; | 
					
						
							|  |  |  | 	end Parse_Class_2; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-03 06:38:20 +00:00
										 |  |  | 	-- -------------------------------------------------------------------
 | 
					
						
							|  |  |  | 	procedure Parse_Plain_Statement_Start (C: in out Compiler) is | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2021-12-05 16:13:36 +00:00
										 |  |  | 		case C.Tk.Id is | 
					
						
							|  |  |  | 			when TK_EOL => | 
					
						
							|  |  |  | 				Pop_Parse_State (C); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			when TK_EOF => | 
					
						
							|  |  |  | 				Pop_Parse_State (C); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if C.Inc.Top > 0 then | 
					
						
							|  |  |  | 					Pop_Inclusion (C, True); | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					-- end of really the input??
 | 
					
						
							|  |  |  | 					null; | 
					
						
							|  |  |  | 				end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			when TK_CSTR => | 
					
						
							|  |  |  | 				null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			when TK_IDENT => | 
					
						
							|  |  |  | 				null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			when TK_DOLLARED_LPAREN =>  -- $(
 | 
					
						
							|  |  |  | 				Push_Parse_State (C, PS_START); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			when TK_RPAREN => | 
					
						
							|  |  |  | 				Pop_Parse_State (C); -- pop as if EOL is seen.
 | 
					
						
							|  |  |  | 				Pop_Parse_State (C); -- pop against TK_DOLLARED_LPAREN
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			when TK_SEMICOLON => | 
					
						
							|  |  |  | 				-- end of the current statement. go on to the next statement
 | 
					
						
							|  |  |  | 				Set_Parse_State (C, PS_PLAIN_STATEMENT_START); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			when others => | 
					
						
							|  |  |  | 				raise Syntax_Error with "invalid token in in plain statement"; | 
					
						
							|  |  |  | 		end case; | 
					
						
							| 
									
										
										
										
											2021-12-03 06:38:20 +00:00
										 |  |  | 	end Parse_Plain_Statement_Start; | 
					
						
							| 
									
										
										
										
											2021-12-05 16:13:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 	-- -------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2021-11-14 15:07:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-07 17:32:50 +00:00
										 |  |  | 	procedure Parse_Start (C: in out Compiler) is | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 		case C.Tk.Id is | 
					
						
							|  |  |  | 			when TK_BSTR => | 
					
						
							|  |  |  | 				null; | 
					
						
							|  |  |  | 			when TK_BYTE => | 
					
						
							|  |  |  | 				null; | 
					
						
							|  |  |  | 			when TK_CHAR => | 
					
						
							|  |  |  | 				null; | 
					
						
							|  |  |  | 			when TK_CSTR => | 
					
						
							|  |  |  | 				null; | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-02 00:31:30 +00:00
										 |  |  | 			when TK_DIRECTIVE => | 
					
						
							| 
									
										
										
										
											2021-11-07 17:32:50 +00:00
										 |  |  | 				if C.Tk.Buf.Equals(LB_XINCLUDE) then | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 					--Set_Parse_State (C, PS_INCLUDE_TARGET);
 | 
					
						
							|  |  |  | 					Push_Parse_State (C, PS_INCLUDE_TARGET); | 
					
						
							| 
									
										
										
										
											2021-11-07 17:32:50 +00:00
										 |  |  | 				else | 
					
						
							| 
									
										
										
										
											2021-11-12 23:31:25 +00:00
										 |  |  | 					raise Syntax_Error with "unknown directive name"; | 
					
						
							| 
									
										
										
										
											2021-11-07 17:32:50 +00:00
										 |  |  | 				end if; | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 			when TK_EOF => | 
					
						
							| 
									
										
										
										
											2021-11-14 15:07:41 +00:00
										 |  |  | 				if C.Inc.Top > 0 then | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 					Pop_Inclusion (C, True); | 
					
						
							| 
									
										
										
										
											2021-11-14 15:07:41 +00:00
										 |  |  | 				else | 
					
						
							|  |  |  | 					-- end of really the input??
 | 
					
						
							|  |  |  | 					null; | 
					
						
							|  |  |  | 				end if; | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 			when TK_EOL => | 
					
						
							|  |  |  | 				null; | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 			when TK_IDENT => | 
					
						
							| 
									
										
										
										
											2021-12-01 17:06:30 +00:00
										 |  |  | 				Parse_Ident (C); | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			--when TK_NUMBER =>
 | 
					
						
							|  |  |  | 			--	null;
 | 
					
						
							|  |  |  | 			-- plus or minus signed may be allowed here too.
 | 
					
						
							|  |  |  | 			-- plusplus or miniusminus may be allowed here too.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 			when TK_SEMICOLON => | 
					
						
							|  |  |  | 				null; | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-05 16:13:36 +00:00
										 |  |  | 			--when TK_HASHED_LBRACE =>
 | 
					
						
							|  |  |  | 			--	null;
 | 
					
						
							|  |  |  | 			--when TK_HASHED_LBRACK =>
 | 
					
						
							|  |  |  | 			--	null;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			when TK_DOLLARED_LPAREN => | 
					
						
							|  |  |  | 				Push_Parse_State (C, PS_START); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			when TK_RPAREN => | 
					
						
							|  |  |  | 				Pop_Parse_State (C); | 
					
						
							| 
									
										
										
										
											2021-12-01 17:06:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 			when others => | 
					
						
							|  |  |  | 				raise Syntax_Error with "unexpected token"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 		end case; | 
					
						
							| 
									
										
										
										
											2021-11-07 17:32:50 +00:00
										 |  |  | 	end Parse_Start; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-14 15:07:41 +00:00
										 |  |  | 	procedure Parse_Include_Target (C: in out Compiler) is | 
					
						
							| 
									
										
										
										
											2021-11-07 17:32:50 +00:00
										 |  |  | 	begin | 
					
						
							|  |  |  | 		if C.Tk.Id = TK_CSTR then | 
					
						
							|  |  |  | 			-- arrange to feed more data from the included file.
 | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 			Push_Inclusion (C, S.To_Rune_Array(C.Tk.Buf)); | 
					
						
							| 
									
										
										
										
											2021-11-07 17:32:50 +00:00
										 |  |  | 		else | 
					
						
							| 
									
										
										
										
											2021-11-14 15:07:41 +00:00
										 |  |  | 			-- the target is not a string.
 | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 			--Dump_Token (C.Tk);
 | 
					
						
							| 
									
										
										
										
											2021-11-12 23:31:25 +00:00
										 |  |  | 			raise Syntax_Error with "string literal required"; | 
					
						
							| 
									
										
										
										
											2021-11-07 17:32:50 +00:00
										 |  |  | 		end if; | 
					
						
							| 
									
										
										
										
											2021-11-14 15:07:41 +00:00
										 |  |  | 	end Parse_Include_Target; | 
					
						
							| 
									
										
										
										
											2021-11-07 17:32:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-14 15:07:41 +00:00
										 |  |  | 	procedure Parse_Include_Terminator (C: in out Compiler) is | 
					
						
							| 
									
										
										
										
											2021-11-07 17:32:50 +00:00
										 |  |  | 	begin | 
					
						
							|  |  |  | 		if C.Tk.Id /= TK_SEMICOLON then | 
					
						
							| 
									
										
										
										
											2021-11-12 23:31:25 +00:00
										 |  |  | 			raise Syntax_Error with "semicolon required"; | 
					
						
							| 
									
										
										
										
											2021-11-07 17:32:50 +00:00
										 |  |  | 		end if; | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 		Pop_Parse_State (C); | 
					
						
							| 
									
										
										
										
											2021-11-14 15:07:41 +00:00
										 |  |  | 	end Parse_Include_Terminator; | 
					
						
							| 
									
										
										
										
											2021-11-07 17:32:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	procedure Got_Token (C: in out Compiler) is | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 		Dump_Token (C.Tk); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case C.Prs.States(C.Prs.Top).Current is | 
					
						
							| 
									
										
										
										
											2021-11-14 15:07:41 +00:00
										 |  |  | 			when PS_START => | 
					
						
							| 
									
										
										
										
											2021-11-07 17:32:50 +00:00
										 |  |  | 				Parse_Start (C); | 
					
						
							| 
									
										
										
										
											2021-12-03 06:38:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-14 15:07:41 +00:00
										 |  |  | 			when PS_INCLUDE_TARGET => | 
					
						
							|  |  |  | 				Parse_Include_Target (C); | 
					
						
							|  |  |  | 			when PS_INCLUDE_TERMINATOR => | 
					
						
							|  |  |  | 				Parse_Include_Terminator (C); | 
					
						
							| 
									
										
										
										
											2021-12-03 06:38:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			when PS_PLAIN_STATEMENT_START => | 
					
						
							|  |  |  | 				Parse_Plain_Statement_Start (C); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-07 17:32:50 +00:00
										 |  |  | 			when others => | 
					
						
							| 
									
										
										
										
											2021-11-14 15:07:41 +00:00
										 |  |  | 				raise Syntax_Error with "unknown parser state"; -- TODO: change this...
 | 
					
						
							| 
									
										
										
										
											2021-11-07 17:32:50 +00:00
										 |  |  | 		end case; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 	end Got_Token; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-28 17:00:17 +00:00
										 |  |  | 	function Is_Ident_Starter(Code: in R.Code) return Boolean is | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2021-12-01 17:06:30 +00:00
										 |  |  | 		return R.Is_Alnum(Code) or else | 
					
						
							|  |  |  | 		       R.Is_Rune(Code, R.V.Underline) or else | 
					
						
							|  |  |  | 		       R.Is_Rune(Code, R.V.Minus_Sign); | 
					
						
							| 
									
										
										
										
											2021-11-28 17:00:17 +00:00
										 |  |  | 	end Is_Ident_Starter; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Is_Ident_Char(Code: in R.Code) return Boolean is | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2021-12-01 17:06:30 +00:00
										 |  |  | 		return Is_Ident_Starter(Code); -- or else R.Is_Rune(Code, R.V.Underline); -- or else R.Is_Rune(C, ...);
 | 
					
						
							| 
									
										
										
										
											2021-11-28 17:00:17 +00:00
										 |  |  | 	end Is_Ident_Char; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 	procedure Feed_Char_Code (C: in out Compiler; Code: in R.Code) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 	<<Start_Over>> | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 		--Dump_Rune (Code);
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 		case C.Lx.State is | 
					
						
							|  |  |  | 			when LX_START => | 
					
						
							|  |  |  | 				if R.Is_Eof(Code) then | 
					
						
							| 
									
										
										
										
											2021-10-31 16:03:11 +00:00
										 |  |  | 					Start_Token (C, LB_EOF); | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 					End_Token (C, TK_EOF); | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 					-- this procedure doesn't prevent you from feeding more runes
 | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 					-- after EOF. but it's not desirable to feed more after EOF.
 | 
					
						
							| 
									
										
										
										
											2021-11-28 17:00:17 +00:00
										 |  |  | 				elsif R.Is_Rune(Code, R.V.LF) then  -- TODO: support a different EOL scheme
 | 
					
						
							|  |  |  | 					Start_Token (C, LB_EOL); | 
					
						
							|  |  |  | 					End_Token (C, TK_EOL); | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 				elsif R.Is_Space(Code) then | 
					
						
							|  |  |  | 					-- ignore. carry on
 | 
					
						
							|  |  |  | 					null; | 
					
						
							| 
									
										
										
										
											2021-11-28 17:00:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				elsif R.Is_Rune(Code, R.V.Number_Sign) then -- #
 | 
					
						
							|  |  |  | 					Set_Lexer_State (C, LX_HASHED, Code); | 
					
						
							|  |  |  | 				elsif R.Is_Rune(Code, R.V.Dollar_Sign) then -- $
 | 
					
						
							|  |  |  | 					Set_Lexer_State (C, LX_DOLLARED, Code); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				elsif R.Is_Rune(Code, R.V.Left_Curly_Bracket) then -- {
 | 
					
						
							|  |  |  | 					Start_Token (C, Code); | 
					
						
							|  |  |  | 					End_Token (C, TK_LBRACE); | 
					
						
							|  |  |  | 				elsif R.Is_Rune(Code, R.V.Right_Curly_Bracket) then -- }
 | 
					
						
							|  |  |  | 					Start_Token (C, Code); | 
					
						
							|  |  |  | 					End_Token (C, TK_RBRACE); | 
					
						
							|  |  |  | 				elsif R.Is_Rune(Code, R.V.Left_Square_Bracket) then -- [
 | 
					
						
							|  |  |  | 					Start_Token (C, Code); | 
					
						
							|  |  |  | 					End_Token (C, TK_LBRACK); | 
					
						
							|  |  |  | 				elsif R.Is_Rune(Code, R.V.Right_Square_Bracket) then -- ]
 | 
					
						
							|  |  |  | 					Start_Token (C, Code); | 
					
						
							|  |  |  | 					End_Token (C, TK_RBRACK); | 
					
						
							|  |  |  | 				elsif R.Is_Rune(Code, R.V.Left_Parenthesis) then -- (
 | 
					
						
							|  |  |  | 					Start_Token (C, Code); | 
					
						
							|  |  |  | 					End_Token (C, TK_LPAREN); | 
					
						
							|  |  |  | 				elsif R.Is_Rune(Code, R.V.Right_Parenthesis) then -- )
 | 
					
						
							|  |  |  | 					Start_Token (C, Code); | 
					
						
							|  |  |  | 					End_Token (C, TK_RPAREN); | 
					
						
							|  |  |  | 				elsif R.Is_Rune(Code, R.V.Semicolon) then -- ;
 | 
					
						
							|  |  |  | 					Start_Token (C, Code); | 
					
						
							|  |  |  | 					End_Token (C, TK_SEMICOLON); | 
					
						
							| 
									
										
										
										
											2021-12-01 17:06:30 +00:00
										 |  |  | 				elsif R.Is_Rune(Code, R.V.Colon) then -- :
 | 
					
						
							|  |  |  | 					Set_Lexer_State (C, LX_COLON, Code); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				elsif R.Is_Rune(Code, R.V.Quotation) then -- "
 | 
					
						
							|  |  |  | 					Set_Lexer_State (C, LX_CSTR); | 
					
						
							| 
									
										
										
										
											2021-11-28 17:00:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				elsif Is_Ident_Starter(Code) then | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 					Set_Lexer_State (C, LX_IDENT, Code); | 
					
						
							|  |  |  | 				elsif R.Is_Digit(Code) then | 
					
						
							|  |  |  | 					Set_Lexer_State (C, LX_NUMBER, Code); | 
					
						
							| 
									
										
										
										
											2021-12-01 17:06:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				--elsif R.Is_Rune(Code, R.V.Plus_Sign) then -- +
 | 
					
						
							|  |  |  | 				--	Set_Lexer_State (C, LX_OP_PLUS, Code);
 | 
					
						
							|  |  |  | 				--elsif R.Is_Rune(Code, R.V.Minus_Sign) then -- -
 | 
					
						
							|  |  |  | 				--	Set_Lexer_State (C, LX_OP_MINUS, Code);
 | 
					
						
							|  |  |  | 				--elsif R.Is_Rune(Code, R.V.Asterisk) then -- *
 | 
					
						
							|  |  |  | 				--	Set_Lexer_State (C, LX_OP_MUL, Code);
 | 
					
						
							|  |  |  | 				--elsif R.Is_Rune(Code, R.V.Slash) then -- /
 | 
					
						
							|  |  |  | 				--	Set_Lexer_State (C, LX_OP_DIV, Code);
 | 
					
						
							|  |  |  | 				--elsif R.Is_Rune(Code, R.V.Left_Arrow) then -- <
 | 
					
						
							|  |  |  | 				--	Set_Lexer_State (C, LX_OP_LESS, Code);
 | 
					
						
							|  |  |  | 				--elsif R.Is_Rune(Code, R.V.Right_Arrow) then -- >
 | 
					
						
							|  |  |  | 				--	Set_Lexer_State (C, LX_OP_GREATER, Code);
 | 
					
						
							|  |  |  | 				 | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 				else | 
					
						
							|  |  |  | 					raise Syntax_Error; | 
					
						
							|  |  |  | 				end if; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-01 17:06:30 +00:00
										 |  |  | 			when LX_COLON => | 
					
						
							|  |  |  | 				if R.Is_Rune(Code, R.V.Equal_Sign) then -- :=
 | 
					
						
							|  |  |  | 					End_Token (C, TK_ASSIGN, Code); | 
					
						
							| 
									
										
										
										
											2021-11-02 00:31:30 +00:00
										 |  |  | 				else | 
					
						
							| 
									
										
										
										
											2021-12-01 17:06:30 +00:00
										 |  |  | 					End_Token (C, TK_COLON); | 
					
						
							| 
									
										
										
										
											2021-11-02 00:31:30 +00:00
										 |  |  | 					goto Start_Over; | 
					
						
							|  |  |  | 				end if; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-12 23:31:25 +00:00
										 |  |  | 			when LX_COMMENT => | 
					
						
							| 
									
										
										
										
											2021-11-28 17:00:17 +00:00
										 |  |  | 				if R.Is_Eof(Code) then | 
					
						
							|  |  |  | 					Set_Lexer_State (C, LX_START); | 
					
						
							|  |  |  | 					goto Start_Over; | 
					
						
							|  |  |  | 				elsif R.Is_Rune(Code, R.V.LF) then -- TODO: support a different EOL scheme
 | 
					
						
							|  |  |  | 					Start_Token (C, LB_EOL); | 
					
						
							|  |  |  | 					End_Token (C, TK_EOL); | 
					
						
							|  |  |  | 				end if; | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-12 23:31:25 +00:00
										 |  |  | 			when LX_CSTR => | 
					
						
							|  |  |  | 				-- TODO: escaping...
 | 
					
						
							|  |  |  | 				if R.Is_Rune(Code, R.V.Quotation) then | 
					
						
							|  |  |  | 					End_Token (C, TK_CSTR); | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 				else | 
					
						
							| 
									
										
										
										
											2021-11-12 23:31:25 +00:00
										 |  |  | 					Feed_Token (C, Code); | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 				end if; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-01 17:06:30 +00:00
										 |  |  | 			when LX_DIRECTIVE => | 
					
						
							|  |  |  | 				if R.Is_Alnum(Code) or else R.Is_Rune(Code, R.V.Underline) then | 
					
						
							|  |  |  | 					Feed_Token (C, Code); | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					End_Token (C, TK_DIRECTIVE); | 
					
						
							|  |  |  | 					goto Start_Over; | 
					
						
							|  |  |  | 				end if; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-28 17:00:17 +00:00
										 |  |  | 			when LX_DOLLARED => | 
					
						
							|  |  |  | 				if R.Is_Rune(Code, R.V.Left_Curly_Bracket) then | 
					
						
							|  |  |  | 					End_Token (C, TK_DOLLARED_LBRACE, Code); | 
					
						
							|  |  |  | 				elsif R.Is_Rune(Code, R.V.Left_Square_Bracket) then | 
					
						
							|  |  |  | 					End_Token (C, TK_DOLLARED_LBRACK, Code); | 
					
						
							|  |  |  | 				elsif R.Is_Rune(Code, R.V.Left_Parenthesis) then | 
					
						
							|  |  |  | 					End_Token (C, TK_DOLLARED_LPAREN, Code); | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					raise Syntax_Error with "invalid dollared token"; | 
					
						
							|  |  |  | 				end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			when LX_HASHED => | 
					
						
							| 
									
										
										
										
											2021-10-31 05:41:19 +00:00
										 |  |  | 				if R.Is_Alnum(Code) or else R.Is_Rune(Code, R.V.Underline) then | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 					Feed_Token (C, Code); | 
					
						
							| 
									
										
										
										
											2021-11-28 17:00:17 +00:00
										 |  |  | 					Switch_Lexer_State (C, LX_DIRECTIVE); | 
					
						
							| 
									
										
										
										
											2021-12-01 17:06:30 +00:00
										 |  |  | 				elsif R.Is_Rune(Code, R.V.Number_Sign) or else R.Is_Rune(Code, R.V.Exclamation) then -- ## or #!
 | 
					
						
							| 
									
										
										
										
											2021-11-28 17:00:17 +00:00
										 |  |  | 					Set_Lexer_State (C, LX_COMMENT); | 
					
						
							|  |  |  | 				elsif R.Is_Rune(Code, R.V.Left_Curly_Bracket) then | 
					
						
							|  |  |  | 					End_Token (C, TK_HASHED_LBRACE, Code); | 
					
						
							|  |  |  | 				elsif R.Is_Rune(Code, R.V.Left_Square_Bracket) then | 
					
						
							|  |  |  | 					End_Token (C, TK_HASHED_LBRACK, Code); | 
					
						
							|  |  |  | 				elsif R.Is_Rune(Code, R.V.Left_Parenthesis) then | 
					
						
							|  |  |  | 					End_Token (C, TK_HASHED_LPAREN, Code); | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					raise Syntax_Error with "invalid hashed token"; | 
					
						
							|  |  |  | 				end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			when LX_IDENT => | 
					
						
							|  |  |  | 				if Is_Ident_Char(Code) then | 
					
						
							|  |  |  | 					Feed_Token (C, Code); | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 				else | 
					
						
							|  |  |  | 					End_Token (C, TK_IDENT); | 
					
						
							|  |  |  | 					goto Start_Over; | 
					
						
							|  |  |  | 				end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			when LX_NUMBER => | 
					
						
							|  |  |  | 				if R.Is_Digit(Code) then | 
					
						
							|  |  |  | 					Feed_Token (C, Code); | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					End_Token (C, TK_IDENT); -- TODO: change this
 | 
					
						
							|  |  |  | 					goto Start_Over; | 
					
						
							|  |  |  | 				end if; | 
					
						
							| 
									
										
										
										
											2021-11-12 23:31:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 			when LX_OP_PLUS => | 
					
						
							|  |  |  | 				if R.Is_Rune(Code, R.V.Plus_Sign) then | 
					
						
							|  |  |  | 					End_Token (C, TK_PLUSPLUS, Code); | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					End_Token (C, TK_PLUS); | 
					
						
							|  |  |  | 					goto Start_Over; | 
					
						
							|  |  |  | 				end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			when LX_OP_MINUS => | 
					
						
							|  |  |  | 				if R.Is_Rune(Code, R.V.Minus_Sign) then | 
					
						
							|  |  |  | 					End_Token (C, TK_MINUSMINUS, Code); | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					End_Token (C, TK_MINUS); | 
					
						
							|  |  |  | 					goto Start_Over; | 
					
						
							|  |  |  | 				end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			when LX_OP_MUL => | 
					
						
							|  |  |  | 				if R.Is_Rune(Code, R.V.Asterisk) then | 
					
						
							|  |  |  | 					End_Token (C, TK_MULMUL, Code); | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					End_Token (C, TK_MUL); | 
					
						
							|  |  |  | 					goto Start_Over; | 
					
						
							|  |  |  | 				end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			when LX_OP_DIV => | 
					
						
							|  |  |  | 				if R.Is_Rune(Code, R.V.Slash) then | 
					
						
							|  |  |  | 					End_Token (C, TK_DIVDIV, Code); | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					End_Token (C, TK_DIV); | 
					
						
							|  |  |  | 					goto Start_Over; | 
					
						
							|  |  |  | 				end if; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-12 23:31:25 +00:00
										 |  |  | 			when LX_OP_GREATER => | 
					
						
							|  |  |  | 				if R.Is_Rune(Code, R.V.Equal_Sign) then | 
					
						
							|  |  |  | 					End_Token (C, TK_GE, Code); | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					End_Token (C, TK_GT); | 
					
						
							|  |  |  | 					goto Start_Over; | 
					
						
							|  |  |  | 				end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			when LX_OP_LESS => | 
					
						
							|  |  |  | 				if R.Is_Rune(Code, R.V.Equal_sign) then | 
					
						
							|  |  |  | 					End_Token (C, TK_LE, Code); | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					End_Token (C, TK_LT); | 
					
						
							|  |  |  | 					goto Start_Over; | 
					
						
							|  |  |  | 				end if; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 		end case; | 
					
						
							|  |  |  | 	end Feed_Char_Code; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-14 15:07:41 +00:00
										 |  |  | 	procedure Feed_Inc (C: in out Compiler) is | 
					
						
							| 
									
										
										
										
											2021-11-28 17:00:17 +00:00
										 |  |  | 		-- Feed the contents of a included stream.	
 | 
					
						
							| 
									
										
										
										
											2021-11-14 15:07:41 +00:00
										 |  |  | 		Entry_Top: constant System_Index := C.Inc.Top; | 
					
						
							| 
									
										
										
										
											2021-11-28 17:00:17 +00:00
										 |  |  | 		Use_Immediate: constant Boolean := True; | 
					
						
							| 
									
										
										
										
											2021-11-14 15:07:41 +00:00
										 |  |  | 	begin | 
					
						
							|  |  |  | 		loop | 
					
						
							|  |  |  | 			while not Ada.Text_IO.End_Of_File(C.Inc.Streams(C.Inc.Top).Handle) loop | 
					
						
							|  |  |  | 				declare | 
					
						
							|  |  |  | 					Ch: Standard.Character; | 
					
						
							|  |  |  | 				begin | 
					
						
							| 
									
										
										
										
											2021-11-28 17:00:17 +00:00
										 |  |  | 					-- Get() skips line terminators. End_Of_Line() checks if it reaches EOL 
 | 
					
						
							|  |  |  | 					-- but can't handle multiple consecutive EOLs. Get_Immediate() doesn't
 | 
					
						
							|  |  |  | 					-- skip EOLs. As detecting every EOL in the multiple consecutive sequence
 | 
					
						
							|  |  |  | 					-- is not required, End_Of_Line()+Get() is good too.
 | 
					
						
							|  |  |  | 					if Use_Immediate then | 
					
						
							|  |  |  | 						Ada.Text_IO.Get_Immediate (C.Inc.Streams(C.Inc.Top).Handle, Ch); | 
					
						
							|  |  |  | 					else | 
					
						
							|  |  |  | 						if Ada.Text_IO.End_Of_Line(C.Inc.Streams(C.Inc.Top).Handle) then | 
					
						
							|  |  |  | 							Feed_Char_Code (C, R.P.LF); | 
					
						
							|  |  |  | 						end if; | 
					
						
							|  |  |  | 						Ada.Text_IO.Get (C.Inc.Streams(C.Inc.Top).Handle, Ch); | 
					
						
							|  |  |  | 					end if; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-14 15:07:41 +00:00
										 |  |  | 					Feed_Char_Code (C, Standard.Character'Pos(Ch)); | 
					
						
							|  |  |  | 				end; | 
					
						
							|  |  |  | 				-- After each feed, C.Inc.Top may get incremented if an inclusion
 | 
					
						
							|  |  |  | 				-- directive is found. so the while loop iterates over the streams
 | 
					
						
							|  |  |  | 				-- of all inner included levels. End_Feed() below drops C.Inc.Top
 | 
					
						
							|  |  |  | 				-- and the outer loop will resume the inner while loop at the outer
 | 
					
						
							|  |  |  | 				-- inclusion level until all entered inclusion levels are exited.
 | 
					
						
							|  |  |  | 			end loop; | 
					
						
							|  |  |  | 			End_Feed (C); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if C.Inc.Top < Entry_Top then | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 				-- Pop_Inclusion() is called on EOF which is fed by End_Feed().
 | 
					
						
							| 
									
										
										
										
											2021-11-14 15:07:41 +00:00
										 |  |  | 				-- It also decrements the stack pointer. The current inclusion
 | 
					
						
							|  |  |  | 				-- stack pointer will get less that First_Top if the first inclusion
 | 
					
						
							|  |  |  | 				-- level entered is exited.
 | 
					
						
							|  |  |  | 				exit; | 
					
						
							|  |  |  | 			end if; | 
					
						
							|  |  |  | 		end loop; | 
					
						
							|  |  |  | 	end Feed_Inc; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 	procedure Feed (C: in out Compiler; Data: in S.Rune_Array) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		for i in Data'Range loop | 
					
						
							|  |  |  | 			Feed_Char_Code (C, R.To_Code(Data(i))); | 
					
						
							| 
									
										
										
										
											2021-11-14 15:07:41 +00:00
										 |  |  | 			if C.Inc.Top > 0 then | 
					
						
							|  |  |  | 				Feed_Inc (C); | 
					
						
							| 
									
										
										
										
											2021-11-07 17:32:50 +00:00
										 |  |  | 			end if; | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 		end loop; | 
					
						
							|  |  |  | 	end Feed; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure End_Feed (C: in out Compiler) is | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2021-10-31 16:03:11 +00:00
										 |  |  | 		Feed_Char_Code (C, R.P.EOF); | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | 	end End_Feed; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	-- -------------------------------------------------------------------
 | 
					
						
							|  |  |  | 	procedure Initialize (C: in out Compiler) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Push_Parse_State (C, PS_START); | 
					
						
							| 
									
										
										
										
											2021-12-11 15:57:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		declare | 
					
						
							|  |  |  | 			X: H3.Trees.Tree; | 
					
						
							|  |  |  | 		begin | 
					
						
							|  |  |  | 			H3.Trees.New_Node (X); | 
					
						
							|  |  |  | 		end; | 
					
						
							| 
									
										
										
										
											2021-11-16 13:34:32 +00:00
										 |  |  | 	end Initialize; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Finalize (C: in out Compiler) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		while C.Inc.Top > 0 loop | 
					
						
							|  |  |  | 			Pop_Inclusion (C, False); | 
					
						
							|  |  |  | 		end loop; | 
					
						
							|  |  |  | 		while C.Prs.Top > 0 loop | 
					
						
							|  |  |  | 			Pop_Parse_State (C); | 
					
						
							|  |  |  | 		end loop; | 
					
						
							|  |  |  | 	end Finalize; | 
					
						
							| 
									
										
										
										
											2021-10-30 01:57:19 +00:00
										 |  |  | end H3.Compilers; |