adding experimental changes
This commit is contained in:
		| @ -7,6 +7,8 @@ generic | |||||||
| 	G_Terminator_Value: Item_Type; | 	G_Terminator_Value: Item_Type; | ||||||
| package H3.Arrays is | package H3.Arrays is | ||||||
|  |  | ||||||
|  | 	subtype Item is Item_Type; | ||||||
|  |  | ||||||
| 	Terminator_Length: constant System_Zero_Or_One := G_Terminator_Length; | 	Terminator_Length: constant System_Zero_Or_One := G_Terminator_Length; | ||||||
| 	Terminator_Value: constant Item_Type := G_Terminator_Value; | 	Terminator_Value: constant Item_Type := G_Terminator_Value; | ||||||
|  |  | ||||||
|  | |||||||
							
								
								
									
										159
									
								
								lib2/h3-cc.adb
									
									
									
									
									
								
							
							
						
						
									
										159
									
								
								lib2/h3-cc.adb
									
									
									
									
									
								
							| @ -5,86 +5,146 @@ package body H3.CC is | |||||||
| 	package UC renames System.UTF_32; | 	package UC renames System.UTF_32; | ||||||
| 	use type System.UTF_32.Category; | 	use type System.UTF_32.Category; | ||||||
|  |  | ||||||
| 	SP: constant Item_Type := Item_Type'Val(32); | 	SP: constant Rune := Rune'Val(32); | ||||||
| 	HT: constant Item_Type := Item_Type'Val(9); | 	HT: constant Rune := Rune'Val(9); | ||||||
|  |  | ||||||
| 	function Is_Alpha (V: in Item_Type) return Boolean is | 	function Is_Alpha (V: in Rune) return Boolean is | ||||||
| 	begin | 	begin | ||||||
| 		return UC.Is_UTF_32_Letter(Item_Type'Pos(V)); | 		return UC.Is_UTF_32_Letter(Rune'Pos(V)); | ||||||
| 	end Is_Alpha; | 	end Is_Alpha; | ||||||
|  |  | ||||||
| 	function Is_Alnum (V: in Item_Type) return Boolean is | 	function Is_Alpha (C: in Code) return Boolean is | ||||||
| 	begin | 	begin | ||||||
| 		return UC.Is_UTF_32_Letter(Item_Type'Pos(V)) or else | 		return not Is_Eof(C) and then Is_Alpha(Rune'Val(C)); | ||||||
| 		       UC.Is_UTF_32_Digit(Item_Type'Pos(V)); | 	end Is_Alpha; | ||||||
|  |  | ||||||
|  | 	function Is_Alnum (V: in Rune) return Boolean is | ||||||
|  | 	begin | ||||||
|  | 		return UC.Is_UTF_32_Letter(Rune'Pos(V)) or else | ||||||
|  | 		       UC.Is_UTF_32_Digit(Rune'Pos(V)); | ||||||
| 	end Is_Alnum; | 	end Is_Alnum; | ||||||
|  |  | ||||||
| 	function Is_Blank (V: in Item_Type) return Boolean is | 	function Is_Alnum (C: in Code) return Boolean is | ||||||
|  | 	begin | ||||||
|  | 		return not Is_Eof(C) and then Is_Alnum(Rune'Val(C)); | ||||||
|  | 	end Is_Alnum; | ||||||
|  |  | ||||||
|  | 	function Is_Blank (V: in Rune) return Boolean is | ||||||
| 	begin | 	begin | ||||||
| 		return V = SP or else V = HT; | 		return V = SP or else V = HT; | ||||||
| 	end Is_Blank; | 	end Is_Blank; | ||||||
|  |  | ||||||
| 	function Is_Cntrl (V: in Item_Type) return Boolean is | 	function Is_Blank (C: in Code) return Boolean is | ||||||
| 	begin | 	begin | ||||||
| 		return UC.Get_Category(Item_Type'Pos(V)) = UC.Cc; | 		return not Is_Eof(C) and then Is_Blank(Rune'Val(C)); | ||||||
|  | 	end Is_Blank; | ||||||
|  |  | ||||||
|  | 	function Is_Cntrl (V: in Rune) return Boolean is | ||||||
|  | 	begin | ||||||
|  | 		return UC.Get_Category(Rune'Pos(V)) = UC.Cc; | ||||||
| 	end Is_Cntrl; | 	end Is_Cntrl; | ||||||
|  |  | ||||||
| 	function Is_Digit (V: in Item_Type) return Boolean is | 	function Is_Cntrl (C: in Code) return Boolean is | ||||||
| 	begin | 	begin | ||||||
| 		return UC.Is_UTF_32_Digit(Item_Type'Pos(V)); | 		return not Is_Eof(C) and then Is_Cntrl(Rune'Val(C)); | ||||||
|  | 	end Is_Cntrl; | ||||||
|  |  | ||||||
|  | 	function Is_Digit (V: in Rune) return Boolean is | ||||||
|  | 	begin | ||||||
|  | 		return UC.Is_UTF_32_Digit(Rune'Pos(V)); | ||||||
| 	end Is_Digit; | 	end Is_Digit; | ||||||
|  |  | ||||||
| 	function Is_Graph (V: in Item_Type) return Boolean is | 	function Is_Digit (C: in Code) return Boolean is | ||||||
|  | 	begin | ||||||
|  | 		return not Is_Eof(C) and then Is_Digit(Rune'Val(C)); | ||||||
|  | 	end Is_Digit; | ||||||
|  |  | ||||||
|  | 	function Is_Graph (V: in Rune) return Boolean is | ||||||
| 	begin | 	begin | ||||||
| 		return Is_Print(V) and then V /= SP; | 		return Is_Print(V) and then V /= SP; | ||||||
| 	end Is_Graph; | 	end Is_Graph; | ||||||
|  |  | ||||||
| 	function Is_Lower (V: in Item_Type) return Boolean is | 	function Is_Graph (C: in Code) return Boolean is | ||||||
| 	begin | 	begin | ||||||
| 		return UC.Get_Category(Item_Type'Pos(V)) = UC.Ll; | 		return not Is_Eof(C) and then Is_Graph(Rune'Val(C)); | ||||||
|  | 	end Is_Graph; | ||||||
|  |  | ||||||
|  | 	function Is_Lower (V: in Rune) return Boolean is | ||||||
|  | 	begin | ||||||
|  | 		return UC.Get_Category(Rune'Pos(V)) = UC.Ll; | ||||||
| 	end Is_Lower; | 	end Is_Lower; | ||||||
|  |  | ||||||
| 	function Is_Print (V: in Item_Type) return Boolean is | 	function Is_Lower (C: in Code) return Boolean is | ||||||
| 	begin | 	begin | ||||||
| 		return not UC.IS_UTF_32_Non_Graphic(Item_Type'Pos(V)); | 		return not Is_Eof(C) and then Is_Lower(Rune'Val(C)); | ||||||
|  | 	end Is_Lower; | ||||||
|  |  | ||||||
|  | 	function Is_Print (V: in Rune) return Boolean is | ||||||
|  | 	begin | ||||||
|  | 		return not UC.IS_UTF_32_Non_Graphic(Rune'Pos(V)); | ||||||
| 	end Is_Print; | 	end Is_Print; | ||||||
|  |  | ||||||
| 	function Is_Punct (V: in Item_Type) return Boolean is | 	function Is_Print (C: in Code) return Boolean is | ||||||
| 	begin | 	begin | ||||||
| 		--return UC.Is_UTF_32_Punctuation(Item_Type'Pos(V)); | 		return not Is_Eof(C) and then Is_Print(Rune'Val(C)); | ||||||
|  | 	end Is_Print; | ||||||
|  |  | ||||||
|  | 	function Is_Punct (V: in Rune) return Boolean is | ||||||
|  | 	begin | ||||||
|  | 		--return UC.Is_UTF_32_Punctuation(Rune'Pos(V)); | ||||||
| 		return Is_Print(V) and then not Is_Space(V) and then not Is_Alnum(V); | 		return Is_Print(V) and then not Is_Space(V) and then not Is_Alnum(V); | ||||||
| 	end Is_Punct; | 	end Is_Punct; | ||||||
|  |  | ||||||
| 	function Is_Space (V: in Item_Type) return Boolean is | 	function Is_Punct (C: in Code) return Boolean is | ||||||
| 	begin | 	begin | ||||||
| 		return UC.Is_UTF_32_Space(Item_Type'Pos(V)) or else | 		return not Is_Eof(C) and then Is_Punct(Rune'Val(C)); | ||||||
| 		       UC.Is_UTF_32_Line_Terminator(Item_Type'Pos(V)) or else | 	end Is_Punct; | ||||||
|  |  | ||||||
|  | 	function Is_Space (V: in Rune) return Boolean is | ||||||
|  | 	begin | ||||||
|  | 		return UC.Is_UTF_32_Space(Rune'Pos(V)) or else | ||||||
|  | 		       UC.Is_UTF_32_Line_Terminator(Rune'Pos(V)) or else | ||||||
| 		       V = HT; | 		       V = HT; | ||||||
| 	end Is_Space; | 	end Is_Space; | ||||||
|  |  | ||||||
| 	function Is_Upper (V: in Item_Type) return Boolean is | 	function Is_Space (C: in Code) return Boolean is | ||||||
| 	begin | 	begin | ||||||
| 		return UC.Get_Category(Item_Type'Pos(V)) = UC.Lu; | 		return not Is_Eof(C) and then Is_Space(Rune'Val(C)); | ||||||
|  | 	end Is_Space; | ||||||
|  |  | ||||||
|  | 	function Is_Upper (V: in Rune) return Boolean is | ||||||
|  | 	begin | ||||||
|  | 		return UC.Get_Category(Rune'Pos(V)) = UC.Lu; | ||||||
| 	end Is_Upper; | 	end Is_Upper; | ||||||
|  |  | ||||||
| 	function Is_Xdigit (V: in Item_Type) return Boolean is | 	function Is_Upper (C: in Code) return Boolean is | ||||||
| 	begin | 	begin | ||||||
| 		return UC.Is_UTF_32_Digit(Item_Type'Pos(V)) or else | 		return not Is_Eof(C) and then Is_Upper(Rune'Val(C)); | ||||||
| 		       Item_Type'Pos(V) in System_Character'Pos('A') .. System_Character'Pos('F') or else | 	end Is_Upper; | ||||||
| 		       Item_Type'Pos(V) in System_Character'Pos('a') .. System_Character'Pos('f'); |  | ||||||
|  | 	function Is_Xdigit (V: in Rune) return Boolean is | ||||||
|  | 	begin | ||||||
|  | 		return UC.Is_UTF_32_Digit(Rune'Pos(V)) or else | ||||||
|  | 		       Rune'Pos(V) in System_Rune'Pos('A') .. System_Rune'Pos('F') or else | ||||||
|  | 		       Rune'Pos(V) in System_Rune'Pos('a') .. System_Rune'Pos('f'); | ||||||
| 	end Is_Xdigit; | 	end Is_Xdigit; | ||||||
|  |  | ||||||
| 	function To_Lower (V: in Item_Type) return Item_Type is | 	function Is_Xdigit (C: in Code) return Boolean is | ||||||
| 	begin | 	begin | ||||||
| 		return Item_Type'Val(UC.UTF_32_To_Lower_Case(Item_Type'Pos(V))); | 		return not Is_Eof(C) and then Is_Xdigit(Rune'Val(C)); | ||||||
|  | 	end Is_Xdigit; | ||||||
|  |  | ||||||
|  | 	function To_Lower (V: in Rune) return Rune is | ||||||
|  | 	begin | ||||||
|  | 		return Rune'Val(UC.UTF_32_To_Lower_Case(Rune'Pos(V))); | ||||||
| 	end To_Lower; | 	end To_Lower; | ||||||
|  |  | ||||||
| 	function To_Upper (V: in Item_Type) return Item_Type is | 	function To_Upper (V: in Rune) return Rune is | ||||||
| 	begin | 	begin | ||||||
| 		return Item_Type'Val(UC.UTF_32_To_Upper_Case(Item_Type'Pos(V))); | 		return Rune'Val(UC.UTF_32_To_Upper_Case(Rune'Pos(V))); | ||||||
| 	end To_Upper; | 	end To_Upper; | ||||||
|  |  | ||||||
| 	function Is_Class (V: in Item_Type; Class: in Item_Class) return Boolean is | 	function Is_Class (V: in Rune; Class: in Item_Class) return Boolean is | ||||||
| 	begin | 	begin | ||||||
| 		case Class is | 		case Class is | ||||||
| 			when ALPHA => return Is_Alpha(V); | 			when ALPHA => return Is_Alpha(V); | ||||||
| @ -102,10 +162,37 @@ package body H3.CC is | |||||||
| 		end case; | 		end case; | ||||||
| 	end Is_Class; | 	end Is_Class; | ||||||
|  |  | ||||||
| 	function Is_Code (V: in Item_Type; Code: in Item_Code) return Boolean is | 	function Is_Class (C: in Code; Class: in Item_Class) return Boolean is | ||||||
|  | 	begin | ||||||
|  | 		return not Is_Eof(C) and then Is_Class(To_Rune(C), Class); | ||||||
|  | 	end Is_Class; | ||||||
|  |  | ||||||
|  | 	function Is_Eof (C: in Code) return Boolean is | ||||||
|  | 	begin | ||||||
|  | 		return C = EOF; | ||||||
|  | 	end Is_Eof; | ||||||
|  |  | ||||||
|  | 	function Is_Code (V: in Rune; C: in Code) return Boolean is | ||||||
| 	begin | 	begin | ||||||
| 		-- a clumsy way to work around strong type checking | 		-- a clumsy way to work around strong type checking | ||||||
| 		-- with unknown Item_Type at the generic level? | 		-- with unknown Rune at the generic level? | ||||||
| 		return Item_Type'Pos(V) = Code; | 		return To_Code(V) = C; | ||||||
| 	end Is_Code; | 	end Is_Code; | ||||||
|  |  | ||||||
|  | 	function Is_Rune (C: in Code; V: in Rune) return Boolean is | ||||||
|  | 	begin | ||||||
|  | 		return To_Code(V) = C; | ||||||
|  | 	end Is_Rune; | ||||||
|  |  | ||||||
|  | 	function To_Rune (C: in Code) return Rune is | ||||||
|  | 	begin | ||||||
|  | 		pragma Assert (not Is_Eof(C)); | ||||||
|  | 		return Rune'Val(C); | ||||||
|  | 	end To_Rune; | ||||||
|  |  | ||||||
|  | 	function To_Code (V: in Rune) return Code is | ||||||
|  | 	begin | ||||||
|  | 		return Rune'Pos(V); | ||||||
|  | 	end To_Code; | ||||||
|  |  | ||||||
| end H3.CC; | end H3.CC; | ||||||
							
								
								
									
										121
									
								
								lib2/h3-cc.ads
									
									
									
									
									
								
							
							
						
						
									
										121
									
								
								lib2/h3-cc.ads
									
									
									
									
									
								
							| @ -1,38 +1,105 @@ | |||||||
| generic | generic | ||||||
| 	type Item_Type is (<>); -- any discrete type | 	-- any discrete type accepted. | ||||||
|  | 	-- can't ada limit type to one of Character, Wide_Character, Wide_Wide_Character? | ||||||
|  | 	type Rune_Type is (<>);  | ||||||
| package H3.CC is | package H3.CC is | ||||||
| 	-- <ctype.h>-like character classification package | 	-- <ctype.h>-like character classification plus other features. | ||||||
| 	-- unicode-based. no system locale honored. | 	-- unicode-based. no system locale honored. | ||||||
|  |  | ||||||
| 	subtype Item_Code is H3.Natural; | 	subtype Rune is Rune_Type; | ||||||
|  | 	type Code is range -1 .. 16#7FFF_FFFF#; | ||||||
|  |  | ||||||
| 	Colon: constant Item_Code := System_Character'Pos(':'); | 	-- virtual code to indicate end of input | ||||||
| 	Semicolon: constant Item_Code := System_Character'Pos(';'); | 	EOF: constant Code := Code'First; | ||||||
| 	Tilde: constant Item_Code := System_Character'Pos('~'); |  | ||||||
| 	Underline: constant Item_Code := System_Character'Pos('_'); |  | ||||||
| 	Equal: constant Item_Code := System_Character'Pos('='); |  | ||||||
| 	L_Arrow: constant Item_Code := System_Character'Pos('<'); |  | ||||||
| 	R_Arrow: constant Item_Code := System_Character'Pos('>'); |  | ||||||
|  |  | ||||||
| 	type Item_Class is (ALPHA, ALNUM, BLANK, CNTRL, DIGIT, GRAPH, LOWER, PRINT, PUNCT, SPACE, UPPER, XDIGIT); | 	C_Colon: constant Code := System_Rune'Pos(':'); | ||||||
| 	function Is_Class (V: in Item_Type; Class: in Item_Class) return Boolean; | 	C_Semicolon: constant Code := System_Rune'Pos(';'); | ||||||
|  | 	C_Tilde: constant Code := System_Rune'Pos('~'); | ||||||
|  | 	C_Underline: constant Code := System_Rune'Pos('_'); | ||||||
|  | 	C_Equal: constant Code := System_Rune'Pos('='); | ||||||
|  | 	C_Left_Arrow: constant Code := System_Rune'Pos('<'); | ||||||
|  | 	C_Right_Arrow: constant Code := System_Rune'Pos('>'); | ||||||
|  |  | ||||||
| 	function Is_Alpha (V: in Item_Type) return Boolean; | 	C_A: constant Code := System_Rune'Pos('A'); | ||||||
| 	function Is_Alnum (V: in Item_Type) return Boolean; | 	C_B: constant Code := System_Rune'Pos('B'); | ||||||
| 	function Is_Blank (V: in Item_Type) return Boolean; | 	C_C: constant Code := System_Rune'Pos('C'); | ||||||
| 	function Is_Cntrl (V: in Item_Type) return Boolean; | 	C_D: constant Code := System_Rune'Pos('D'); | ||||||
| 	function Is_Digit (V: in Item_Type) return Boolean; | 	C_E: constant Code := System_Rune'Pos('E'); | ||||||
| 	function Is_Graph (V: in Item_Type) return Boolean; |  | ||||||
| 	function Is_Print (V: in Item_Type) return Boolean; |  | ||||||
| 	function Is_Punct (V: in Item_Type) return Boolean; |  | ||||||
| 	function Is_Space (V: in Item_Type) return Boolean; |  | ||||||
| 	function Is_Xdigit (V: in Item_Type) return Boolean; |  | ||||||
|  |  | ||||||
| 	function Is_Lower (V: in Item_Type) return Boolean; | 	Colon: constant Rune := Rune'Val(C_Colon); | ||||||
| 	function Is_Upper (V: in Item_Type) return Boolean; | 	Semicolon: constant Rune := Rune'Val(C_Semicolon); | ||||||
|  | 	Tilde: constant Rune := Rune'Val(C_Tilde); | ||||||
|  | 	Underline: constant Rune := Rune'Val(C_Underline); | ||||||
|  | 	Equal: constant Rune := Rune'Val(C_Equal); | ||||||
|  | 	Left_Arrow: constant Rune := Rune'Val(C_Left_Arrow); | ||||||
|  | 	Right_Arrow: constant Rune := Rune'Val(C_Right_Arrow); | ||||||
|  |  | ||||||
| 	function To_Lower (V: in Item_Type) return Item_Type; | 	UC_A: constant Rune := Rune'Val(C_A); | ||||||
| 	function To_Upper (V: in Item_Type) return Item_Type; | 	UC_B: constant Rune := Rune'Val(C_B); | ||||||
|  | 	UC_C: constant Rune := Rune'Val(C_C); | ||||||
|  | 	UC_D: constant Rune := Rune'Val(C_D); | ||||||
|  | 	UC_E: constant Rune := Rune'Val(C_E); | ||||||
|  | 	UC_O: constant Rune := Rune'Val(System_Rune'Pos('O')); | ||||||
|  | 	UC_F: constant Rune := Rune'Val(System_Rune'Pos('F')); | ||||||
|  |  | ||||||
|  | 	type Item_Class is ( | ||||||
|  | 		ALPHA, | ||||||
|  | 		ALNUM, | ||||||
|  | 		BLANK, | ||||||
|  | 		CNTRL, | ||||||
|  | 		DIGIT, | ||||||
|  | 		GRAPH, | ||||||
|  | 		LOWER, | ||||||
|  | 		PRINT, | ||||||
|  | 		PUNCT, | ||||||
|  | 		SPACE, | ||||||
|  | 		UPPER, | ||||||
|  | 		XDIGIT | ||||||
|  | 	); | ||||||
|  |  | ||||||
|  | 	function Is_Alpha (V: in Rune) return Boolean; | ||||||
|  | 	function Is_Alnum (V: in Rune) return Boolean; | ||||||
|  | 	function Is_Blank (V: in Rune) return Boolean; | ||||||
|  | 	function Is_Cntrl (V: in Rune) return Boolean; | ||||||
|  | 	function Is_Digit (V: in Rune) return Boolean; | ||||||
|  | 	function Is_Graph (V: in Rune) return Boolean; | ||||||
|  | 	function Is_Print (V: in Rune) return Boolean; | ||||||
|  | 	function Is_Punct (V: in Rune) return Boolean; | ||||||
|  | 	function Is_Space (V: in Rune) return Boolean; | ||||||
|  | 	function Is_Xdigit (V: in Rune) return Boolean; | ||||||
|  | 	function Is_Lower (V: in Rune) return Boolean; | ||||||
|  | 	function Is_Upper (V: in Rune) return Boolean; | ||||||
|  | 	 | ||||||
|  | 	function To_Lower (V: in Rune) return Rune; | ||||||
|  | 	function To_Upper (V: in Rune) return Rune; | ||||||
|  |  | ||||||
|  | 	function Is_Alpha (C: in Code) return Boolean; | ||||||
|  | 	function Is_Alnum (C: in Code) return Boolean; | ||||||
|  | 	function Is_Blank (C: in Code) return Boolean; | ||||||
|  | 	function Is_Cntrl (C: in Code) return Boolean; | ||||||
|  | 	function Is_Digit (C: in Code) return Boolean; | ||||||
|  | 	function Is_Graph (C: in Code) return Boolean; | ||||||
|  | 	function Is_Print (C: in Code) return Boolean; | ||||||
|  | 	function Is_Punct (C: in Code) return Boolean; | ||||||
|  | 	function Is_Space (C: in Code) return Boolean; | ||||||
|  | 	function Is_Xdigit (C: in Code) return Boolean; | ||||||
|  | 	function Is_Lower (C: in Code) return Boolean; | ||||||
|  | 	function Is_Upper (C: in Code) return Boolean; | ||||||
|  |  | ||||||
|  | 	function Is_Class (V: in Rune; Class: in Item_Class) return Boolean; | ||||||
|  | 	function Is_Class (C: in Code; Class: in Item_Class) return Boolean; | ||||||
|  |  | ||||||
|  | 	function Is_Eof (C: in Code) return Boolean; | ||||||
|  | 	pragma Inline (Is_Eof); | ||||||
|  |  | ||||||
|  | 	function Is_Code (V: in Rune; C: in Code) return Boolean; | ||||||
|  | 	pragma Inline (Is_Code); | ||||||
|  | 	function Is_Rune (C: in Code; V: in Rune) return Boolean; | ||||||
|  | 	pragma Inline (Is_Rune); | ||||||
|  |  | ||||||
|  | 	function To_Rune (C: in Code) return Rune; | ||||||
|  | 	pragma Inline (To_Rune); | ||||||
|  | 	function To_Code (V: in Rune) return Code; | ||||||
|  | 	pragma Inline (To_Code); | ||||||
|  |  | ||||||
| 	function Is_Code (V: in Item_Type; Code: in Item_Code) return Boolean; |  | ||||||
| end H3.CC; | end H3.CC; | ||||||
							
								
								
									
										197
									
								
								lib2/h3-compilers.adb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								lib2/h3-compilers.adb
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,197 @@ | |||||||
|  | with ada.text_io; | ||||||
|  |  | ||||||
|  | package body H3.Compilers is | ||||||
|  | 	procedure Set_Lexer_State (C: in out Compiler; State: in Lexer_State) is | ||||||
|  | 	begin | ||||||
|  | 		C.Lx.State := State; | ||||||
|  | 	end Set_Lexer_State; | ||||||
|  |  | ||||||
|  | 	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; | ||||||
|  | 		S.Clear (C.Tk.Buf); | ||||||
|  | 		S.Append (C.Tk.Buf, Ch); | ||||||
|  | 	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; | ||||||
|  |  | ||||||
|  | 	procedure Got_Token (C: in out Compiler) is | ||||||
|  | 	begin | ||||||
|  | 		--case C.P.State IS | ||||||
|  | 		--	when START => | ||||||
|  | 		--		null; | ||||||
|  | 		--end case; | ||||||
|  |  | ||||||
|  | ada.text_io.put_line (C.Tk.Id'Img); | ||||||
|  | 		case C.Tk.Id is | ||||||
|  | 			when TK_BSTR => | ||||||
|  | 				null; | ||||||
|  | 			when TK_BYTE => | ||||||
|  | 				null; | ||||||
|  | 			when TK_CHAR => | ||||||
|  | 				null; | ||||||
|  | 			when TK_CSTR => | ||||||
|  | 				null; | ||||||
|  | 			when TK_EOF => | ||||||
|  | 				null; | ||||||
|  | 			when TK_EOL => | ||||||
|  | 				null; | ||||||
|  | 			when TK_GE => | ||||||
|  | 				null; | ||||||
|  | 			when TK_GT => | ||||||
|  | 				null; | ||||||
|  | 			when TK_IDENT => | ||||||
|  | 				null; | ||||||
|  | 			when TK_LE => | ||||||
|  | 				null; | ||||||
|  | 			when TK_LT => | ||||||
|  | 				null; | ||||||
|  | 			when TK_SEMICOLON => | ||||||
|  | 				null; | ||||||
|  | 		end case; | ||||||
|  | 	end Got_Token; | ||||||
|  |  | ||||||
|  | 	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; | ||||||
|  |  | ||||||
|  | 	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 | ||||||
|  | 		S.Append (C.Tk.Buf, R.To_Rune(Code)); | ||||||
|  | 		C.Tk.Id := Id; | ||||||
|  | 		Got_Token (C); | ||||||
|  | 		Set_Lexer_State (C, LX_START); | ||||||
|  | 	end End_Token; | ||||||
|  |  | ||||||
|  | 	procedure Feed_Char_Code (C: in out Compiler; Code: in R.Code) is | ||||||
|  | 	begin | ||||||
|  | 	<<Start_Over>> | ||||||
|  | 	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; | ||||||
|  | 		case C.Lx.State is | ||||||
|  | 			when LX_START => | ||||||
|  | 				if R.Is_Eof(Code) then | ||||||
|  | 					Start_Token (C, S.Rune_Array'(R.Left_Arrow, R.UC_E, R.UC_O, R.UC_F, R.Right_Arrow)); | ||||||
|  | 					End_Token (C, TK_EOF); | ||||||
|  | 					-- this procedure doesn't prevent you from feeding more | ||||||
|  | 					-- after EOF. but it's not desirable to feed more after EOF. | ||||||
|  | 				elsif R.Is_Space(Code) then | ||||||
|  | 					-- ignore. carry on | ||||||
|  | 					null; | ||||||
|  | 				elsif R.Is_Alpha(Code) then | ||||||
|  | 					Set_Lexer_State (C, LX_IDENT, Code); | ||||||
|  | 				elsif R.Is_Digit(Code) then | ||||||
|  | 					Set_Lexer_State (C, LX_NUMBER, Code); | ||||||
|  | 				elsif R.Is_Rune(Code, R.Semicolon) then | ||||||
|  | 					Start_Token (C, Code); | ||||||
|  | 					End_Token (C, TK_SEMICOLON); | ||||||
|  | 				elsif R.Is_Rune(Code, R.Left_Arrow) then | ||||||
|  | 					Set_Lexer_State (C, LX_OP_LESS, Code); | ||||||
|  | 				elsif R.Is_Rune(Code, R.Right_Arrow) then | ||||||
|  | 					Set_Lexer_State (C, LX_OP_GREATER, Code); | ||||||
|  | 				else | ||||||
|  | 					raise Syntax_Error; | ||||||
|  | 				end if; | ||||||
|  |  | ||||||
|  | 			when LX_OP_GREATER => | ||||||
|  | 				if R.Is_Rune(Code, R.Equal) 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.Equal) then | ||||||
|  | 					End_Token (C, TK_LE, Code); | ||||||
|  | 				else | ||||||
|  | 					End_Token (C, TK_LT); | ||||||
|  | 					goto Start_Over; | ||||||
|  | 				end if; | ||||||
|  |  | ||||||
|  | 			when LX_COMMENT => | ||||||
|  | 				null; | ||||||
|  |  | ||||||
|  | 			when LX_IDENT => | ||||||
|  | 				if R.Is_Alnum(Code) or else R.Is_Rune(Code, R.Underline) then | ||||||
|  | 					Feed_Token (C, Code); | ||||||
|  | 				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; | ||||||
|  | 		end case; | ||||||
|  | 	end Feed_Char_Code; | ||||||
|  |  | ||||||
|  | 	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))); | ||||||
|  | 		end loop; | ||||||
|  | 	end Feed; | ||||||
|  |  | ||||||
|  | 	procedure End_Feed (C: in out Compiler) is | ||||||
|  | 	begin | ||||||
|  | 		Feed_Char_Code (C, R.EOF); | ||||||
|  | 	end End_Feed; | ||||||
|  |  | ||||||
|  | end H3.Compilers; | ||||||
							
								
								
									
										58
									
								
								lib2/h3-compilers.ads
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								lib2/h3-compilers.ads
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,58 @@ | |||||||
|  | with H3.CC; | ||||||
|  | with H3.Strings; | ||||||
|  |  | ||||||
|  | generic | ||||||
|  | 	type Rune_Type is (<>); | ||||||
|  | package H3.Compilers is | ||||||
|  | 	package R is new H3.CC(Rune_Type); | ||||||
|  | 	package S is new H3.Strings(Rune_Type); | ||||||
|  |  | ||||||
|  | 	Syntax_Error: exception; | ||||||
|  |  | ||||||
|  | 	type Compiler is tagged private; | ||||||
|  |  | ||||||
|  | 	procedure Feed (C: in out Compiler; Data: in S.Rune_Array); | ||||||
|  | 	procedure End_Feed (C: in out Compiler); | ||||||
|  |  | ||||||
|  | private | ||||||
|  | 	type Lexer_State is ( | ||||||
|  | 		LX_START, | ||||||
|  | 		LX_COMMENT, | ||||||
|  | 		LX_IDENT, | ||||||
|  | 		LX_NUMBER, | ||||||
|  | 		LX_OP_GREATER, | ||||||
|  | 		LX_OP_LESS | ||||||
|  | 	); | ||||||
|  | 	type Lexer is record | ||||||
|  | 		State: Lexer_State := LX_START; | ||||||
|  | 	end record; | ||||||
|  |  | ||||||
|  | 	type Token_Id is ( | ||||||
|  | 		TK_BSTR, | ||||||
|  | 		TK_BYTE, | ||||||
|  | 		TK_CHAR, | ||||||
|  | 		TK_CSTR, | ||||||
|  | 		TK_EOF, | ||||||
|  | 		TK_EOL, | ||||||
|  | 		TK_IDENT, | ||||||
|  | 		TK_GE, | ||||||
|  | 		TK_GT, | ||||||
|  | 		TK_LE, | ||||||
|  | 		TK_LT, | ||||||
|  | 		TK_SEMICOLON | ||||||
|  | 	); | ||||||
|  | 	type Token is record | ||||||
|  | 		Id: Token_Id := TK_EOF; | ||||||
|  | 		Buf: S.Elastic_String; | ||||||
|  | 	end record; | ||||||
|  |  | ||||||
|  | 	type Parser_State is (START, INCLUDE); | ||||||
|  | 	type Parser is record | ||||||
|  | 		State: Parser_State := START; | ||||||
|  | 	end record; | ||||||
|  |  | ||||||
|  | 	type Compiler is tagged record | ||||||
|  | 		Lx: Lexer; | ||||||
|  | 		Tk: Token; | ||||||
|  | 	end record; | ||||||
|  | end H3.Compilers; | ||||||
| @ -22,10 +22,10 @@ package H3.MM is | |||||||
| 	procedure Create (R: in out Ref_Counted; V: in Item_Type); | 	procedure Create (R: in out Ref_Counted; V: in Item_Type); | ||||||
|  |  | ||||||
| 	function Get_Item_Pointer (R: in Ref_Counted) return Item_Pointer; | 	function Get_Item_Pointer (R: in Ref_Counted) return Item_Pointer; | ||||||
| 	pragma Inline(Get_Item_Pointer); | 	pragma Inline (Get_Item_Pointer); | ||||||
|  |  | ||||||
| 	function Is_Shared (R: in Ref_Counted) return Boolean; | 	function Is_Shared (R: in Ref_Counted) return Boolean; | ||||||
| 	pragma Inline(Is_Shared); | 	pragma Inline (Is_Shared); | ||||||
|  |  | ||||||
| 	overriding procedure Initialize (R: in out Ref_Counted); | 	overriding procedure Initialize (R: in out Ref_Counted); | ||||||
| 	overriding procedure Adjust (R: in out Ref_Counted); | 	overriding procedure Adjust (R: in out Ref_Counted); | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| package body H3.Strings is | package body H3.Strings is | ||||||
|  |  | ||||||
| 	procedure Append (Obj: in out Elastic_String; V: in Character_Array) is | 	procedure Append (Obj: in out Elastic_String; V: in Rune_Array) is | ||||||
| 	begin | 	begin | ||||||
| 		P.Append (P.Elastic_Array(Obj), V); | 		P.Append (P.Elastic_Array(Obj), V); | ||||||
| 	end; | 	end; | ||||||
|  | |||||||
| @ -1,22 +1,23 @@ | |||||||
| with H3.Arrays; | with H3.Arrays; | ||||||
|  |  | ||||||
| generic | generic | ||||||
| 	type Item_Type is (<>); | 	type Rune_Type is (<>); | ||||||
| package H3.Strings is | package H3.Strings is | ||||||
|  |  | ||||||
| 	package P is new H3.Arrays(Item_Type, 1, Item_Type'First); | 	package P is new H3.Arrays(Rune_Type, 1, Rune_Type'First); | ||||||
|  |  | ||||||
|  | 	subtype Rune is P.Item; | ||||||
|  | 	subtype Rune_Array is P.Item_Array; | ||||||
|  | 	subtype Thin_Rune_Array_Pointer is P.Thin_Item_Array_Pointer; | ||||||
|  |  | ||||||
| 	Terminator_Length: System_Zero_Or_One renames P.Terminator_Length; | 	Terminator_Length: System_Zero_Or_One renames P.Terminator_Length; | ||||||
| 	Terminator_Value: Item_Type renames P.Terminator_Value; | 	Terminator_Value: Rune renames P.Terminator_Value; | ||||||
|  |  | ||||||
| 	subtype Character_Array is P.Item_Array; |  | ||||||
| 	subtype Thin_Character_Array_Pointer is P.Thin_Item_Array_Pointer; |  | ||||||
|  |  | ||||||
| 	type Elastic_String is new P.Elastic_Array with record | 	type Elastic_String is new P.Elastic_Array with record | ||||||
| 		--A: standard.integer := 999; | 		--A: standard.integer := 999; | ||||||
| 		null; | 		null; | ||||||
| 	end record; | 	end record; | ||||||
|  |  | ||||||
| 	overriding procedure Append (Obj: in out Elastic_String; V: in Character_Array); | 	overriding procedure Append (Obj: in out Elastic_String; V: in Rune_Array); | ||||||
|  |  | ||||||
| end H3.Strings; | end H3.Strings; | ||||||
|  | |||||||
| @ -6,7 +6,7 @@ package H3 is | |||||||
| 	subtype Boolean is Standard.Boolean; | 	subtype Boolean is Standard.Boolean; | ||||||
| 	subtype Natural is Standard.Natural; | 	subtype Natural is Standard.Natural; | ||||||
|  |  | ||||||
| 	subtype System_Character is Standard.Wide_Character; | 	subtype System_Rune is Standard.Wide_Character; | ||||||
|  |  | ||||||
| 	System_Byte_Bits: constant := System.Storage_Unit; | 	System_Byte_Bits: constant := System.Storage_Unit; | ||||||
| 	System_Word_Bits: constant := System.Word_Size; | 	System_Word_Bits: constant := System.Word_Size; | ||||||
|  | |||||||
							
								
								
									
										10
									
								
								lib2/hello3.adb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								lib2/hello3.adb
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | |||||||
|  | with H3.Compilers; | ||||||
|  |  | ||||||
|  | procedure hello3 is | ||||||
|  | 	package C is new H3.Compilers(Standard.Wide_Character); | ||||||
|  |  | ||||||
|  | 	Compiler: C.Compiler; | ||||||
|  | begin | ||||||
|  | 	Compiler.Feed ("<<=hello world"); | ||||||
|  | 	Compiler.End_Feed; | ||||||
|  | end hello3; | ||||||
		Reference in New Issue
	
	Block a user