| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | with H2.Pool; | 
					
						
							| 
									
										
										
										
											2014-01-01 14:07:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | -- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx
 | 
					
						
							|  |  |  | -- TODO: delete these after debugging
 | 
					
						
							| 
									
										
										
										
											2014-01-14 14:22:06 +00:00
										 |  |  | with Ada.Unchecked_Deallocation; -- for h2scm c interface. TOOD: move it to a separate file
 | 
					
						
							|  |  |  | with Interfaces.C; | 
					
						
							| 
									
										
										
										
											2014-01-01 14:07:03 +00:00
										 |  |  | with ada.text_io; | 
					
						
							|  |  |  | with ada.wide_text_io; | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | with ada.exceptions; | 
					
						
							| 
									
										
										
										
											2014-01-01 14:07:03 +00:00
										 |  |  | -- TODO: delete above after debugging
 | 
					
						
							|  |  |  | -- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | package body H2.Scheme is | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-20 14:51:53 +00:00
										 |  |  | 	package body Bigint is separate; | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | 	package body Token is separate; | 
					
						
							| 
									
										
										
										
											2014-03-05 18:06:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 	DEBUG_GC: Standard.Boolean := Standard.False; | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 	-- PRIMITIVE DEFINITIONS
 | 
					
						
							|  |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-14 15:47:10 +00:00
										 |  |  | 	type Procedure_Code is ( | 
					
						
							|  |  |  | 		Callcc_Procedure, | 
					
						
							|  |  |  | 		Car_Procedure, | 
					
						
							|  |  |  | 		Cdr_Procedure, | 
					
						
							|  |  |  | 		Cons_Procedure, | 
					
						
							|  |  |  | 		Not_Procedure, | 
					
						
							| 
									
										
										
										
											2014-02-15 03:41:37 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		N_Add_Procedure, | 
					
						
							| 
									
										
										
										
											2014-02-14 15:47:10 +00:00
										 |  |  | 		N_EQ_Procedure, | 
					
						
							|  |  |  | 		N_GT_Procedure, | 
					
						
							|  |  |  | 		N_LT_Procedure, | 
					
						
							|  |  |  | 		N_GE_Procedure, | 
					
						
							|  |  |  | 		N_LE_Procedure, | 
					
						
							|  |  |  | 		N_Multiply_Procedure, | 
					
						
							|  |  |  | 		N_Quotient_Procedure, | 
					
						
							|  |  |  | 		N_Remainder_Procedure, | 
					
						
							|  |  |  | 		N_Subtract_Procedure, | 
					
						
							| 
									
										
										
										
											2014-02-15 03:41:37 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		Q_Boolean_Procedure, | 
					
						
							| 
									
										
										
										
											2014-02-14 15:47:10 +00:00
										 |  |  | 		Q_Eq_Procedure, | 
					
						
							|  |  |  | 		Q_Eqv_Procedure, | 
					
						
							|  |  |  | 		Q_Null_Procedure, | 
					
						
							|  |  |  | 		Q_Number_Procedure, | 
					
						
							| 
									
										
										
										
											2014-02-16 15:02:04 +00:00
										 |  |  | 		Q_Pair_Procedure, | 
					
						
							| 
									
										
										
										
											2014-02-14 15:47:10 +00:00
										 |  |  | 		Q_Procedure_Procedure, | 
					
						
							|  |  |  | 		Q_String_Procedure, | 
					
						
							| 
									
										
										
										
											2014-02-16 15:02:04 +00:00
										 |  |  | 		Q_String_EQ_Procedure, | 
					
						
							| 
									
										
										
										
											2014-02-14 15:47:10 +00:00
										 |  |  | 		Q_Symbol_Procedure, | 
					
						
							| 
									
										
										
										
											2014-02-15 03:41:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-14 15:47:10 +00:00
										 |  |  | 		Setcar_Procedure, | 
					
						
							|  |  |  | 		Setcdr_Procedure | 
					
						
							|  |  |  | 	); | 
					
						
							|  |  |  | 	for Procedure_Code'Size use Object_Integer'Size; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | 	-- I define these constants to word around the limitation of not being
 | 
					
						
							|  |  |  | 	-- able to use a string literal when the string type is a generic parameter.
 | 
					
						
							|  |  |  | 	-- Why doesn't ada include a formal type support for different character
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 	-- and string types? This limitation is caused because the generic
 | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | 	-- type I chosed to use to represent a character type is a discrete type.
 | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 	Label_And:        constant Object_Character_Array := (Ch_Val.LC_A, Ch_Val.LC_N, Ch_Val.LC_D); -- "and"
 | 
					
						
							|  |  |  | 	Label_Begin:      constant Object_Character_Array := (Ch_Val.LC_B, Ch_Val.LC_E, Ch_Val.LC_G, Ch_Val.LC_I, Ch_Val.LC_N); -- "begin"
 | 
					
						
							|  |  |  | 	Label_Case:       constant Object_Character_Array := (Ch_Val.LC_C, Ch_Val.LC_A, Ch_Val.LC_S, Ch_Val.LC_E); -- "case"
 | 
					
						
							|  |  |  | 	Label_Cond:       constant Object_Character_Array := (Ch_Val.LC_C, Ch_Val.LC_O, Ch_Val.LC_N, Ch_Val.LC_D); -- "cond"
 | 
					
						
							|  |  |  | 	Label_Define:     constant Object_Character_Array := (Ch_Val.LC_D, Ch_Val.LC_E, Ch_Val.LC_F, Ch_Val.LC_I, Ch_Val.LC_N, Ch_Val.LC_E); -- "define"
 | 
					
						
							|  |  |  | 	Label_Do:         constant Object_Character_Array := (Ch_Val.LC_D, Ch_Val.LC_O); -- "do"
 | 
					
						
							|  |  |  | 	Label_If:         constant Object_Character_Array := (Ch_Val.LC_I, Ch_Val.LC_F); -- "if"
 | 
					
						
							|  |  |  | 	Label_Lambda:     constant Object_Character_Array := (Ch_Val.LC_L, Ch_Val.LC_A, Ch_Val.LC_M, Ch_Val.LC_B, Ch_Val.LC_D, Ch_Val.LC_A); -- "lambda"
 | 
					
						
							|  |  |  | 	Label_Let:        constant Object_Character_Array := (Ch_Val.LC_L, Ch_Val.LC_E, Ch_Val.LC_T); -- "let"
 | 
					
						
							|  |  |  | 	Label_Letast:     constant Object_Character_Array := (Ch_Val.LC_L, Ch_Val.LC_E, Ch_Val.LC_T, Ch_Val.Asterisk); -- "let*"
 | 
					
						
							|  |  |  | 	Label_Letrec:     constant Object_Character_Array := (Ch_Val.LC_L, Ch_Val.LC_E, Ch_Val.LC_T, Ch_Val.LC_R, Ch_Val.LC_E, Ch_Val.LC_C); -- "letrec"
 | 
					
						
							|  |  |  | 	Label_Or:         constant Object_Character_Array := (Ch_Val.LC_O, Ch_Val.LC_R); -- "or"
 | 
					
						
							|  |  |  | 	Label_Quasiquote: constant Object_Character_Array := (Ch_Val.LC_Q, Ch_Val.LC_U, Ch_Val.LC_A, Ch_Val.LC_S, Ch_Val.LC_I, | 
					
						
							|  |  |  | 	                                                      Ch_Val.LC_Q, Ch_Val.LC_U, Ch_Val.LC_O, Ch_Val.LC_T, Ch_Val.LC_E); -- "quasiquote"
 | 
					
						
							|  |  |  | 	Label_Quote:      constant Object_Character_Array := (Ch_Val.LC_Q, Ch_Val.LC_U, Ch_Val.LC_O, Ch_Val.LC_T, Ch_Val.LC_E); -- "quote"
 | 
					
						
							|  |  |  | 	Label_Set:        constant Object_Character_Array := (Ch_Val.LC_S, Ch_Val.LC_E, Ch_Val.LC_T, Ch_Val.Exclamation); -- "set!"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Label_Callcc:     constant Object_Character_Array := (Ch_Val.LC_C, Ch_Val.LC_A, Ch_Val.LC_L, Ch_Val.LC_L, Ch_Val.Minus_Sign, | 
					
						
							|  |  |  | 	                                                      Ch_Val.LC_W, Ch_Val.LC_I, Ch_Val.LC_T, Ch_Val.LC_H, Ch_Val.Minus_Sign, | 
					
						
							|  |  |  | 	                                                      Ch_Val.LC_C, Ch_Val.LC_U, Ch_Val.LC_R, Ch_Val.LC_R, Ch_Val.LC_E, Ch_Val.LC_N, Ch_Val.LC_T, Ch_Val.Minus_Sign, | 
					
						
							|  |  |  | 	                                                      Ch_Val.LC_C, Ch_Val.LC_O, Ch_Val.LC_N, Ch_Val.LC_T, Ch_Val.LC_I, Ch_Val.LC_N, Ch_Val.LC_U, Ch_Val.LC_A, | 
					
						
							|  |  |  | 	                                                      Ch_Val.LC_T, Ch_Val.LC_I, Ch_Val.LC_O, Ch_Val.LC_N);  -- "call-with-current-continuation"
 | 
					
						
							|  |  |  | 	Label_Car:        constant Object_Character_Array := (Ch_Val.LC_C, Ch_Val.LC_A, Ch_Val.LC_R); -- "car"
 | 
					
						
							|  |  |  | 	Label_Cdr:        constant Object_Character_Array := (Ch_Val.LC_C, Ch_Val.LC_D, Ch_Val.LC_R); -- "cdr"
 | 
					
						
							|  |  |  | 	Label_Cons:       constant Object_Character_Array := (Ch_Val.LC_C, Ch_Val.LC_O, Ch_Val.LC_N, Ch_Val.LC_S); -- "cons"
 | 
					
						
							|  |  |  | 	Label_Not:        constant Object_Character_Array := (Ch_Val.LC_N, Ch_Val.LC_O, Ch_Val.LC_T); -- "not"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Label_N_Add:       constant Object_Character_Array := (1 => Ch_Val.Plus_Sign); -- "+"
 | 
					
						
							|  |  |  | 	Label_N_EQ:        constant Object_Character_Array := (1 => Ch_Val.Equal_Sign); -- "="
 | 
					
						
							|  |  |  | 	Label_N_GE:        constant Object_Character_Array := (Ch_Val.Greater_Than_Sign, Ch_Val.Equal_Sign); -- ">="
 | 
					
						
							|  |  |  | 	Label_N_GT:        constant Object_Character_Array := (1 => Ch_Val.Greater_Than_Sign); -- ">"
 | 
					
						
							|  |  |  | 	Label_N_LE:        constant Object_Character_Array := (Ch_Val.Less_Than_Sign, Ch_Val.Equal_Sign); -- "<="
 | 
					
						
							|  |  |  | 	Label_N_LT:        constant Object_Character_Array := (1 => Ch_Val.Less_Than_Sign); -- "<"
 | 
					
						
							|  |  |  | 	Label_N_Multiply:  constant Object_Character_Array := (1 => Ch_Val.Asterisk); -- "*"
 | 
					
						
							|  |  |  | 	Label_N_Quotient:  constant Object_Character_Array := (Ch_Val.LC_Q, Ch_Val.LC_U, Ch_Val.LC_O, Ch_Val.LC_T, Ch_Val.LC_I, Ch_Val.LC_E, Ch_Val.LC_N, Ch_Val.LC_T); -- "quotient"
 | 
					
						
							|  |  |  | 	Label_N_Remainder: constant Object_Character_Array := (Ch_Val.LC_R, Ch_Val.LC_E, Ch_Val.LC_M, Ch_Val.LC_A, Ch_Val.LC_I, Ch_Val.LC_N, Ch_Val.LC_D, Ch_Val.LC_E, Ch_Val.LC_R); -- "remainder"
 | 
					
						
							|  |  |  | 	Label_N_Subtract:  constant Object_Character_Array := (1 => Ch_Val.Minus_Sign); -- "-"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Label_Q_Boolean:   constant Object_Character_Array := (Ch_Val.LC_B, Ch_Val.LC_O, Ch_Val.LC_O, Ch_Val.LC_L, Ch_Val.LC_E, Ch_Val.LC_A, Ch_Val.LC_N, Ch_Val.Question); -- "boolean?"
 | 
					
						
							|  |  |  | 	Label_Q_Eq:        constant Object_Character_Array := (Ch_Val.LC_E, Ch_Val.LC_Q, Ch_Val.Question); -- "eq?"
 | 
					
						
							|  |  |  | 	Label_Q_Eqv:       constant Object_Character_Array := (Ch_Val.LC_E, Ch_Val.LC_Q, Ch_Val.LC_V, Ch_Val.Question); -- "eqv?"
 | 
					
						
							|  |  |  | 	Label_Q_Null:      constant Object_Character_Array := (Ch_Val.LC_N, Ch_Val.LC_U, Ch_Val.LC_L, Ch_Val.LC_L, Ch_Val.Question); -- "null?"
 | 
					
						
							|  |  |  | 	Label_Q_Number:    constant Object_Character_Array := (Ch_Val.LC_N, Ch_Val.LC_U, Ch_Val.LC_M, Ch_Val.LC_B, Ch_Val.LC_E, Ch_Val.LC_R, Ch_Val.Question); -- "number?"
 | 
					
						
							|  |  |  | 	Label_Q_Pair:      constant Object_Character_Array := (Ch_Val.LC_P, Ch_Val.LC_A, Ch_Val.LC_I, Ch_Val.LC_R, Ch_Val.Question); -- "pair?"
 | 
					
						
							|  |  |  | 	Label_Q_Procedure: constant Object_Character_Array := (Ch_Val.LC_P, Ch_Val.LC_R, Ch_Val.LC_O, Ch_Val.LC_C, Ch_Val.LC_E, Ch_Val.LC_D, Ch_Val.LC_U, Ch_Val.LC_R, Ch_Val.LC_E, Ch_Val.Question); -- "procedure?"
 | 
					
						
							|  |  |  | 	Label_Q_String:    constant Object_Character_Array := (Ch_Val.LC_S, Ch_Val.LC_T, Ch_Val.LC_R, Ch_Val.LC_I, Ch_Val.LC_N, Ch_Val.LC_G, Ch_Val.Question); -- "string?"
 | 
					
						
							|  |  |  | 	Label_Q_String_EQ: constant Object_Character_Array := (Ch_Val.LC_S, Ch_Val.LC_T, Ch_Val.LC_R, Ch_Val.LC_I, Ch_Val.LC_N, Ch_Val.LC_G, Ch_Val.Equal_Sign, Ch_Val.Question); -- "string=?"
 | 
					
						
							|  |  |  | 	Label_Q_Symbol:    constant Object_Character_Array := (Ch_Val.LC_S, Ch_Val.LC_Y, Ch_Val.LC_M, Ch_Val.LC_B, Ch_Val.LC_O, Ch_Val.LC_L, Ch_Val.Question); -- "symbol?"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Label_Setcar:      constant Object_Character_Array := (Ch_Val.LC_S, Ch_Val.LC_E, Ch_Val.LC_T, Ch_Val.Minus_Sign, Ch_Val.LC_C, Ch_Val.LC_A, Ch_Val.LC_R, Ch_Val.Exclamation); -- "set-car!"
 | 
					
						
							|  |  |  | 	Label_Setcdr:      constant Object_Character_Array := (Ch_Val.LC_S, Ch_Val.LC_E, Ch_Val.LC_T, Ch_Val.Minus_Sign, Ch_Val.LC_C, Ch_Val.LC_D, Ch_Val.LC_R, Ch_Val.Exclamation); -- "set-cdr!"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Label_Newline:    constant Object_Character_Array := (Ch_Val.LC_N, Ch_Val.LC_E, Ch_Val.LC_W, Ch_Val.LC_L, Ch_Val.LC_I, Ch_Val.LC_N, Ch_Val.LC_E); -- "newline"
 | 
					
						
							|  |  |  | 	Label_Space:      constant Object_Character_Array := (Ch_Val.LC_S, Ch_Val.LC_P, Ch_Val.LC_A, Ch_Val.LC_C, Ch_Val.LC_E); -- "space"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Label_Arrow:      constant Object_Character_Array := (Ch_Val.Equal_Sign, Ch_Val.Greater_Than_Sign); -- "=>"
 | 
					
						
							|  |  |  | 	Label_Else:       constant Object_Character_Array := (Ch_Val.LC_E, Ch_Val.LC_L, Ch_Val.LC_S, Ch_Val.LC_E); -- "else"
 | 
					
						
							| 
									
										
										
										
											2014-02-15 03:41:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2014-03-03 15:36:03 +00:00
										 |  |  | 	-- INTERNAL EXCEPTIONS
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2014-01-07 17:02:12 +00:00
										 |  |  | 	Stream_End_Error: exception; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	-- INTERNALLY-USED TYPES
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 	type Heap_Element_Pointer is access all Heap_Element; | 
					
						
							| 
									
										
										
										
											2014-01-24 07:58:46 +00:00
										 |  |  | 	for Heap_Element_Pointer'Size use Object_Pointer_Bits; -- ensure that it can be overlaid by an ObjectPointer
 | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 	type Thin_Heap_Element_Array is array (1 .. Heap_Size'Last) of Heap_Element; | 
					
						
							|  |  |  | 	type Thin_Heap_Element_Array_Pointer is access all Thin_Heap_Element_Array; | 
					
						
							|  |  |  | 	for Thin_Heap_Element_Array_Pointer'Size use Object_Pointer_Bits; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 	subtype Moved_Object_Record is Object_Record (Moved_Object, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-29 02:30:50 +00:00
										 |  |  | 	type Opcode_Type is ( | 
					
						
							|  |  |  | 		Opcode_Exit, | 
					
						
							|  |  |  | 		Opcode_Evaluate_Result, | 
					
						
							|  |  |  | 		Opcode_Evaluate_Object, | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-08 03:53:53 +00:00
										 |  |  | 		Opcode_And_Finish, | 
					
						
							|  |  |  | 		Opcode_Or_Finish, | 
					
						
							| 
									
										
										
										
											2014-02-14 15:47:10 +00:00
										 |  |  | 		Opcode_Case_Finish, | 
					
						
							| 
									
										
										
										
											2014-02-10 15:39:20 +00:00
										 |  |  | 		Opcode_Cond_Finish, | 
					
						
							| 
									
										
										
										
											2014-02-07 16:25:38 +00:00
										 |  |  | 		Opcode_Define_Finish, | 
					
						
							| 
									
										
										
										
											2014-02-17 15:11:00 +00:00
										 |  |  | 		Opcode_Do_Binding, | 
					
						
							|  |  |  | 		Opcode_Do_Break, | 
					
						
							|  |  |  | 		Opcode_Do_Step, | 
					
						
							|  |  |  | 		Opcode_Do_Test, | 
					
						
							|  |  |  | 		Opcode_Do_Update, | 
					
						
							| 
									
										
										
										
											2014-01-29 02:30:50 +00:00
										 |  |  | 		Opcode_Grouped_Call,  -- (begin ...), closure apply, let body
 | 
					
						
							| 
									
										
										
										
											2014-02-07 16:25:38 +00:00
										 |  |  | 		Opcode_If_Finish, | 
					
						
							| 
									
										
										
										
											2014-01-29 02:30:50 +00:00
										 |  |  | 		Opcode_Let_Binding, | 
					
						
							|  |  |  | 		Opcode_Letast_Binding, | 
					
						
							| 
									
										
										
										
											2014-02-09 15:28:46 +00:00
										 |  |  | 		Opcode_Letrec_Binding, | 
					
						
							| 
									
										
										
										
											2014-01-29 02:30:50 +00:00
										 |  |  | 		Opcode_Procedure_Call, | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 		Opcode_Procedure_Call_Finish, | 
					
						
							| 
									
										
										
										
											2014-01-29 02:30:50 +00:00
										 |  |  | 		Opcode_Set_Finish, | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-29 02:30:50 +00:00
										 |  |  | 		Opcode_Apply, | 
					
						
							|  |  |  | 		Opcode_Read_Object, | 
					
						
							|  |  |  | 		Opcode_Read_List, | 
					
						
							|  |  |  | 		Opcode_Read_List_Cdr, | 
					
						
							|  |  |  | 		Opcode_Read_List_End, | 
					
						
							|  |  |  | 		Opcode_Close_List, | 
					
						
							| 
									
										
										
										
											2014-02-06 03:28:14 +00:00
										 |  |  | 		Opcode_Close_Quote, | 
					
						
							|  |  |  | 		Opcode_Close_Quote_In_List | 
					
						
							| 
									
										
										
										
											2014-01-29 02:30:50 +00:00
										 |  |  | 	); | 
					
						
							|  |  |  | 	for Opcode_Type'Size use Object_Integer'Size; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	-- COMMON OBJECTS
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	Cons_Object_Size: constant Pointer_Object_Size := 2; | 
					
						
							|  |  |  | 	Cons_Car_Index: constant Pointer_Object_Size := 1; | 
					
						
							|  |  |  | 	Cons_Cdr_Index: constant Pointer_Object_Size := 2; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 	Frame_Object_Size: constant Pointer_Object_Size := 6; | 
					
						
							| 
									
										
										
										
											2014-01-26 14:58:02 +00:00
										 |  |  | 	Frame_Parent_Index: constant Pointer_Object_Size := 1; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	Frame_Opcode_Index: constant Pointer_Object_Size := 2; | 
					
						
							|  |  |  | 	Frame_Operand_Index: constant Pointer_Object_Size := 3; | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 	Frame_Environment_Index: constant Pointer_Object_Size := 4; | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 	Frame_Intermediate_Index: constant Pointer_Object_Size := 5; | 
					
						
							|  |  |  | 	Frame_Result_Index: constant Pointer_Object_Size := 6; | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Procedure_Object_Size: constant Pointer_Object_Size := 1; | 
					
						
							|  |  |  | 	Procedure_Opcode_Index: constant Pointer_Object_Size := 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Closure_Object_Size: constant Pointer_Object_Size := 2; | 
					
						
							|  |  |  | 	Closure_Code_Index: constant Pointer_Object_Size := 1; | 
					
						
							|  |  |  | 	Closure_Environment_Index: constant Pointer_Object_Size := 2; | 
					
						
							| 
									
										
										
										
											2014-02-01 15:59:36 +00:00
										 |  |  | 	Continuation_Object_Size: constant Pointer_Object_Size := 1; | 
					
						
							| 
									
										
										
										
											2014-01-26 16:15:28 +00:00
										 |  |  | 	Continuation_Frame_Index: constant Pointer_Object_Size := 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 	procedure Set_New_Location (Object: in Object_Pointer; | 
					
						
							|  |  |  | 	                            Ptr:    in Heap_Element_Pointer); | 
					
						
							|  |  |  | 	procedure Set_New_Location (Object: in Object_Pointer; | 
					
						
							|  |  |  | 	                            Ptr:    in Object_Pointer); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	pragma Inline (Set_New_Location); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Get_New_Location (Object: in Object_Pointer) return Object_Pointer; | 
					
						
							|  |  |  | 	pragma Inline (Get_New_Location); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-10 14:54:46 +00:00
										 |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 	-- FOR DEBUGGING. REMVOE THESE LATER
 | 
					
						
							|  |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 	procedure Output_Character_Array (Source: in Object_Character_Array) is | 
					
						
							|  |  |  | 		-- for debugging only.
 | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		for I in Source'Range loop | 
					
						
							|  |  |  | 			--Ada.Text_IO.Put (Source(I));
 | 
					
						
							|  |  |  | -- TODO: note this is a hack for quick printing.
 | 
					
						
							|  |  |  | 			Ada.Text_IO.Put (Standard.Character'Val(Object_Character'Pos(Source(I)))); | 
					
						
							|  |  |  | 		end loop; | 
					
						
							|  |  |  | 	end Output_Character_Array; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	-- POINTER AND DATA CONVERSION
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	function Get_Pointer_Type (Pointer: in Object_Pointer) return Object_Pointer_Type is | 
					
						
							|  |  |  | 		pragma Inline (Get_Pointer_Type); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Word: Object_Word; | 
					
						
							|  |  |  | 		for Word'Address use Pointer'Address; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		return Object_Pointer_Type(Word and Object_Word(Object_Pointer_Type_Mask)); | 
					
						
							|  |  |  | 	end Get_Pointer_Type; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Is_Pointer (Pointer: in Object_Pointer) return Standard.Boolean is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		return Get_Pointer_Type(Pointer) = Object_Pointer_Type_Pointer; | 
					
						
							|  |  |  | 	end Is_Pointer; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Is_Special_Pointer (Pointer: in Object_Pointer) return Standard.Boolean is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		-- though sepcial, these 3 pointers gets true for Is_Pointer.
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		return Pointer = Nil_Pointer or else | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		       Pointer = True_Pointer or else | 
					
						
							|  |  |  | 		       Pointer = False_Pointer; | 
					
						
							|  |  |  | 	end Is_Special_Pointer; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Is_Normal_Pointer (Pointer: in Object_Pointer) return Standard.Boolean is | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		return Is_Pointer(Pointer) and then | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	            not Is_Special_Pointer(Pointer); | 
					
						
							|  |  |  | 	end Is_Normal_Pointer; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Is_Integer (Pointer: in Object_Pointer) return Standard.Boolean is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		return Get_Pointer_Type(Pointer) = Object_Pointer_Type_Integer; | 
					
						
							|  |  |  | 	end Is_Integer; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Is_Character (Pointer: in Object_Pointer) return Standard.Boolean is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		return Get_Pointer_Type(Pointer) = Object_Pointer_Type_Character; | 
					
						
							|  |  |  | 	end Is_Character; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Is_Byte (Pointer: in Object_Pointer) return Standard.Boolean is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		return Get_Pointer_Type(Pointer) = Object_Pointer_Type_Byte; | 
					
						
							|  |  |  | 	end Is_Byte; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-24 15:17:57 +00:00
										 |  |  | 	function Integer_To_Pointer (Value: in Object_Integer) return Object_Pointer is | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		Pointer: Object_Pointer; | 
					
						
							|  |  |  | 		Word: Object_Word; | 
					
						
							|  |  |  | 		for Word'Address use Pointer'Address; | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-02-24 15:17:57 +00:00
										 |  |  | 		if Value < 0 then | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 			-- change the sign of a negative number.
 | 
					
						
							|  |  |  | 			-- '-Int' may violate the range of Object_Integer
 | 
					
						
							|  |  |  | 			-- if it is Object_Integer'First. So I add 1 to 'Int'
 | 
					
						
							|  |  |  | 			-- first to make it fall between Object_Integer'First + 1
 | 
					
						
							|  |  |  | 			-- .. 0 and typecast it with an extra increment.
 | 
					
						
							|  |  |  | 			--Word := Object_Word (-(Int + 1)) + 1;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			-- Let me use Object_Signed_Word instead of the trick shown above
 | 
					
						
							| 
									
										
										
										
											2014-02-24 15:17:57 +00:00
										 |  |  | 			Word := Object_Word(-Object_Signed_Word(Value)); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			-- shift the number to the left by 2 and
 | 
					
						
							|  |  |  | 			-- set the highest bit on by force.
 | 
					
						
							|  |  |  | 			Word := (Word * (2 ** Object_Pointer_Type_Bits)) or Object_Word(Object_Pointer_Type_Integer) or (2 ** (Word'Size - 1)); | 
					
						
							|  |  |  | 		else | 
					
						
							| 
									
										
										
										
											2014-02-24 15:17:57 +00:00
										 |  |  | 			Word := Object_Word(Value); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 			-- Shift 'Word' to the left by 2 and set the integer mark.
 | 
					
						
							|  |  |  | 			Word := (Word * (2 ** Object_Pointer_Type_Bits)) or Object_Word(Object_Pointer_Type_Integer); | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return Pointer; | 
					
						
							|  |  |  | 	end Integer_To_Pointer; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-24 15:17:57 +00:00
										 |  |  | 	function Character_To_Pointer (Value: in Object_Character) return Object_Pointer is | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		Pointer: Object_Pointer; | 
					
						
							|  |  |  | 		Word: Object_Word; | 
					
						
							|  |  |  | 		for Word'Address use Pointer'Address; | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		-- Note: Object_Character may get defined to Wide_Wide_Character.
 | 
					
						
							|  |  |  | 		--   and Wide_Wide_Character'Last is #16#7FFFFFFF#. Such a large value
 | 
					
						
							|  |  |  | 		--   may get lost when it's shifted left by 2 if Object_Word is 32 bits long
 | 
					
						
							|  |  |  | 		--   or short. In reality, the last Unicode code point assigned is far
 | 
					
						
							|  |  |  | 		--   less than #16#7FFFFFFF# as of this writing. So I should not be
 | 
					
						
							|  |  |  | 		--   worried about it for the time being.
 | 
					
						
							| 
									
										
										
										
											2014-02-24 15:17:57 +00:00
										 |  |  | 		Word := Object_Character'Pos(Value); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		Word := (Word * (2 ** Object_Pointer_Type_Bits)) or Object_Word(Object_Pointer_Type_Character); | 
					
						
							|  |  |  | 		return Pointer; | 
					
						
							|  |  |  | 	end Character_To_Pointer; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-24 15:17:57 +00:00
										 |  |  | 	function Byte_To_Pointer (Value: in Object_Byte) return Object_Pointer is | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		Pointer: Object_Pointer; | 
					
						
							|  |  |  | 		Word: Object_Word; | 
					
						
							|  |  |  | 		for Word'Address use Pointer'Address; | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-02-24 15:17:57 +00:00
										 |  |  | 		Word := Object_Word(Value); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		Word := (Word * (2 ** Object_Pointer_Type_Bits)) or Object_Word(Object_Pointer_Type_Byte); | 
					
						
							|  |  |  | 		return Pointer; | 
					
						
							|  |  |  | 	end Byte_To_Pointer; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Pointer_To_Word is new Ada.Unchecked_Conversion (Object_Pointer, Object_Word); | 
					
						
							|  |  |  | 	--function Pointer_To_Word (Pointer: in Object_Pointer) return Object_Word is
 | 
					
						
							| 
									
										
										
										
											2014-01-29 02:30:50 +00:00
										 |  |  | 	--	pragma Inline (Pointer_To_Word);
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	--	Word: Object_Word;
 | 
					
						
							|  |  |  | 	--	for Word'Address use Pointer'Address;
 | 
					
						
							|  |  |  | 	--begin
 | 
					
						
							|  |  |  | 	--	return Word;
 | 
					
						
							|  |  |  | 	--end Pointer_To_Word;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Pointer_To_Integer (Pointer: in Object_Pointer) return Object_Integer is | 
					
						
							| 
									
										
										
										
											2014-02-24 15:17:57 +00:00
										 |  |  | 		Word: Object_Word := Pointer_To_Word(Pointer); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	begin | 
					
						
							|  |  |  | 		if (Word and (2 ** (Word'Size - 1))) /= 0 then | 
					
						
							|  |  |  | 			-- if the highest bit is set, it's a negative number
 | 
					
						
							|  |  |  | 			-- originally. strip it off and shift 'Word' to the right by 2.
 | 
					
						
							|  |  |  | 			return Object_Integer (-Object_Signed_Word (Word and not (2 ** (Word'Size - 1))) / (2 ** Object_Pointer_Type_Bits)); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			-- shift Word to the right by Object_Pointer_Type_Bits.
 | 
					
						
							|  |  |  | 			return Object_Integer (Word / (2 ** Object_Pointer_Type_Bits)); | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 	end Pointer_To_Integer; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Pointer_To_Character (Pointer: in Object_Pointer) return Object_Character is | 
					
						
							|  |  |  | 		Word: Object_Word := Pointer_To_Word (Pointer); | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-01-01 14:07:03 +00:00
										 |  |  | 		return Object_Character'Val(Word / (2 ** Object_Pointer_Type_Bits)); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	end Pointer_To_Character; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Pointer_To_Byte (Pointer: in Object_Pointer) return Object_Byte is | 
					
						
							|  |  |  | 		Word: Object_Word := Pointer_To_Word (Pointer); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		return Object_Byte(Word / (2 ** Object_Pointer_Type_Bits)); | 
					
						
							|  |  |  | 	end Pointer_To_Byte; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 	-- TODO: delete this procedure
 | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | 	procedure Print_Object_Pointer (Msg: in Standard.String; Source: in Object_Pointer) is | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		W: Object_Word; | 
					
						
							|  |  |  | 		for W'Address use Source'Address; | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		Ptr_Type: Object_Pointer_Type; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 		Ptr_Type := Get_Pointer_Type(Source); | 
					
						
							|  |  |  | 		if Ptr_Type = Object_Pointer_Type_Character then | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | 			Ada.Text_IO.Put_Line (Msg & Object_Character'Image(Pointer_To_Character(Source))); | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 		elsif Ptr_Type = Object_Pointer_Type_Integer then | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | 			Ada.Text_IO.Put_Line (Msg & Object_Integer'Image(Pointer_To_Integer(Source))); | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 		elsif Is_Special_Pointer(Source) then | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | 			Ada.Text_IO.Put_Line (Msg & " at " & Object_Word'Image(W)); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		elsif Source.Kind = Character_Object then | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 			Ada.Text_IO.Put (Msg & " at " & Object_Word'Image(W) & | 
					
						
							|  |  |  | 			                   " at " & Object_Kind'Image(Source.Kind) & | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | 			                   " size " & Object_Size'Image(Source.Size) & " - "); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 			if Source.Kind = Moved_Object then | 
					
						
							| 
									
										
										
										
											2014-01-10 14:54:46 +00:00
										 |  |  | 				Output_Character_Array (Get_New_Location(Source).Character_Slot); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 			else | 
					
						
							| 
									
										
										
										
											2014-01-10 14:54:46 +00:00
										 |  |  | 				Output_Character_Array (Source.Character_Slot); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 			end if; | 
					
						
							|  |  |  | 		else | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 			Ada.Text_IO.Put_Line (Msg & " at " & Object_Word'Image(W) & | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | 			                            " kind: " & Object_Kind'Image(Source.Kind) & | 
					
						
							|  |  |  | 			                            " size: " & Object_Size'Image(Source.Size) & | 
					
						
							|  |  |  | 			                            " tag: " & Object_Tag'Image(Source.Tag)); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		end if; | 
					
						
							|  |  |  | 	end Print_Object_Pointer; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 	function String_To_Integer_Pointer (Source: in Object_Character_Array) return Object_Pointer is | 
					
						
							| 
									
										
										
										
											2014-01-08 14:59:48 +00:00
										 |  |  | 		V: Object_Integer := 0; | 
					
						
							|  |  |  | 		Negative: Standard.Boolean := False; | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 		First: Object_Size; | 
					
						
							| 
									
										
										
										
											2014-01-08 14:59:48 +00:00
										 |  |  | 	begin | 
					
						
							|  |  |  | 		-- TODO: BIGNUM, RANGE CHECK, ETC
 | 
					
						
							|  |  |  | 		pragma Assert (Source'Length > 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		First := Source'First; | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 		if Source(First) = Ch_Val.Minus_Sign then | 
					
						
							| 
									
										
										
										
											2014-01-08 14:59:48 +00:00
										 |  |  | 			First := First + 1; | 
					
						
							|  |  |  | 			Negative := Standard.True; | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 		elsif Source(First) = Ch_Val.Plus_Sign then | 
					
						
							| 
									
										
										
										
											2014-01-08 14:59:48 +00:00
										 |  |  | 			First := First + 1; | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 		for I in First .. Source'Last loop | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 			V := V * 10 + Object_Character'Pos(Source(I)) - Object_Character'Pos(Ch_Val.Zero); | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		end loop; | 
					
						
							| 
									
										
										
										
											2014-01-08 14:59:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-09 18:01:38 +00:00
										 |  |  | 		if Negative then | 
					
						
							| 
									
										
										
										
											2014-01-08 14:59:48 +00:00
										 |  |  | 			V := -V; | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return Integer_To_Pointer(V); | 
					
						
							|  |  |  | 	end String_To_Integer_Pointer; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-09 18:01:38 +00:00
										 |  |  | 	-- TODO: remove this function or improve it to handle conversion properly.
 | 
					
						
							|  |  |  | 	function String_To_Object_Character_Array (Source: in Standard.String) return Object_Character_Array is | 
					
						
							|  |  |  | 		Result: Object_Character_Array (1 .. Source'Length); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		for I in Result'Range loop | 
					
						
							|  |  |  | 			Result(I) := Object_Character'Val(Standard.Character'Pos(Source(Source'First + Standard.Natural(I) - 1))); | 
					
						
							|  |  |  | 		end loop; | 
					
						
							|  |  |  | 		return Result; | 
					
						
							|  |  |  | 	end; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-29 02:30:50 +00:00
										 |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 	-- MORE CONVERSIONS
 | 
					
						
							|  |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 	--function Pointer_To_Opcode (Pointer: in Object_Pointer) return Opcode_Type renames Pointer_To_Integer;
 | 
					
						
							|  |  |  | 	--function Opcode_To_Pointer (Opcode: in Opcode_Type) return Object_Pointer renames Integer_To_Pointer;
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-29 02:30:50 +00:00
										 |  |  | 	function Pointer_To_Opcode (Pointer: in Object_Pointer) return Opcode_Type is | 
					
						
							|  |  |  | 		pragma Inline (Pointer_To_Opcode); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		return Opcode_Type'Val(Pointer_To_Integer(Pointer)); | 
					
						
							|  |  |  | 	end Pointer_To_Opcode; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Opcode_To_Pointer (Opcode: in Opcode_Type) return Object_Pointer is | 
					
						
							|  |  |  | 		pragma Inline (Opcode_To_Pointer); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		 return Integer_To_Pointer(Opcode_Type'Pos(Opcode)); | 
					
						
							|  |  |  | 	end Opcode_To_Pointer; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-10 08:33:18 +00:00
										 |  |  | 	function Pointer_To_Procedure_Code (Pointer: in Object_Pointer) return Procedure_Code is | 
					
						
							|  |  |  | 		pragma Inline (Pointer_To_Procedure_Code); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		return Procedure_Code'Val(Pointer_To_Integer(Pointer)); | 
					
						
							|  |  |  | 	end Pointer_To_Procedure_Code; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Procedure_Code_To_Pointer (Opcode: in Procedure_Code) return Object_Pointer is | 
					
						
							|  |  |  | 		pragma Inline (Procedure_Code_To_Pointer); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		 return Integer_To_Pointer(Procedure_Code'Pos(Opcode)); | 
					
						
							|  |  |  | 	end Procedure_Code_To_Pointer; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 	function Token_To_Pointer (Interp: access Interpreter_Record; | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 	                           Token:  in     Token_Record) return Object_Pointer is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		case Token.Kind is | 
					
						
							|  |  |  | 			when Integer_Token => | 
					
						
							|  |  |  | 				-- TODO: bignum
 | 
					
						
							| 
									
										
										
										
											2014-03-25 16:43:46 +00:00
										 |  |  | 				--return String_To_Integer_Pointer(Token.Value.Ptr.all(1..Token.Value.Last));
 | 
					
						
							| 
									
										
										
										
											2021-08-21 14:31:39 +00:00
										 |  |  | 				return Bigint.From_String(Interp, Token.Value.Ptr.all(1..Token.Value.Last),  10); | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			when Character_Token => | 
					
						
							|  |  |  | 				pragma Assert (Token.Value.Last = 1); | 
					
						
							|  |  |  | 				return Character_To_Pointer(Token.Value.Ptr.all(1)); | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 			when String_Token => | 
					
						
							| 
									
										
										
										
											2014-03-07 17:58:01 +00:00
										 |  |  | 				return Make_String(Interp, Token.Value.Ptr.all(1..Token.Value.Last)); | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 			when Identifier_Token => | 
					
						
							| 
									
										
										
										
											2014-03-07 17:58:01 +00:00
										 |  |  | 				return Make_Symbol(Interp, Token.Value.Ptr.all(1..Token.Value.Last)); | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			when True_Token => | 
					
						
							|  |  |  | 				return True_Pointer; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			when False_Token => | 
					
						
							|  |  |  | 				return False_Pointer; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			when others => | 
					
						
							|  |  |  | 				return null; | 
					
						
							|  |  |  | 		end case; | 
					
						
							|  |  |  | 	end Token_To_Pointer; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-14 15:47:10 +00:00
										 |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 	-- COMPARISON
 | 
					
						
							|  |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Equal_Values (X: in Object_Pointer; Y: in Object_Pointer) return Standard.Boolean is | 
					
						
							|  |  |  | 		Ptr_Type: Object_Pointer_Type; | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-02-15 03:41:37 +00:00
										 |  |  | 		if X = Y then | 
					
						
							|  |  |  | 			return Standard.True; | 
					
						
							|  |  |  | 		end if; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-14 15:47:10 +00:00
										 |  |  | 		Ptr_Type := Get_Pointer_Type(X); | 
					
						
							|  |  |  | 		case Ptr_Type is | 
					
						
							|  |  |  | 			when Object_Pointer_Type_Integer | | 
					
						
							|  |  |  | 			     Object_Pointer_Type_Character | | 
					
						
							|  |  |  | 			     Object_Pointer_Type_Byte => | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-15 03:41:37 +00:00
										 |  |  | 				-- This part of the code won't be reached if two special
 | 
					
						
							|  |  |  | 				-- pointers are the same. So False can be returned safely
 | 
					
						
							|  |  |  | 				-- without further check. See the lines commented out.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				--if Get_Pointer_Type(Y) = Ptr_Type then
 | 
					
						
							|  |  |  | 				--	return X = Y;
 | 
					
						
							|  |  |  | 				--else
 | 
					
						
							| 
									
										
										
										
											2014-02-14 15:47:10 +00:00
										 |  |  | 					return Standard.False; | 
					
						
							| 
									
										
										
										
											2014-02-15 03:41:37 +00:00
										 |  |  | 				--end if;
 | 
					
						
							| 
									
										
										
										
											2014-02-14 15:47:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			when others => | 
					
						
							|  |  |  | 				-- TODO: BIGNUM, OTHER NUMERIC DATA.
 | 
					
						
							| 
									
										
										
										
											2014-02-16 15:02:04 +00:00
										 |  |  | 				if Is_Special_Pointer(X) then | 
					
						
							|  |  |  | 					return X = Y; | 
					
						
							|  |  |  | 				elsif Get_Pointer_Type(Y) /= Ptr_Type then | 
					
						
							| 
									
										
										
										
											2014-02-15 03:41:37 +00:00
										 |  |  | 					return Standard.False; | 
					
						
							|  |  |  | 				end if; | 
					
						
							| 
									
										
										
										
											2014-02-16 15:02:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-14 15:47:10 +00:00
										 |  |  | 				case X.Kind is | 
					
						
							|  |  |  | 					when Character_Object => | 
					
						
							|  |  |  | 						if Y.Kind = X.Kind then | 
					
						
							|  |  |  | 							return X.Character_Slot = Y.Character_Slot; | 
					
						
							|  |  |  | 						else | 
					
						
							|  |  |  | 							return Standard.False; | 
					
						
							|  |  |  | 						end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					when Byte_Object => | 
					
						
							|  |  |  | 						if Y.Kind = X.Kind then | 
					
						
							|  |  |  | 							return X.Byte_Slot = Y.Byte_Slot; | 
					
						
							|  |  |  | 						else | 
					
						
							|  |  |  | 							return Standard.False; | 
					
						
							|  |  |  | 						end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					when Word_Object => | 
					
						
							|  |  |  | 						if Y.Kind = X.Kind then | 
					
						
							|  |  |  | 							return X.Word_Slot = Y.Word_Slot; | 
					
						
							|  |  |  | 						else | 
					
						
							|  |  |  | 							return Standard.False; | 
					
						
							|  |  |  | 						end if; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-20 14:51:53 +00:00
										 |  |  | 					when Half_Word_Object => | 
					
						
							|  |  |  | 						if Y.Kind = X.Kind then | 
					
						
							|  |  |  | 							return X.Half_Word_Slot = Y.Half_Word_Slot; | 
					
						
							|  |  |  | 						else | 
					
						
							|  |  |  | 							return Standard.False; | 
					
						
							|  |  |  | 						end if; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-14 15:47:10 +00:00
										 |  |  | 					when Pointer_Object => | 
					
						
							|  |  |  | 						return X = Y; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					when Moved_Object => | 
					
						
							|  |  |  | 						raise Internal_Error; | 
					
						
							|  |  |  | 				end case; | 
					
						
							|  |  |  | 		end case; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	end Equal_Values; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	-- MEMORY MANAGEMENT
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | -- (define x ())
 | 
					
						
							|  |  |  | -- (define x #())
 | 
					
						
							|  |  |  | -- (define x $())
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | -- (define x #(
 | 
					
						
							| 
									
										
										
										
											2014-02-14 15:47:10 +00:00
										 |  |  | --              (#a . 10)  ; a is a symbol
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | --              (b . 20)   ; b is a variable. resolve b at the eval-time and use it.
 | 
					
						
							|  |  |  | --              ("c" . 30) ; "c" is a string
 | 
					
						
							|  |  |  | --            )
 | 
					
						
							|  |  |  | -- )
 | 
					
						
							|  |  |  | -- (clone x y) -- deep copy
 | 
					
						
							|  |  |  | -- (define y x) -- reference assignment
 | 
					
						
							|  |  |  | -- (set! x.a 20) -- syntaic sugar
 | 
					
						
							|  |  |  | -- (set! (get x #a) 20)
 | 
					
						
							|  |  |  | -- (define x (make-hash))
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	-- I wanted to reuse the Size field to store the pointer to
 | 
					
						
							|  |  |  | 	-- the new location. GCC-GNAT 3.2.3 suffered from various constraint
 | 
					
						
							|  |  |  | 	-- check errors. So i gave up on this procedure.
 | 
					
						
							|  |  |  | 	--------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 	--procedure Set_New_Location (Object: in Object_Pointer; Ptr: in Heap_Element_Pointer) is
 | 
					
						
							|  |  |  | 		--New_Addr: Heap_Element_Pointer;
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		--for New_Addr'Address use Object.Size'Address;
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		--pragma Import (Ada, New_Addr);
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	--begin
 | 
					
						
							|  |  |  | 		--New_Addr := Ptr;
 | 
					
						
							|  |  |  | 	--end Set_New_Location;
 | 
					
						
							|  |  |  | 	--function Get_New_Location (Object: in Object_Pointer) return Object_Pointer is
 | 
					
						
							|  |  |  | 		--New_Ptr: Object_Pointer;
 | 
					
						
							|  |  |  | 		--for New_Ptr'Address use Object.Size'Address;
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		--pragma Import (Ada, New_Ptr);
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	--begin
 | 
					
						
							|  |  |  | 		--return New_Ptr;
 | 
					
						
							|  |  |  | 	--end;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 	-- Instead, I created a new object kind that indicates a moved object.
 | 
					
						
							|  |  |  | 	-- The original object is replaced by this special object. this special
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	-- object takes up the smallest space that a valid object can take. So
 | 
					
						
							|  |  |  | 	-- it is safe to overlay it on any normal objects.
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 	procedure Set_New_Location (Object: in Object_Pointer; Ptr: in Heap_Element_Pointer) is | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		Moved_Object: Moved_Object_Record; | 
					
						
							|  |  |  | 		for Moved_Object'Address use Object.all'Address; | 
					
						
							|  |  |  | 		-- pramga Import must not be specified here as I'm counting
 | 
					
						
							|  |  |  | 		-- on the default initialization of Moved_Object to overwrite
 | 
					
						
							|  |  |  | 		-- the Kind discriminant in particular.
 | 
					
						
							|  |  |  | 		--pragma Import (Ada, Moved_Object); -- this must not be used.
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 		function To_Object_Pointer is new Ada.Unchecked_Conversion (Heap_Element_Pointer, Object_Pointer); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	begin | 
					
						
							|  |  |  | 		Moved_Object.New_Pointer := To_Object_Pointer (Ptr); | 
					
						
							|  |  |  | 	end Set_New_Location; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Set_New_Location (Object: in Object_Pointer; Ptr: in Object_Pointer) is | 
					
						
							|  |  |  | 		Moved_Object: Moved_Object_Record; | 
					
						
							|  |  |  | 		for Moved_Object'Address use Object.all'Address; | 
					
						
							|  |  |  | 		--pragma Import (Ada, Moved_Object); -- this must not be used.
 | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Moved_Object.New_Pointer := Ptr; | 
					
						
							|  |  |  | 	end Set_New_Location; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Get_New_Location (Object: in Object_Pointer) return Object_Pointer is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		return Object.New_Pointer; | 
					
						
							|  |  |  | 	end Get_New_Location; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | 	function Verify_Pointer (Source: in Object_Pointer) return Object_Pointer is | 
					
						
							|  |  |  | 		pragma Inline (Verify_Pointer); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		if not Is_Normal_Pointer(Source) or else | 
					
						
							|  |  |  | 		   Source.Kind /= Moved_Object then | 
					
						
							|  |  |  | 			return Source; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			return Get_New_Location(Source); | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 	end Verify_Pointer; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 	function Allocate_Bytes_In_Heap (Heap:       access Heap_Record; | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 	                                 Heap_Bytes: in     Heap_Size) return Heap_Element_Pointer is | 
					
						
							|  |  |  | 		Avail: Heap_Size; | 
					
						
							|  |  |  | 		Result: Heap_Element_Pointer; | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 		Real_Bytes: Heap_Size := Heap_Bytes; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 		if Real_Bytes < Moved_Object_Record'Max_Size_In_Storage_Elements then | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 			-- Guarantee the minimum object size to be greater than or
 | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 			-- equal to the size of a moved object for GC to work.
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 			Real_Bytes := Moved_Object_Record'Max_Size_In_Storage_Elements; | 
					
						
							| 
									
										
										
										
											2014-02-07 09:04:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 			-- Note: Extra attention must be paid when calculating the
 | 
					
						
							|  |  |  | 			-- actual bytes allocated for an object. Scan_New_Heap() also
 | 
					
						
							| 
									
										
										
										
											2014-02-07 09:04:46 +00:00
										 |  |  | 			-- makes similar adjustment to skip actual allocated bytes.
 | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 		end if; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		Avail := Heap.Size - Heap.Bound; | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 		if Real_Bytes > Avail then | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 			return null; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		end if; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 		Result := Heap.Space(Heap.Bound + 1)'Unchecked_Access; | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 		Heap.Bound := Heap.Bound + Real_Bytes; | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 		return Result; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	end Allocate_Bytes_In_Heap; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 	function Get_Heap_Number (Interp: access Interpreter_Record; | 
					
						
							|  |  |  | 	                          Source: in     Object_Pointer) return Heap_Number is | 
					
						
							|  |  |  | 		-- for debugging
 | 
					
						
							|  |  |  | 		SW: Object_Word; | 
					
						
							|  |  |  | 		for SW'Address use Source'Address; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		H1: Heap_Element_Pointer := Interp.Heap(0).Space(1)'Unchecked_Access; | 
					
						
							|  |  |  | 		H2: Heap_Element_Pointer := Interp.Heap(1).Space(1)'Unchecked_Access; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		HW1: Object_Word; | 
					
						
							|  |  |  | 		for HW1'Address use H1'Address; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		HW2: Object_Word; | 
					
						
							|  |  |  | 		for HW2'Address use H2'Address; | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		if SW >= HW1 and then SW < HW1 + Object_Word(Interp.Heap(0).Size) then | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 			return 0; | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 		end if; | 
					
						
							|  |  |  | 		if SW >= HW2 and then SW < HW2 + Object_Word(Interp.Heap(1).Size) then | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 			return 1; | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 		end if; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | 		if Source = Nil_Pointer then | 
					
						
							|  |  |  | ada.text_io.put_line ("HEAP SOURCE IS NIL"); | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 		raise Internal_Error; | 
					
						
							|  |  |  | 	end Get_Heap_Number; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	procedure Copy_Object (Source: in     Object_Pointer; | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 	                       Target: in out Heap_Element_Pointer) is | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		pragma Inline (Copy_Object); | 
					
						
							|  |  |  | 		subtype Target_Object_Record is Object_Record (Source.Kind, Source.Size); | 
					
						
							|  |  |  | 		type Target_Object_Pointer is access all Target_Object_Record; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Target_Object: Target_Object_Pointer; | 
					
						
							|  |  |  | 		for Target_Object'Address use Target'Address; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		pragma Import (Ada, Target_Object); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	begin | 
					
						
							|  |  |  | 		-- This procedure should work. but gnat 4.3.2 on whiite(ppc32,wii)
 | 
					
						
							|  |  |  | 		-- produced erroneous code when it was called from Move_One_Object().
 | 
					
						
							|  |  |  | 		-- Target_Object_Record'Size, Target_Object.all'Size, and
 | 
					
						
							|  |  |  | 		-- Target_Object_Record'Max_Size_In_Stroage_Elements were not
 | 
					
						
							|  |  |  | 		-- always correct. For example, for a character object containing
 | 
					
						
							|  |  |  | 		-- the string "lambda", Target_Object.all'Size returned 72 while
 | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 		-- it's supposed to be 96. Use Copy_Object_With_Size() below instead.
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		Target_Object.all := Source.all; | 
					
						
							|  |  |  | 		pragma Assert (Source.all'Size = Target_Object.all'Size); | 
					
						
							|  |  |  | 	end Copy_Object; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-07 05:22:41 +00:00
										 |  |  | 	procedure Copy_Object_With_Size (Source: in Object_Pointer; | 
					
						
							|  |  |  | 	                                 Target: in Heap_Element_Pointer; | 
					
						
							|  |  |  | 	                                 Bytes:  in Heap_Size) is | 
					
						
							| 
									
										
										
										
											2014-02-07 09:04:46 +00:00
										 |  |  | 		pragma Inline (Copy_Object_With_Size); | 
					
						
							|  |  |  | 		pragma Assert (Bytes > 0); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		-- This procedure uses a more crude type for copying objects.
 | 
					
						
							|  |  |  | 		-- It's the result of an effort to work around some compiler
 | 
					
						
							|  |  |  | 		-- issues mentioned above.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-07 05:22:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		-- The work around, however, still didn't work well with gnat-3.15p.
 | 
					
						
							|  |  |  | 		-- The overlaying(thus overlaid)  pointer is initialized to null
 | 
					
						
							|  |  |  | 		-- despite pragma Import.
 | 
					
						
							|  |  |  | 		--Tgt: Thin_Heap_Element_Array_Pointer;
 | 
					
						
							|  |  |  | 		--for Tgt'Address use Target'Address;
 | 
					
						
							|  |  |  | 		--pragma Import (Ada, Tgt);
 | 
					
						
							|  |  |  | 		--Src: Thin_Heap_Element_Array_Pointer;
 | 
					
						
							|  |  |  | 		--for Src'Address use Source'Address;
 | 
					
						
							|  |  |  | 		--pragma Import (Ada, Src);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		-- So let me turn to unchecked conversion instead.
 | 
					
						
							| 
									
										
										
										
											2021-08-21 14:31:39 +00:00
										 |  |  | 		function Conv1 is new Ada.Unchecked_Conversion(Object_Pointer, Thin_Heap_Element_Array_Pointer); | 
					
						
							|  |  |  | 		function Conv2 is new Ada.Unchecked_Conversion(Heap_Element_Pointer, Thin_Heap_Element_Array_Pointer); | 
					
						
							| 
									
										
										
										
											2014-02-07 05:22:41 +00:00
										 |  |  | 		Src: Thin_Heap_Element_Array_Pointer := Conv1(Source); | 
					
						
							|  |  |  | 		Tgt: Thin_Heap_Element_Array_Pointer := Conv2(Target); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-02-07 05:22:41 +00:00
										 |  |  | 		Tgt(Tgt'First .. Tgt'First + Bytes - 1) := Src(Src'First .. Src'First + Bytes - 1); | 
					
						
							| 
									
										
										
										
											2013-12-11 16:30:56 +00:00
										 |  |  | 	end Copy_Object_With_Size; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	procedure Collect_Garbage (Interp: in out Interpreter_Record) is | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 		Last_Pos: Heap_Size; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		New_Heap: Heap_Number; | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | 		Original_Symbol_Table: Object_Pointer; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 		--function To_Object_Pointer is new Ada.Unchecked_Conversion (Heap_Element_Pointer, Object_Pointer);
 | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 		function Move_One_Object (Source: in Object_Pointer) return Object_Pointer is | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		begin | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 			pragma Assert (Is_Normal_Pointer(Source)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if Source.Kind = Moved_Object then | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 				-- the object has moved to the new heap.
 | 
					
						
							|  |  |  | 				-- the size field has been updated to the new object
 | 
					
						
							|  |  |  | 				-- in the 'else' block below. i can simply return it
 | 
					
						
							|  |  |  | 				-- without further migration.
 | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 				return Get_New_Location (Source); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 			else | 
					
						
							|  |  |  | 				declare | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 					Bytes: Heap_Size; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					-- This variable holds the allocation result
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 					Ptr: Heap_Element_Pointer; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					-- Create an overlay for type conversion
 | 
					
						
							|  |  |  | 					New_Object: Object_Pointer; | 
					
						
							|  |  |  | 					for New_Object'Address use Ptr'Address; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 					pragma Import (Ada, New_Object); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 				begin | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 					-- Target_Object_Record'Max_Size_In_Storage_Elements gave
 | 
					
						
							|  |  |  | 					-- some erroneous values when compiled with GNAT 4.3.2 on
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 					-- WII(ppc) Debian.
 | 
					
						
							|  |  |  | 					--Bytes := Target_Object_Record'Max_Size_In_Storage_Elements;
 | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 					Bytes := Source.all'Size / System.Storage_Unit; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					-- Allocate space in the new heap
 | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 					Ptr := Allocate_Bytes_In_Heap(Interp.Heap(New_Heap), Bytes); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					-- Allocation here must not fail because
 | 
					
						
							|  |  |  | 					-- I'm allocating the new space in a new heap for
 | 
					
						
							|  |  |  | 					-- moving an existing object in the current heap.
 | 
					
						
							|  |  |  | 					-- It must not fail, assuming the new heap is as large
 | 
					
						
							|  |  |  | 					-- as the old heap, and garbage collection doesn't
 | 
					
						
							|  |  |  | 					-- allocate more objects than in the old heap.
 | 
					
						
							|  |  |  | 					pragma Assert (Ptr /= null); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-07 09:04:46 +00:00
										 |  |  | 					-- This minimum size adjustment is not needed when copying
 | 
					
						
							|  |  |  | 					-- an object as it's ok to have garbage in the trailing space.
 | 
					
						
							|  |  |  | 					-- See Allocate_Bytes_In_Heap() and Scan_New_Heap() for more info.
 | 
					
						
							|  |  |  | 					--if Bytes < Moved_Object_Record'Max_Size_In_Storage_Elements then
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 					--	Bytes := Moved_Object_Record'Max_Size_In_Storage_Elements;
 | 
					
						
							| 
									
										
										
										
											2014-02-07 09:04:46 +00:00
										 |  |  | 					--end  if;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 					-- Copy the payload to the new object
 | 
					
						
							|  |  |  | 					--Copy_Object (Object, Ptr); -- not reliable with some compilers
 | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 					Copy_Object_With_Size (Source, Ptr, Bytes); -- use this instead
 | 
					
						
							|  |  |  | 					pragma Assert (Source.all'Size = New_Object.all'Size); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 					pragma Assert (Bytes = New_Object.all'Size / System.Storage_Unit); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					-- Let the size field of the old object point to the
 | 
					
						
							|  |  |  | 					-- new object allocated in the new heap. It is returned
 | 
					
						
							|  |  |  | 					-- in the 'if' block at the beginning of this function
 | 
					
						
							|  |  |  | 					-- if the object is marked with FLAG_MOVED;
 | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 					Set_New_Location (Source, Ptr); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					-- Return the new object
 | 
					
						
							|  |  |  | 					return New_Object; | 
					
						
							|  |  |  | 				end; | 
					
						
							|  |  |  | 			end if; | 
					
						
							|  |  |  | 		end Move_One_Object; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 		function Scan_New_Heap (Start_Position: in Heap_Size) return Heap_Size is | 
					
						
							|  |  |  | 			Ptr: Heap_Element_Pointer; | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 			Position: Heap_Size := Start_Position; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		begin | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | --Ada.Text_IO.Put_Line ("Start Scanning New Heap from " & Heap_Size'Image(Start_Position) & " Bound: " & Heap_Size'Image (Interp.Heap(New_Heap).Bound));
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 			while Position <= Interp.Heap(New_Heap).Bound loop | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | --Ada.Text_IO.Put_Line (">>> Scanning New Heap from " & Heap_Size'Image (Position) & " Bound: " & Heap_Size'Image (Interp.Heap(New_Heap).Bound));
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 				Ptr := Interp.Heap(New_Heap).Space(Position)'Unchecked_Access; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				declare | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 					-- There is a overlaid pointer initialization problem despite
 | 
					
						
							| 
									
										
										
										
											2014-02-07 05:22:41 +00:00
										 |  |  | 					-- "pragma Import()" in gnat-3.15p.
 | 
					
						
							|  |  |  | 					--Object: Object_Pointer;
 | 
					
						
							|  |  |  | 					--for Object'Address use Ptr'Address;
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 					--pragma Import (Ada, Object);
 | 
					
						
							| 
									
										
										
										
											2014-02-07 05:22:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					-- So let me turn to unchecked conversion.
 | 
					
						
							|  |  |  | 					function Conv1 is new Ada.Unchecked_Conversion (Heap_Element_Pointer, Object_Pointer); | 
					
						
							|  |  |  | 					Object: Object_Pointer := Conv1(Ptr); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					--subtype Target_Object_Record is Object_Record (Object.Kind, Object.Size);
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 					Bytes: Heap_Size; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 				begin | 
					
						
							|  |  |  | 					--Bytes := Target_Object_Record'Max_Size_In_Storage_Elements;
 | 
					
						
							|  |  |  | 					Bytes := Object.all'Size / System.Storage_Unit; | 
					
						
							| 
									
										
										
										
											2014-02-07 09:04:46 +00:00
										 |  |  | 					if Bytes < Moved_Object_Record'Max_Size_In_Storage_Elements then | 
					
						
							|  |  |  | 						-- Allocate_Bytes_In_Heap() guarantee the minimum object size.
 | 
					
						
							|  |  |  | 						-- The size must be guaranteed here when scanning a heap.
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 						Bytes := Moved_Object_Record'Max_Size_In_Storage_Elements; | 
					
						
							| 
									
										
										
										
											2014-02-07 09:04:46 +00:00
										 |  |  | 					end if; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					if Object.Kind = Pointer_Object then | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | --Ada.Text_IO.Put_Line (">>> Scanning Obj " & Object_Kind'Image(Object.Kind) & " Size: " & Object_Size'Image(Object.Size) & " At " & Object_Word'Image(Pointer_To_Word(Object)) & " Bytes " & Heap_Size'Image(Bytes));
 | 
					
						
							|  |  |  | --Print_Object_Pointer (">>> Scanning :", Object);
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 						for i in Object.Pointer_Slot'Range loop | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 							if Is_Normal_Pointer(Object.Pointer_Slot(i)) then | 
					
						
							|  |  |  | 								Object.Pointer_Slot(i) := Move_One_Object(Object.Pointer_Slot(i)); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 							end if; | 
					
						
							|  |  |  | 						end loop; | 
					
						
							|  |  |  | 					end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					Position := Position + Bytes; | 
					
						
							|  |  |  | 				end; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			end loop; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return Position; | 
					
						
							|  |  |  | 		end Scan_New_Heap; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		procedure Compact_Symbol_Table is | 
					
						
							|  |  |  | 			Pred: Object_Pointer; | 
					
						
							|  |  |  | 			Cons: Object_Pointer; | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | 			Car: Object_Pointer; | 
					
						
							|  |  |  | 			Cdr: Object_Pointer; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		begin | 
					
						
							|  |  |  | -- TODO: Change code here if the symbol table structure is changed to a hash table.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Pred := Nil_Pointer; | 
					
						
							|  |  |  | 			Cons := Interp.Symbol_Table; | 
					
						
							|  |  |  | 			while Cons /= Nil_Pointer loop | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 				pragma Assert (Cons.Tag = Cons_Object); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | 				Car := Cons.Pointer_Slot(Cons_Car_Index); | 
					
						
							|  |  |  | 				Cdr := Cons.Pointer_Slot(Cons_Cdr_Index); | 
					
						
							|  |  |  | 				pragma Assert (Car.Kind = Moved_Object or else Car.Tag = Symbol_Object); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if Car.Kind /= Moved_Object and then | 
					
						
							|  |  |  | 				   (Car.Flags and Syntax_Object) = 0 then | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 					-- A non-syntax symbol has not been moved.
 | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | 					-- Unlink the cons cell from the symbol table.
 | 
					
						
							|  |  |  | 					if Pred = Nil_Pointer then | 
					
						
							|  |  |  | 						Interp.Symbol_Table := Cdr; | 
					
						
							|  |  |  | 					else | 
					
						
							|  |  |  | 						Pred.Pointer_Slot(Cons_Cdr_Index) := Cdr; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 					end if; | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | 				else | 
					
						
							|  |  |  | 					Pred := Cons; | 
					
						
							|  |  |  | 				end if; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				Cons := Cdr; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 			end loop; | 
					
						
							|  |  |  | 		end Compact_Symbol_Table; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-07 05:22:41 +00:00
										 |  |  | ada.text_io.put_line ("[GC BEGIN]"); | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | --declare
 | 
					
						
							|  |  |  | --Avail: Heap_Size;
 | 
					
						
							|  |  |  | --begin
 | 
					
						
							|  |  |  | --Avail := Interp.Heap(Interp.Current_Heap).Size - Interp.Heap(Interp.Current_Heap).Bound;
 | 
					
						
							|  |  |  | --Ada.Text_IO.Put_Line (">>> [GC BEGIN] BOUND: " & Heap_Size'Image(Interp.Heap(Interp.Current_Heap).Bound) & " AVAIL: " & Heap_Size'Image(Avail));
 | 
					
						
							|  |  |  | --end;
 | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		-- As the Heap_Number type is a modular type that can
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		-- represent 0 and 1, incrementing it gives the next value.
 | 
					
						
							|  |  |  | 		New_Heap := Interp.Current_Heap + 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 		-- Migrate some root objects
 | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | --Print_Object_Pointer (">>> [GC] Stack BEFORE ...", Interp.Stack);
 | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 		if Is_Normal_Pointer(Interp.Stack) then | 
					
						
							|  |  |  | 			Interp.Stack := Move_One_Object(Interp.Stack); | 
					
						
							|  |  |  | 		end if; | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 		Interp.Root_Environment := Move_One_Object(Interp.Root_Environment); | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 		Interp.Root_Frame := Move_One_Object(Interp.Root_Frame); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-15 09:21:26 +00:00
										 |  |  | 		-- Migrate temporary object pointers
 | 
					
						
							|  |  |  | 		for I in Interp.Top.Data'First .. Interp.Top.Last loop | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 			if Interp.Top.Data(I).all = Interp.Symbol_Table then | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | 				-- The symbol table must stay before compaction.
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 				-- Skip migrating a temporary object pointer if it
 | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | 				-- is pointing to the symbol table. Remember that
 | 
					
						
							|  |  |  | 				-- such skipping has happened.
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 				Original_Symbol_Table := Interp.Symbol_Table; | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | 			elsif Interp.Top.Data(I).all /= null and then | 
					
						
							|  |  |  | 			      Is_Normal_Pointer(Interp.Top.Data(I).all) then | 
					
						
							| 
									
										
										
										
											2014-01-15 09:21:26 +00:00
										 |  |  | 				Interp.Top.Data(I).all := Move_One_Object(Interp.Top.Data(I).all); | 
					
						
							|  |  |  | 			end if; | 
					
						
							|  |  |  | 		end loop; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-22 14:11:30 +00:00
										 |  |  | 		-- Migrate some known symbols
 | 
					
						
							| 
									
										
										
										
											2014-02-10 15:39:20 +00:00
										 |  |  | 		Interp.Arrow_Symbol := Move_One_Object(Interp.Arrow_Symbol); | 
					
						
							|  |  |  | 		Interp.Else_Symbol := Move_One_Object(Interp.Else_Symbol); | 
					
						
							|  |  |  | 		Interp.Quasiquote_Symbol := Move_One_Object(Interp.Quasiquote_Symbol); | 
					
						
							|  |  |  | 		Interp.Quote_Symbol := Move_One_Object(Interp.Quote_Symbol); | 
					
						
							| 
									
										
										
										
											2014-01-22 14:11:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | --Ada.Text_IO.Put_Line (">>> [GC SCANNING NEW HEAP]");
 | 
					
						
							| 
									
										
										
										
											2014-01-15 09:21:26 +00:00
										 |  |  | 		-- Scan the heap
 | 
					
						
							|  |  |  | 		Last_Pos := Scan_New_Heap(Interp.Heap(New_Heap).Space'First); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		-- Traverse the symbol table for unreferenced symbols.
 | 
					
						
							|  |  |  | 		-- If the symbol has not moved to the new heap, the symbol
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		-- is not referenced by any other objects than the symbol
 | 
					
						
							|  |  |  | 		-- table itself
 | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | --Ada.Text_IO.Put_Line (">>> [GC COMPACTING SYMBOL TABLE]");
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		Compact_Symbol_Table; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | --Print_Object_Pointer (">>> [GC MOVING SYMBOL TABLE]", Interp.Symbol_Table);
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		-- Migrate the symbol table itself
 | 
					
						
							| 
									
										
										
										
											2014-01-15 09:21:26 +00:00
										 |  |  | 		Interp.Symbol_Table := Move_One_Object(Interp.Symbol_Table); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | 		-- Update temporary object pointers that were pointing to the symbol table
 | 
					
						
							|  |  |  | 		if Original_Symbol_Table /= null then | 
					
						
							|  |  |  | 			for I in Interp.Top.Data'First .. Interp.Top.Last loop | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 				if Interp.Top.Data(I).all = Original_Symbol_Table then | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | 					-- update to the new symbol table
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 					Interp.Top.Data(I).all := Interp.Symbol_Table; | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | 				end if; | 
					
						
							|  |  |  | 			end loop; | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | --Ada.Text_IO.Put_Line (">>> [GC SCANNING HEAP AGAIN AFTER SYMBOL TABLE MIGRATION]");
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		-- Scan the new heap again from the end position of
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		-- the previous scan to move referenced objects by
 | 
					
						
							|  |  |  | 		-- the symbol table.
 | 
					
						
							| 
									
										
										
										
											2014-01-15 09:21:26 +00:00
										 |  |  | 		Last_Pos := Scan_New_Heap(Last_Pos); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		-- Swap the current heap and the new heap
 | 
					
						
							|  |  |  | 		Interp.Heap(Interp.Current_Heap).Bound := 0; | 
					
						
							|  |  |  | 		Interp.Current_Heap := New_Heap; | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | --declare
 | 
					
						
							|  |  |  | --Avail: Heap_Size;
 | 
					
						
							|  |  |  | --begin
 | 
					
						
							|  |  |  | --Avail := Interp.Heap(Interp.Current_Heap).Size - Interp.Heap(Interp.Current_Heap).Bound;
 | 
					
						
							|  |  |  | --Print_Object_Pointer (">>> [GC DONE] Stack ...", Interp.Stack);
 | 
					
						
							|  |  |  | --Ada.Text_IO.Put_Line (">>> [GC DONE] BOUND: " & Heap_Size'Image(Interp.Heap(Interp.Current_Heap).Bound) & " AVAIL: " & Heap_Size'Image(Avail));
 | 
					
						
							|  |  |  | --Ada.Text_IO.Put_Line (">>> [GC DONE] ----------------------------------------------------------");
 | 
					
						
							|  |  |  | --end;
 | 
					
						
							| 
									
										
										
										
											2014-02-07 05:22:41 +00:00
										 |  |  | ada.text_io.put_line ("[GC END]"); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	end Collect_Garbage; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 	function Allocate_Bytes (Interp: access Interpreter_Record; | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 	                         Bytes:  in     Heap_Size) return Heap_Element_Pointer is | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		-- I use this temporary variable not to change Result
 | 
					
						
							|  |  |  | 		-- if Allocation_Error should be raised.
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 		Tmp: Heap_Element_Pointer; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	begin | 
					
						
							|  |  |  | 		pragma Assert (Bytes > 0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | -- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 | 
					
						
							|  |  |  | if DEBUG_GC then | 
					
						
							|  |  |  | 	Collect_Garbage (Interp.all); | 
					
						
							|  |  |  | end if; | 
					
						
							|  |  |  | -- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 		Tmp := Allocate_Bytes_In_Heap (Interp.Heap(Interp.Current_Heap), Bytes); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		if Tmp = null and then (Interp.Trait.Trait_Bits and No_Garbage_Collection) = 0 then | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 			Collect_Garbage (Interp.all); | 
					
						
							|  |  |  | 			Tmp := Allocate_Bytes_In_Heap (Interp.Heap(Interp.Current_Heap), Bytes); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 			if Tmp = null then | 
					
						
							|  |  |  | 				raise Allocation_Error; | 
					
						
							|  |  |  | 			end if; | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 		return Tmp; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	end Allocate_Bytes; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 	function Allocate_Pointer_Object (Interp:  access Interpreter_Record; | 
					
						
							|  |  |  | 	                                  Size:    in     Pointer_Object_Size; | 
					
						
							|  |  |  | 	                                  Initial: in     Object_Pointer) return Object_Pointer is | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		subtype Pointer_Object_Record is Object_Record (Pointer_Object, Size); | 
					
						
							|  |  |  | 		type Pointer_Object_Pointer is access all Pointer_Object_Record; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 		Ptr: Heap_Element_Pointer; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		Obj_Ptr: Pointer_Object_Pointer; | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 		for Obj_Ptr'Address use Ptr'Address; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		pragma Import (Ada, Obj_Ptr); | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 		Result: Object_Pointer; | 
					
						
							|  |  |  | 		for Result'Address use Ptr'Address; | 
					
						
							|  |  |  | 		pragma Import (Ada, Result); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2021-08-21 14:31:39 +00:00
										 |  |  | 		Ptr := Allocate_Bytes( | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 			Interp, | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 			Heap_Size'(Pointer_Object_Record'Max_Size_In_Storage_Elements) | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Obj_Ptr.all := ( | 
					
						
							|  |  |  | 			Kind => Pointer_Object, | 
					
						
							|  |  |  | 			Size => Size, | 
					
						
							|  |  |  | 			Flags => 0, | 
					
						
							|  |  |  | 			Tag => Unknown_Object, | 
					
						
							| 
									
										
										
										
											2014-02-20 14:51:53 +00:00
										 |  |  | 			Scode => Syntax_Code'Val(0), | 
					
						
							|  |  |  | 			Sign => Positive_Sign, | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 			Pointer_Slot => (others => Initial) | 
					
						
							|  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		return Result; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	end Allocate_Pointer_Object; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 	function Allocate_Character_Object (Interp: access Interpreter_Record; | 
					
						
							|  |  |  | 	                                    Size:   in     Character_Object_Size) return Object_Pointer is | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		subtype Character_Object_Record is Object_Record (Character_Object, Size); | 
					
						
							|  |  |  | 		type Character_Object_Pointer is access all Character_Object_Record; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 		Ptr: Heap_Element_Pointer; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		Obj_Ptr: Character_Object_Pointer; | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 		for Obj_Ptr'Address use Ptr'Address; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		pragma Import (Ada, Obj_Ptr); | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 		Result: Object_Pointer; | 
					
						
							|  |  |  | 		for Result'Address use Ptr'Address; | 
					
						
							|  |  |  | 		pragma Import (Ada, Result); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 		Ptr := Allocate_Bytes ( | 
					
						
							|  |  |  | 			Interp.Self, | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 			Heap_Size'(Character_Object_Record'Max_Size_In_Storage_Elements) | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Obj_Ptr.all := ( | 
					
						
							|  |  |  | 			Kind => Character_Object, | 
					
						
							|  |  |  | 			Size => Size, | 
					
						
							|  |  |  | 			Flags => 0, | 
					
						
							|  |  |  | 			Tag => Unknown_Object, | 
					
						
							| 
									
										
										
										
											2014-02-20 14:51:53 +00:00
										 |  |  | 			Scode => Syntax_Code'Val(0), | 
					
						
							|  |  |  | 			Sign => Positive_Sign, | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 			Character_Slot => (others => Ch_Val.NUL), | 
					
						
							|  |  |  | 			Character_Terminator => Ch_Val.NUL | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		); | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		return Result; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	end Allocate_Character_Object; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 	function Allocate_Character_Object (Interp: access Interpreter_Record; | 
					
						
							| 
									
										
										
										
											2014-03-07 17:58:01 +00:00
										 |  |  | 	                                    Source: in     Object_Character_Array; | 
					
						
							|  |  |  | 	                                    Invert: in     Standard.Boolean) return Object_Pointer is | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 		Result: Object_Pointer; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	begin | 
					
						
							|  |  |  | 		if Source'Length > Character_Object_Size'Last then | 
					
						
							|  |  |  | 			raise Size_Error; | 
					
						
							|  |  |  | 		end if; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-07 17:58:01 +00:00
										 |  |  | 		Result := Allocate_Character_Object (Interp, Size => Character_Object_Size'(Source'Length)); | 
					
						
							|  |  |  | 		if Invert then | 
					
						
							|  |  |  | 			for I in Source'Range loop | 
					
						
							|  |  |  | 				Result.Character_Slot(Result.Character_Slot'Last - (I - Source'First)) := Source(I); | 
					
						
							|  |  |  | 			end loop; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			Result.Character_Slot := Source; | 
					
						
							|  |  |  | 		end if; | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 		return Result; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	end Allocate_Character_Object; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 	function Allocate_Byte_Object (Interp: access Interpreter_Record; | 
					
						
							|  |  |  | 	                               Size:   in     Byte_Object_Size) return Object_Pointer is | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		subtype Byte_Object_Record is Object_Record (Byte_Object, Size); | 
					
						
							|  |  |  | 		type Byte_Object_Pointer is access all Byte_Object_Record; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 		Ptr: Heap_Element_Pointer; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		Obj_Ptr: Byte_Object_Pointer; | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 		for Obj_Ptr'Address use Ptr'Address; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		pragma Import (Ada, Obj_Ptr); | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 		Result: Object_Pointer; | 
					
						
							|  |  |  | 		for Result'Address use Ptr'Address; | 
					
						
							|  |  |  | 		pragma Import (Ada, Result); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 		Ptr := Allocate_Bytes (Interp.Self, Heap_Size'(Byte_Object_Record'Max_Size_In_Storage_Elements)); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		Obj_Ptr.all := ( | 
					
						
							|  |  |  | 			Kind => Byte_Object, | 
					
						
							|  |  |  | 			Size => Size, | 
					
						
							|  |  |  | 			Flags => 0, | 
					
						
							|  |  |  | 			Tag => Unknown_Object, | 
					
						
							| 
									
										
										
										
											2014-02-20 14:51:53 +00:00
										 |  |  | 			Scode => Syntax_Code'Val(0), | 
					
						
							|  |  |  | 			Sign => Positive_Sign, | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 			Byte_Slot => (others => 0) | 
					
						
							|  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 		return Result; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	end Allocate_Byte_Object; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-20 14:51:53 +00:00
										 |  |  | 	function Allocate_Word_Object (Interp: access Interpreter_Record; | 
					
						
							|  |  |  | 	                               Size:   in     Word_Object_Size) return Object_Pointer is | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		subtype Word_Object_Record is Object_Record (Word_Object, Size); | 
					
						
							|  |  |  | 		type Word_Object_Pointer is access all Word_Object_Record; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Ptr: Heap_Element_Pointer; | 
					
						
							|  |  |  | 		Obj_Ptr: Word_Object_Pointer; | 
					
						
							|  |  |  | 		for Obj_Ptr'Address use Ptr'Address; | 
					
						
							|  |  |  | 		pragma Import (Ada, Obj_Ptr); | 
					
						
							|  |  |  | 		Result: Object_Pointer; | 
					
						
							|  |  |  | 		for Result'Address use Ptr'Address; | 
					
						
							|  |  |  | 		pragma Import (Ada, Result); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Ptr := Allocate_Bytes (Interp.Self, Heap_Size'(Word_Object_Record'Max_Size_In_Storage_Elements)); | 
					
						
							|  |  |  | 		Obj_Ptr.all := ( | 
					
						
							|  |  |  | 			Kind => Word_Object, | 
					
						
							|  |  |  | 			Size => Size, | 
					
						
							|  |  |  | 			Flags => 0, | 
					
						
							|  |  |  | 			Tag => Unknown_Object, | 
					
						
							|  |  |  | 			Scode => Syntax_Code'Val(0), | 
					
						
							|  |  |  | 			Sign => Positive_Sign, | 
					
						
							|  |  |  | 			Word_Slot => (others => 0) | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 		return Result; | 
					
						
							|  |  |  | 	end Allocate_Word_Object; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Allocate_Half_Word_Object (Interp: access Interpreter_Record; | 
					
						
							|  |  |  | 	                                    Size:   in     Half_Word_Object_Size) return Object_Pointer is | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		subtype Half_Word_Object_Record is Object_Record (Half_Word_Object, Size); | 
					
						
							|  |  |  | 		type Half_Word_Object_Pointer is access all Half_Word_Object_Record; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Ptr: Heap_Element_Pointer; | 
					
						
							|  |  |  | 		Obj_Ptr: Half_Word_Object_Pointer; | 
					
						
							|  |  |  | 		for Obj_Ptr'Address use Ptr'Address; | 
					
						
							|  |  |  | 		pragma Import (Ada, Obj_Ptr); | 
					
						
							|  |  |  | 		Result: Object_Pointer; | 
					
						
							|  |  |  | 		for Result'Address use Ptr'Address; | 
					
						
							|  |  |  | 		pragma Import (Ada, Result); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Ptr := Allocate_Bytes (Interp.Self, Heap_Size'(Half_Word_Object_Record'Max_Size_In_Storage_Elements)); | 
					
						
							|  |  |  | 		Obj_Ptr.all := ( | 
					
						
							|  |  |  | 			Kind => Half_Word_Object, | 
					
						
							|  |  |  | 			Size => Size, | 
					
						
							|  |  |  | 			Flags => 0, | 
					
						
							|  |  |  | 			Tag => Unknown_Object, | 
					
						
							|  |  |  | 			Scode => Syntax_Code'Val(0), | 
					
						
							|  |  |  | 			Sign => Positive_Sign, | 
					
						
							|  |  |  | 			Half_Word_Slot => (others => 0) | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 		return Result; | 
					
						
							|  |  |  | 	end Allocate_Half_Word_Object; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 	procedure Push_Top (Interp: in out Interpreter_Record; | 
					
						
							|  |  |  | 	                    Source: access Object_Pointer) is | 
					
						
							|  |  |  | 		Top: Top_Record renames Interp.Top; | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		if Top.Last >= Top.Data'Last then | 
					
						
							|  |  |  | 			-- Something is wrong. Too many temporary object pointers
 | 
					
						
							|  |  |  | 			raise Internal_Error; -- TODO: change the exception to something else.
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		end if; | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		Top.Last := Top.Last + 1; | 
					
						
							|  |  |  | 		Top.Data(Top.Last) := Top_Datum(Source); | 
					
						
							|  |  |  | 	end Push_Top; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 	procedure Pop_Tops (Interp: in out Interpreter_Record; | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 	                    Count:  in     Object_Size) is | 
					
						
							|  |  |  | 		Top: Top_Record renames Interp.Top; | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		if Top.Last < Count then | 
					
						
							|  |  |  | 			-- Something is wrong. Too few temporary object pointers
 | 
					
						
							|  |  |  | 			raise Internal_Error; -- TODO: change the exception to something else.
 | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 		Top.Last := Top.Last - Count; | 
					
						
							|  |  |  | 	end Pop_Tops; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Clear_Tops (Interp: in out Interpreter_Record) is | 
					
						
							|  |  |  | 		pragma Inline (Clear_Tops); | 
					
						
							|  |  |  | 		Top: Top_Record renames Interp.Top; | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Top.Last := Top.Data'First - 1; | 
					
						
							|  |  |  | 	end Clear_Tops; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 	function Make_Cons (Interp:  access Interpreter_Record; | 
					
						
							|  |  |  | 	                    Car:     in     Object_Pointer; | 
					
						
							|  |  |  | 	                    Cdr:     in     Object_Pointer) return Object_Pointer is | 
					
						
							|  |  |  | 		Cons: Object_Pointer; | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 		Aliased_Car: aliased Object_Pointer := Car; | 
					
						
							|  |  |  | 		Aliased_Cdr: aliased Object_Pointer := Cdr; | 
					
						
							| 
									
										
										
										
											2013-12-18 14:58:46 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 		Push_Top (Interp.all, Aliased_Car'Unchecked_Access); | 
					
						
							|  |  |  | 		Push_Top (Interp.all, Aliased_Cdr'Unchecked_Access); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-21 14:31:39 +00:00
										 |  |  | 		Cons := Allocate_Pointer_Object(Interp, Cons_Object_Size, Nil_Pointer); | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | 		Cons.Pointer_Slot(Cons_Car_Index) := Aliased_Car; | 
					
						
							|  |  |  | 		Cons.Pointer_Slot(Cons_Cdr_Index) := Aliased_Cdr; | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 		Cons.Tag := Cons_Object; | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		Pop_Tops (Interp.all, 2); | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 		return Cons; | 
					
						
							| 
									
										
										
										
											2013-12-18 14:58:46 +00:00
										 |  |  | 	end Make_Cons; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	function Is_Cons (Source: in Object_Pointer) return Standard.Boolean is | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		return Is_Normal_Pointer(Source) and then | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		       Source.Tag = Cons_Object; | 
					
						
							|  |  |  | 	end Is_Cons; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 	function Get_Car (Source: in Object_Pointer) return Object_Pointer is | 
					
						
							|  |  |  | 		pragma Inline (Get_Car); | 
					
						
							| 
									
										
										
										
											2013-12-18 14:58:46 +00:00
										 |  |  | 		pragma Assert (Is_Cons(Source)); | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 		return Source.Pointer_Slot(Cons_Car_Index); | 
					
						
							|  |  |  | 	end Get_Car; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 	procedure Set_Car (Source: in Object_Pointer; | 
					
						
							|  |  |  | 	                   Value:  in Object_Pointer) is | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 		pragma Inline (Set_Car); | 
					
						
							| 
									
										
										
										
											2013-12-18 14:58:46 +00:00
										 |  |  | 		pragma Assert (Is_Cons(Source)); | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 		Source.Pointer_Slot(Cons_Car_Index) := Value; | 
					
						
							|  |  |  | 	end Set_Car; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Get_Cdr (Source: in Object_Pointer) return Object_Pointer is | 
					
						
							|  |  |  | 		pragma Inline (Get_Cdr); | 
					
						
							| 
									
										
										
										
											2013-12-18 14:58:46 +00:00
										 |  |  | 		pragma Assert (Is_Cons(Source)); | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 		return Source.Pointer_Slot(Cons_Cdr_Index); | 
					
						
							|  |  |  | 	end Get_Cdr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 	procedure Set_Cdr (Source: in Object_Pointer; | 
					
						
							|  |  |  | 	                   Value:  in Object_Pointer) is | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 		pragma Inline (Set_Cdr); | 
					
						
							| 
									
										
										
										
											2013-12-18 14:58:46 +00:00
										 |  |  | 		pragma Assert (Is_Cons(Source)); | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 		Source.Pointer_Slot(Cons_Cdr_Index) := Value; | 
					
						
							|  |  |  | 	end Set_Cdr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-20 15:47:08 +00:00
										 |  |  | 	function Get_Last_Cdr (Source: in Object_Pointer) return Object_Pointer is | 
					
						
							|  |  |  | 		pragma Assert (Is_Cons(Source)); | 
					
						
							|  |  |  | 		Ptr: Object_Pointer := Source; | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		loop | 
					
						
							|  |  |  | 			Ptr := Get_Cdr(Ptr); | 
					
						
							|  |  |  | 			exit when not Is_Cons(Ptr); | 
					
						
							|  |  |  | 		end loop; | 
					
						
							|  |  |  | 		return Ptr; | 
					
						
							|  |  |  | 	end Get_Last_Cdr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 	function Reverse_Cons (Source:   in Object_Pointer; | 
					
						
							| 
									
										
										
										
											2014-01-08 07:18:14 +00:00
										 |  |  | 	                       Last_Cdr: in Object_Pointer := Nil_Pointer) return Object_Pointer is | 
					
						
							| 
									
										
										
										
											2013-12-18 14:58:46 +00:00
										 |  |  | 		pragma Assert (Is_Cons(Source)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		-- Note: The non-nil cdr in the last cons cell gets lost.
 | 
					
						
							|  |  |  | 		--       e.g.) Reversing (1 2 3 . 4) results in (3 2 1)
 | 
					
						
							|  |  |  | 		Ptr: Object_Pointer; | 
					
						
							|  |  |  | 		Next: Object_Pointer; | 
					
						
							|  |  |  | 		Prev: Object_Pointer; | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-01-08 07:18:14 +00:00
										 |  |  | 		Prev := Last_Cdr; | 
					
						
							| 
									
										
										
										
											2013-12-18 14:58:46 +00:00
										 |  |  | 		Ptr := Source; | 
					
						
							|  |  |  | 		loop | 
					
						
							|  |  |  | 			Next := Get_Cdr(Ptr); | 
					
						
							|  |  |  | 			Set_Cdr (Ptr, Prev); | 
					
						
							|  |  |  | 			Prev := Ptr; | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | 			exit when not Is_Cons(Next); | 
					
						
							|  |  |  | 			Ptr := Next; | 
					
						
							| 
									
										
										
										
											2013-12-18 14:58:46 +00:00
										 |  |  | 		end loop; | 
					
						
							|  |  |  | 		return Ptr; | 
					
						
							|  |  |  | 	end Reverse_Cons; | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-10 08:33:18 +00:00
										 |  |  | 	function Is_String (Source: in Object_Pointer) return Standard.Boolean is | 
					
						
							|  |  |  | 		pragma Inline (Is_String); | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		return Is_Normal_Pointer(Source) and then | 
					
						
							| 
									
										
										
										
											2014-02-10 08:33:18 +00:00
										 |  |  | 		       Source.Tag = String_Object; | 
					
						
							|  |  |  | 	end Is_String; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 	function Make_String (Interp: access  Interpreter_Record; | 
					
						
							| 
									
										
										
										
											2014-03-07 17:58:01 +00:00
										 |  |  | 	                      Source: in      Object_Character_Array; | 
					
						
							|  |  |  | 	                      Invert: in      Standard.Boolean := Standard.False) return Object_Pointer is | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 		Result: Object_Pointer; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-03-07 17:58:01 +00:00
										 |  |  | 		Result := Allocate_Character_Object(Interp, Source, Invert); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		Result.Tag := String_Object; | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 		return Result; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	end Make_String; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 	function Is_Symbol (Source: in Object_Pointer) return Standard.Boolean is | 
					
						
							|  |  |  | 		pragma Inline (Is_Symbol); | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		return Is_Normal_Pointer(Source) and then | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 		       Source.Tag = Symbol_Object; | 
					
						
							|  |  |  | 	end Is_Symbol; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 	function Make_Symbol (Interp: access Interpreter_Record; | 
					
						
							| 
									
										
										
										
											2014-03-07 17:58:01 +00:00
										 |  |  | 	                      Source: in     Object_Character_Array; | 
					
						
							|  |  |  | 	                      Invert: in     Standard.Boolean := Standard.False) return Object_Pointer is | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 		Ptr: aliased Object_Pointer; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	begin | 
					
						
							|  |  |  | 		-- TODO: the current linked list implementation isn't efficient.
 | 
					
						
							|  |  |  | 		--       change the symbol table to a hashable table.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		-- Find an existing symbol in the symbol table.
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 		Ptr := Interp.Symbol_Table; | 
					
						
							|  |  |  | 		while Ptr /= Nil_Pointer loop | 
					
						
							|  |  |  | 			pragma Assert (Is_Cons(Ptr)); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			declare | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 				Car: Object_Pointer renames Ptr.Pointer_Slot(Cons_Car_Index); | 
					
						
							|  |  |  | 				Cdr: Object_Pointer renames Ptr.Pointer_Slot(Cons_Cdr_Index); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 			begin | 
					
						
							|  |  |  | 				pragma Assert (Car.Tag = Symbol_Object); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-10 14:54:46 +00:00
										 |  |  | 				if Car.Character_Slot = Source then | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | 					-- the character string contents are the same.
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 					return Car; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 				end if; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 				Ptr := Cdr; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 			end; | 
					
						
							|  |  |  | 		end loop; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		-- Create a symbol object
 | 
					
						
							| 
									
										
										
										
											2014-03-07 17:58:01 +00:00
										 |  |  | 		Ptr := Allocate_Character_Object(Interp, Source, Invert); | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 		Ptr.Tag := Symbol_Object; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | 		-- Make Ptr safe from GC
 | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 		Push_Top (Interp.all, Ptr'Unchecked_Access); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		-- Link the symbol to the symbol table.
 | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | 		Interp.Symbol_Table := Make_Cons(Interp.Self, Ptr, Interp.Symbol_Table); | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		Pop_Tops (Interp.all, 1); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 		return Ptr; | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 	end Make_Symbol; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 	function Make_Array (Interp: access Interpreter_Record; | 
					
						
							|  |  |  | 	                     Size:   in     Pointer_Object_Size) return Object_Pointer is | 
					
						
							| 
									
										
										
										
											2014-02-20 14:51:53 +00:00
										 |  |  | 		Ptr: Object_Pointer; | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-02-20 14:51:53 +00:00
										 |  |  | 		Ptr := Allocate_Pointer_Object(Interp, Size, Nil_Pointer); | 
					
						
							|  |  |  | 		Ptr.Tag := Array_Object; | 
					
						
							|  |  |  | 		return Ptr; | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 	end Make_Array; | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 	function Is_Array (Source: in Object_Pointer) return Standard.Boolean is | 
					
						
							|  |  |  | 		pragma Inline (Is_Array); | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		return Is_Normal_Pointer(Source) and then | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 		       Source.Tag = Array_Object; | 
					
						
							|  |  |  | 	end Is_Array; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-20 14:51:53 +00:00
										 |  |  | 	function Make_Bigint (Interp: access Interpreter_Record; | 
					
						
							| 
									
										
										
										
											2014-02-21 16:08:43 +00:00
										 |  |  | 	                      Size:   in     Half_Word_Object_Size) return Object_Pointer is | 
					
						
							| 
									
										
										
										
											2014-02-20 14:51:53 +00:00
										 |  |  | 		Ptr: Object_Pointer; | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Ptr := Allocate_Half_Word_Object(Interp, Size); | 
					
						
							|  |  |  | 		Ptr.Tag := Bigint_Object; | 
					
						
							|  |  |  | 		return Ptr; | 
					
						
							|  |  |  | 	end Make_Bigint; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Make_Bigint (Interp: access Interpreter_Record; | 
					
						
							|  |  |  | 	                      Value:  in     Object_Integer) return Object_Pointer is | 
					
						
							|  |  |  | 		Size: Pointer_Object_Size; | 
					
						
							|  |  |  | 		Ptr: Object_Pointer; | 
					
						
							|  |  |  | 		W: Object_Word; | 
					
						
							|  |  |  | 		H: Object_Half_Word; | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		if Value < 0 then | 
					
						
							|  |  |  | 			W := Object_Word(-(Object_Signed_Word(Value))); | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		else | 
					
						
							| 
									
										
										
										
											2014-02-20 14:51:53 +00:00
										 |  |  | 			W := Object_Word(Value); | 
					
						
							|  |  |  | 		end if; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-20 14:51:53 +00:00
										 |  |  | 		H := Bigint.Get_High(W); | 
					
						
							|  |  |  | 		if H > 0 then | 
					
						
							|  |  |  | 			Size := 2; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			Size := 1; | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Ptr := Allocate_Half_Word_Object(Interp, Size); | 
					
						
							|  |  |  | 		Ptr.Tag := Bigint_Object; | 
					
						
							|  |  |  | 		Ptr.Half_Word_Slot(1) := Bigint.Get_Low(W); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if H > 0 then | 
					
						
							|  |  |  | 			Ptr.Half_Word_Slot(2) := H; | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if Value < 0 then | 
					
						
							|  |  |  | 			Ptr.Sign := Negative_Sign; | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-24 15:17:57 +00:00
										 |  |  | 		return Ptr; | 
					
						
							|  |  |  | 	end Make_Bigint; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-20 14:51:53 +00:00
										 |  |  | 	function Is_Bigint (Source: in Object_Pointer) return Standard.Boolean is | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		return Is_Normal_Pointer(Source) and then | 
					
						
							| 
									
										
										
										
											2014-02-20 14:51:53 +00:00
										 |  |  | 		       Source.Tag = Bigint_Object; | 
					
						
							|  |  |  | 	end Is_Bigint; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 	function Make_Frame (Interp:  access Interpreter_Record; | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 	                     Parent:   in     Object_Pointer; -- current stack pointer
 | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 	                     Opcode:  in     Object_Pointer; | 
					
						
							|  |  |  | 	                     Operand: in     Object_Pointer; | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 	                     Envir:   in     Object_Pointer; | 
					
						
							|  |  |  | 	                     Interm:  in     Object_Pointer) return Object_Pointer is | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 		Frame: Object_Pointer; | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 		Aliased_Parent: aliased Object_Pointer := Parent; | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 		Aliased_Opcode: aliased Object_Pointer := Opcode; | 
					
						
							|  |  |  | 		Aliased_Operand: aliased Object_Pointer := Operand; | 
					
						
							|  |  |  | 		Aliased_Envir: aliased Object_Pointer := Envir; | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 		Aliased_Interm: aliased Object_Pointer := Interm; | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 		Push_Top (Interp.all, Aliased_Parent'Unchecked_Access); | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 		Push_Top (Interp.all, Aliased_Opcode'Unchecked_Access); | 
					
						
							|  |  |  | 		Push_Top (Interp.all, Aliased_Operand'Unchecked_Access); | 
					
						
							|  |  |  | 		Push_Top (Interp.all, Aliased_Envir'Unchecked_Access); | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 		Push_Top (Interp.all, Aliased_Interm'Unchecked_Access); | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | -- TODO: create a Frame in a special memory rather than in Heap Memory.
 | 
					
						
							|  |  |  | --       Since it's used for stack, it can be made special.
 | 
					
						
							|  |  |  | 		Frame := Allocate_Pointer_Object (Interp, Frame_Object_Size, Nil_Pointer); | 
					
						
							|  |  |  | 		Frame.Tag := Frame_Object; | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 		Frame.Pointer_Slot(Frame_Parent_Index) := Aliased_Parent; | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 		Frame.Pointer_Slot(Frame_Opcode_Index) := Aliased_Opcode; | 
					
						
							|  |  |  | 		Frame.Pointer_Slot(Frame_Operand_Index) := Aliased_Operand; | 
					
						
							|  |  |  | 		Frame.Pointer_Slot(Frame_Environment_Index) := Aliased_Envir; | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 		Frame.Pointer_Slot(Frame_Intermediate_Index) := Aliased_Interm; | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 		Pop_Tops (Interp.all, 5); | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 		return Frame; | 
					
						
							|  |  |  | 	end Make_Frame; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Is_Frame (Source: in Object_Pointer) return Standard.Boolean is | 
					
						
							|  |  |  | 		pragma Inline (Is_Frame); | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		return Is_Normal_Pointer(Source) and then | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 		       Source.Tag = Frame_Object; | 
					
						
							|  |  |  | 	end Is_Frame; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 	function Get_Frame_Intermediate (Frame: in Object_Pointer) return Object_Pointer is | 
					
						
							|  |  |  | 		pragma Inline (Get_Frame_Intermediate); | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 		pragma Assert (Is_Frame(Frame)); | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 		return Frame.Pointer_Slot(Frame_Intermediate_Index); | 
					
						
							|  |  |  | 	end Get_Frame_Intermediate; | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 	procedure Set_Frame_Intermediate (Frame: in Object_Pointer; | 
					
						
							|  |  |  | 	                                  Value: in Object_Pointer) is | 
					
						
							|  |  |  | 		pragma Inline (Set_Frame_Intermediate); | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 		pragma Assert (Is_Frame(Frame)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		-- This procedure is not to set a single result,
 | 
					
						
							|  |  |  | 		-- but to set the result chain. so it can be useful
 | 
					
						
							|  |  |  | 		-- if you want to migrate a result chain from one frame
 | 
					
						
							|  |  |  | 		-- to another. It's what this assertion is for.
 | 
					
						
							| 
									
										
										
										
											2014-01-28 15:42:28 +00:00
										 |  |  | 		pragma Assert (Value = Nil_Pointer or else Is_Cons(Value)); | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 		Frame.Pointer_Slot(Frame_Intermediate_Index) := Value; | 
					
						
							|  |  |  | 	end Set_Frame_Intermediate; | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 	procedure Chain_Frame_Intermediate (Interp: in out Interpreter_Record; | 
					
						
							|  |  |  | 	                                    Frame:  in     Object_Pointer; | 
					
						
							|  |  |  | 	                                    Value:  in     Object_Pointer) is | 
					
						
							|  |  |  | 		pragma Inline (Chain_Frame_Intermediate); | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 		pragma Assert (Is_Frame(Frame)); | 
					
						
							|  |  |  | 		V: Object_Pointer; | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		-- Add a new cons cell to the front
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		--Push_Top (Interp, Frame'Unchecked_Access);
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		--Frame.Pointer_Slot(Frame_Intermediate_Index) :=
 | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 		--	Make_Cons(Interp.Self, Value, Frame.Pointer_Slot(Frame_Intermediate_Index));
 | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 		--Pop_Tops (Interp, 1);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		-- This seems to cause a problem if Interp.Stack changes in Make_Cons().
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		--Interp.Stack.Pointer_Slot(Frame_Intermediate_Index) :=
 | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 		--	Make_Cons(Interp.Self, Value, Interp.Stack.Pointer_Slot(Frame_Intermediate_Index));
 | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		-- So, let's separate the evaluation and the assignment.
 | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 		V := Make_Cons(Interp.Self, Value, Interp.Stack.Pointer_Slot(Frame_Intermediate_Index)); | 
					
						
							|  |  |  | 		Interp.Stack.Pointer_Slot(Frame_Intermediate_Index) := V; | 
					
						
							|  |  |  | 	end Chain_Frame_Intermediate; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Get_Frame_Result (Frame: in Object_Pointer) return Object_Pointer is | 
					
						
							|  |  |  | 		pragma Inline (Get_Frame_Result); | 
					
						
							|  |  |  | 		pragma Assert (Is_Frame(Frame)); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		return Frame.Pointer_Slot(Frame_Result_Index); | 
					
						
							|  |  |  | 	end Get_Frame_Result; | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 	procedure Set_Frame_Result (Frame: in Object_Pointer; | 
					
						
							|  |  |  | 	                            Value: in Object_Pointer) is | 
					
						
							|  |  |  | 		pragma Inline (Set_Frame_Result); | 
					
						
							|  |  |  | 		pragma Assert (Is_Frame(Frame)); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Frame.Pointer_Slot(Frame_Result_Index) := Value; | 
					
						
							|  |  |  | 	end Set_Frame_Result; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 	procedure Clear_Frame_Result (Frame: in Object_Pointer) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Frame.Pointer_Slot(Frame_Result_Index) := Nil_Pointer; | 
					
						
							|  |  |  | 	end Clear_Frame_Result; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Get_Frame_Environment (Frame: in Object_Pointer) return Object_Pointer is | 
					
						
							|  |  |  | 		pragma Inline (Get_Frame_Environment); | 
					
						
							|  |  |  | 		pragma Assert (Is_Frame(Frame)); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		return Frame.Pointer_Slot(Frame_Environment_Index); | 
					
						
							|  |  |  | 	end Get_Frame_Environment; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Set_Frame_Environment (Frame: in Object_Pointer; | 
					
						
							|  |  |  | 	                                 Value: in Object_Pointer) is | 
					
						
							|  |  |  | 		pragma Inline (Set_Frame_Environment); | 
					
						
							|  |  |  | 		pragma Assert (Is_Frame(Frame)); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Frame.Pointer_Slot(Frame_Environment_Index) := Value; | 
					
						
							|  |  |  | 	end Set_Frame_Environment; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Get_Frame_Opcode (Frame: in Object_Pointer) return Opcode_Type is | 
					
						
							|  |  |  | 		pragma Inline (Get_Frame_Opcode); | 
					
						
							|  |  |  | 		pragma Assert (Is_Frame(Frame)); | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-01-29 02:30:50 +00:00
										 |  |  | 		return Pointer_To_Opcode(Frame.Pointer_Slot(Frame_Opcode_Index)); | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 	end Get_Frame_Opcode; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 	procedure Set_Frame_Opcode (Frame:  in Object_Pointer; | 
					
						
							| 
									
										
										
										
											2014-01-29 02:30:50 +00:00
										 |  |  | 	                            Opcode: in Opcode_Type) is | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 		pragma Inline (Set_Frame_Opcode); | 
					
						
							|  |  |  | 		pragma Assert (Is_Frame(Frame)); | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-01-29 02:30:50 +00:00
										 |  |  | 		Frame.Pointer_Slot(Frame_Opcode_Index) := Opcode_To_Pointer(Opcode); | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 	end Set_Frame_Opcode; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Get_Frame_Operand (Frame: in Object_Pointer) return Object_Pointer is | 
					
						
							|  |  |  | 		pragma Inline (Get_Frame_Operand); | 
					
						
							|  |  |  | 		pragma Assert (Is_Frame(Frame)); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		return Frame.Pointer_Slot(Frame_Operand_Index); | 
					
						
							|  |  |  | 	end Get_Frame_Operand; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Set_Frame_Operand (Frame: in Object_Pointer; | 
					
						
							|  |  |  | 	                             Value: in Object_Pointer) is | 
					
						
							|  |  |  | 		pragma Inline (Set_Frame_Operand); | 
					
						
							|  |  |  | 		pragma Assert (Is_Frame(Frame)); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Frame.Pointer_Slot(Frame_Operand_Index) := Value; | 
					
						
							|  |  |  | 	end Set_Frame_Operand; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-26 14:58:02 +00:00
										 |  |  | 	function Get_Frame_Parent (Frame: in Object_Pointer) return Object_Pointer is | 
					
						
							|  |  |  | 		pragma Inline (Get_Frame_Parent); | 
					
						
							|  |  |  | 		pragma Assert (Is_Frame(Frame)); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		return Frame.Pointer_Slot(Frame_Parent_Index); | 
					
						
							|  |  |  | 	end Get_Frame_Parent; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 	procedure Set_Frame_Parent (Frame: in Object_Pointer; | 
					
						
							|  |  |  | 	                            Value: in Object_Pointer) is | 
					
						
							|  |  |  | 		pragma Inline (Set_Frame_Parent); | 
					
						
							|  |  |  | 		pragma Assert (Is_Frame(Frame)); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Frame.Pointer_Slot(Frame_Parent_Index) := Value; | 
					
						
							|  |  |  | 	end Set_Frame_Parent; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 	procedure Switch_Frame (Frame:   in Object_Pointer; | 
					
						
							|  |  |  | 	                        Opcode:  in Opcode_Type; | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 	                        Operand: in Object_Pointer; | 
					
						
							|  |  |  | 	                        Interm:  in Object_Pointer) is | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		Set_Frame_Opcode (Frame, Opcode); | 
					
						
							|  |  |  | 		Set_Frame_Operand (Frame, Operand); | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 		Set_Frame_Intermediate (Frame, Interm); | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 		Set_Frame_Result (Frame, Nil_Pointer); | 
					
						
							|  |  |  | 	end Switch_Frame; | 
					
						
							| 
									
										
										
										
											2014-02-05 03:21:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	--
 | 
					
						
							|  |  |  | 	-- Environment is a cons cell whose slots represents:
 | 
					
						
							|  |  |  | 	--   Car: Point to the first key/value pair.
 | 
					
						
							|  |  |  | 	--   Cdr: Point to Parent environment
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 	--
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 	-- A key/value pair is held in an array object consisting of 3 slots.
 | 
					
						
							|  |  |  | 	--   #1: Key
 | 
					
						
							|  |  |  | 	--   #2: Value
 | 
					
						
							|  |  |  | 	--   #3: Link to the next key/value array.
 | 
					
						
							|  |  |  | 	--
 | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 	-- Frame.Environment     Interp.Root_Environment
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  |      --   |                      |
 | 
					
						
							|  |  |  | 	--   |                      V
 | 
					
						
							|  |  |  | 	--   |     +----+----+    +----+----+
 | 
					
						
							|  |  |  | 	--   +---> | |  |   ----> | |  | Nil|
 | 
					
						
							|  |  |  | 	--         +-|--+-----    +-|--+-----
 | 
					
						
							|  |  |  | 	--           |              |
 | 
					
						
							|  |  |  | 	--           |              +--> another list
 | 
					
						
							|  |  |  | 	--           V
 | 
					
						
							|  |  |  | 	--         +----+----+----+   +----+----+----+   +----+----+----+   +----+----+----+
 | 
					
						
							|  |  |  | 	--   list: | |  | |  |  ----> | |  | |  | -----> | |  | |  | -----> | |  | |  | Nil|
 | 
					
						
							|  |  |  | 	--         +-|--+-|-------+   +-|--+-|-------+   +-|--+-|-------+   +-|--+-|-------+
 | 
					
						
							|  |  |  | 	--           |    |             |    |             |    |             |    |
 | 
					
						
							|  |  |  | 	--           V    V             V    V             V    V             V    V
 | 
					
						
							|  |  |  | 	--          Key  Value          Key  Value        Key  Value         Key  Value
 | 
					
						
							|  |  |  | 	--
 | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 	-- Upon initialization, Root_Frame.Environment is equal to Interp.Root_Environment.
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 	-- CDR(Interp.Root_Environment) is Nil_Pointer.
 | 
					
						
							|  |  |  | 	--
 | 
					
						
							|  |  |  | 	-- TODO: Change environment implementation to a hash table or something similar
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Make_Environment (Interp: access Interpreter_Record; | 
					
						
							|  |  |  | 	                           Parent: in     Object_Pointer) return Object_Pointer is | 
					
						
							|  |  |  | 		pragma Inline (Make_Environment); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		return Make_Cons(Interp, Nil_Pointer, Parent); | 
					
						
							|  |  |  | 	end Make_Environment; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Find_In_Environment_List (Interp: access Interpreter_Record; | 
					
						
							|  |  |  | 	                                   List:   in     Object_Pointer; | 
					
						
							|  |  |  | 	                                   Key:    in     Object_Pointer) return Object_Pointer is | 
					
						
							|  |  |  | 		Arr: Object_Pointer; | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Arr := List; | 
					
						
							|  |  |  | 		while Arr /= Nil_Pointer loop | 
					
						
							|  |  |  | 			pragma Assert (Is_Array(Arr)); | 
					
						
							|  |  |  | 			pragma Assert (Arr.Size = 3); | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 			if Arr.Pointer_Slot(1) = Key then | 
					
						
							|  |  |  | 				return Arr; | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 			end if; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 			Arr := Arr.Pointer_Slot(3); | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		end loop; | 
					
						
							|  |  |  | 		return null; -- not found.
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 	end Find_In_Environment_List; | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-22 15:01:58 +00:00
										 |  |  | 	function Get_Environment (Interp: access Interpreter_Record; | 
					
						
							|  |  |  | 	                          Key:    in     Object_Pointer) return Object_Pointer is | 
					
						
							|  |  |  | 		Envir: Object_Pointer; | 
					
						
							|  |  |  | 		Arr: Object_Pointer; | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		pragma Assert (Is_Symbol(Key)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 		Envir := Get_Frame_Environment(Interp.Stack); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-22 15:01:58 +00:00
										 |  |  | 		while Envir /= Nil_Pointer loop | 
					
						
							|  |  |  | 			pragma Assert (Is_Cons(Envir)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Arr := Find_In_Environment_List(Interp, Get_Car(Envir), Key); | 
					
						
							|  |  |  | 			if Arr /= null then | 
					
						
							|  |  |  | 				return Arr.Pointer_Slot(2); | 
					
						
							|  |  |  | 			end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			-- Move on to the parent environment
 | 
					
						
							|  |  |  | 			Envir := Get_Cdr(Envir); | 
					
						
							|  |  |  | 		end loop; | 
					
						
							|  |  |  | 		return null; -- not found
 | 
					
						
							|  |  |  | 	end Get_Environment; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Set_Environment (Interp: access Interpreter_Record; | 
					
						
							|  |  |  | 	                          Key:    in     Object_Pointer; | 
					
						
							|  |  |  | 	                          Value:  in     Object_Pointer) return Object_Pointer is | 
					
						
							|  |  |  | 		Envir: Object_Pointer; | 
					
						
							|  |  |  | 		Arr: Object_Pointer; | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-02-09 15:28:46 +00:00
										 |  |  | 		-- Search the whole environment chain unlike Set_Current_Environment().
 | 
					
						
							| 
									
										
										
										
											2014-01-22 15:01:58 +00:00
										 |  |  | 		-- It is mainly for set!.
 | 
					
						
							|  |  |  | 		pragma Assert (Is_Symbol(Key)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 		Envir := Get_Frame_Environment(Interp.Stack); | 
					
						
							| 
									
										
										
										
											2014-01-22 15:01:58 +00:00
										 |  |  | 		while Envir /= Nil_Pointer loop | 
					
						
							|  |  |  | 			pragma Assert (Is_Cons(Envir)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Arr := Find_In_Environment_List(Interp, Get_Car(Envir), Key); | 
					
						
							|  |  |  | 			if Arr /= null then | 
					
						
							|  |  |  | 				-- Overwrite an existing pair
 | 
					
						
							|  |  |  | 				Arr.Pointer_Slot(2) := Value; | 
					
						
							|  |  |  | 				return Value; | 
					
						
							|  |  |  | 			end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			-- Move on to the parent environment
 | 
					
						
							|  |  |  | 			Envir := Get_Cdr(Envir); | 
					
						
							|  |  |  | 		end loop; | 
					
						
							|  |  |  | 		return null; -- not found. not set
 | 
					
						
							|  |  |  | 	end Set_Environment; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-20 15:47:08 +00:00
										 |  |  | 	procedure Put_Environment (Interp: in out Interpreter_Record; | 
					
						
							| 
									
										
										
										
											2014-02-09 15:28:46 +00:00
										 |  |  | 	                           Envir:  in     Object_Pointer; | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 	                           Key:    in     Object_Pointer; | 
					
						
							|  |  |  | 	                           Value:  in     Object_Pointer) is | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 		Arr: Object_Pointer; | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		-- Search the current environment only. It doesn't search the
 | 
					
						
							| 
									
										
										
										
											2014-01-22 15:01:58 +00:00
										 |  |  | 		-- environment. If no key is found, add a new pair
 | 
					
						
							|  |  |  | 		-- This is mainly for define.
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 		pragma Assert (Is_Symbol(Key)); | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 		pragma Assert (Is_Cons(Envir)); | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 		Arr := Find_In_Environment_List(Interp.Self, Get_Car(Envir), Key); | 
					
						
							| 
									
										
										
										
											2014-01-22 15:01:58 +00:00
										 |  |  | 		if Arr /= null then | 
					
						
							|  |  |  | 			-- Found. Update the existing one
 | 
					
						
							|  |  |  | 			Arr.Pointer_Slot(2) := Value; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			-- Add a new key/value pair in the current environment
 | 
					
						
							|  |  |  | 			-- if no existing pair has been found.
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 			declare | 
					
						
							| 
									
										
										
										
											2014-02-09 15:28:46 +00:00
										 |  |  | 				Aliased_Envir: aliased Object_Pointer := Envir; | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 				Aliased_Key: aliased Object_Pointer := Key; | 
					
						
							|  |  |  | 				Aliased_Value: aliased Object_Pointer := Value; | 
					
						
							|  |  |  | 			begin | 
					
						
							| 
									
										
										
										
											2014-02-09 15:28:46 +00:00
										 |  |  | 				Push_Top (Interp, Aliased_Envir'Unchecked_Access); | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 				Push_Top (Interp, Aliased_Key'Unchecked_Access); | 
					
						
							|  |  |  | 				Push_Top (Interp, Aliased_Value'Unchecked_Access); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				Arr := Make_Array(Interp.Self, 3); | 
					
						
							|  |  |  | 				Arr.Pointer_Slot(1) := Aliased_Key; | 
					
						
							|  |  |  | 				Arr.Pointer_Slot(2) := Aliased_Value; | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 				-- Chain the pair to the head of the list
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 				Arr.Pointer_Slot(3) := Get_Car(Aliased_Envir); | 
					
						
							| 
									
										
										
										
											2014-02-09 15:28:46 +00:00
										 |  |  | 				Set_Car (Aliased_Envir, Arr); | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 				Pop_Tops (Interp, 3); | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 			end; | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 		end if; | 
					
						
							| 
									
										
										
										
											2014-01-20 15:47:08 +00:00
										 |  |  | 	end Put_Environment; | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 15:28:46 +00:00
										 |  |  | 	procedure Set_Current_Environment (Interp: in out Interpreter_Record; | 
					
						
							|  |  |  | 	                                   Key:    in     Object_Pointer; | 
					
						
							|  |  |  | 	                                   Value:  in     Object_Pointer) is | 
					
						
							|  |  |  | 		pragma Inline (Set_Current_Environment); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Put_Environment (Interp, Get_Frame_Environment(Interp.Stack), Key, Value); | 
					
						
							|  |  |  | 	end Set_Current_Environment; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Set_Parent_Environment (Interp: in out Interpreter_Record; | 
					
						
							|  |  |  | 	                                   Key:    in     Object_Pointer; | 
					
						
							|  |  |  | 	                                   Value:  in     Object_Pointer) is | 
					
						
							|  |  |  | 		pragma Inline (Set_Parent_Environment); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Put_Environment (Interp, Get_Frame_Environment(Get_Frame_Parent(Interp.Stack)), Key, Value); | 
					
						
							|  |  |  | 	end Set_Parent_Environment; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	function Make_Syntax (Interp: access Interpreter_Record; | 
					
						
							|  |  |  | 	                      Opcode: in     Syntax_Code; | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 	                      Name:   in     Object_Character_Array) return Object_Pointer is | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 		Result: Object_Pointer; | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-01-21 05:08:46 +00:00
										 |  |  | 		Result := Make_Symbol(Interp, Name); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		Result.Flags := Result.Flags or Syntax_Object; | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 		Result.Scode := Opcode; | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | --Ada.Text_IO.Put ("Creating Syntax Symbol ");
 | 
					
						
							| 
									
										
										
										
											2014-01-11 03:38:02 +00:00
										 |  |  | --Put_String (To_Thin_Object_String_Pointer (Result));
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 		return Result; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	end Make_Syntax; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-18 14:58:46 +00:00
										 |  |  | 	function Is_Syntax (Source: in Object_Pointer) return Standard.Boolean is | 
					
						
							|  |  |  | 		pragma Inline (Is_Syntax); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		return Is_Symbol(Source) and then (Source.Flags and Syntax_Object) /= 0; | 
					
						
							|  |  |  | 	end Is_Syntax; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 	function Make_Procedure (Interp: access Interpreter_Record; | 
					
						
							| 
									
										
										
										
											2014-02-10 08:33:18 +00:00
										 |  |  | 	                         Code:   in     Procedure_Code; | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 	                         Name:   in     Object_Character_Array) return Object_Pointer is | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 		-- this procedure is for internal use only
 | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 		Symbol: aliased Object_Pointer; | 
					
						
							|  |  |  | 		Proc:   aliased Object_Pointer; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 		Push_Top (Interp.all, Symbol'Unchecked_Access); | 
					
						
							|  |  |  | 		Push_Top (Interp.all, Proc'Unchecked_Access); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 		-- Make a symbol for the procedure
 | 
					
						
							| 
									
										
										
										
											2014-01-21 05:08:46 +00:00
										 |  |  | 		Symbol := Make_Symbol(Interp, Name); | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		-- Make the actual procedure object
 | 
					
						
							| 
									
										
										
										
											2014-01-21 05:08:46 +00:00
										 |  |  | 		Proc := Allocate_Pointer_Object(Interp, Procedure_Object_Size, Nil_Pointer); | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 		Proc.Tag := Procedure_Object; | 
					
						
							| 
									
										
										
										
											2014-02-10 08:33:18 +00:00
										 |  |  | 		Proc.Pointer_Slot(Procedure_Opcode_Index) := Procedure_Code_To_Pointer(Code); | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		-- Link it to the top environement
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		pragma Assert (Get_Frame_Environment(Interp.Stack) = Interp.Root_Environment); | 
					
						
							| 
									
										
										
										
											2014-01-21 05:08:46 +00:00
										 |  |  | 		pragma Assert (Get_Environment(Interp.Self, Symbol) = null); | 
					
						
							| 
									
										
										
										
											2014-02-09 15:28:46 +00:00
										 |  |  | 		Set_Current_Environment (Interp.all, Symbol, Proc); | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 		Pop_Tops (Interp.all, 2); | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 		return Proc; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	end Make_Procedure; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-18 14:58:46 +00:00
										 |  |  | 	function Is_Procedure (Source: in Object_Pointer) return Standard.Boolean is | 
					
						
							|  |  |  | 		pragma Inline (Is_Procedure); | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		return Is_Normal_Pointer(Source) and then | 
					
						
							| 
									
										
										
										
											2013-12-18 14:58:46 +00:00
										 |  |  | 		       Source.Tag = Procedure_Object; | 
					
						
							|  |  |  | 	end Is_Procedure; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Get_Procedure_Opcode (Proc: in Object_Pointer) return Procedure_Code is | 
					
						
							|  |  |  | 		pragma Inline (Get_Procedure_Opcode); | 
					
						
							|  |  |  | 		pragma Assert (Is_Procedure(Proc)); | 
					
						
							|  |  |  | 		pragma Assert (Proc.Size = Procedure_Object_Size); | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-02-10 08:33:18 +00:00
										 |  |  | 		return Pointer_To_Procedure_Code(Proc.Pointer_Slot(Procedure_Opcode_Index)); | 
					
						
							| 
									
										
										
										
											2013-12-18 14:58:46 +00:00
										 |  |  | 	end Get_Procedure_Opcode; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 	function Make_Closure (Interp: access Interpreter_Record; | 
					
						
							|  |  |  | 	                       Code:   in     Object_Pointer; | 
					
						
							|  |  |  | 	                       Envir:  in     Object_Pointer) return Object_Pointer is | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 		Closure: Object_Pointer; | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 		Aliased_Code: aliased Object_Pointer := Code; | 
					
						
							|  |  |  | 		Aliased_Envir: aliased Object_Pointer := Envir; | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 		Push_Top (Interp.all, Aliased_Code'Unchecked_Access); | 
					
						
							|  |  |  | 		Push_Top (Interp.all, Aliased_Envir'Unchecked_Access); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 		Closure := Allocate_Pointer_Object (Interp, Closure_Object_Size, Nil_Pointer); | 
					
						
							|  |  |  | 		Closure.Tag := Closure_Object; | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 		Closure.Pointer_Slot(Closure_Code_Index) := Aliased_Code; | 
					
						
							|  |  |  | 		Closure.Pointer_Slot(Closure_Environment_Index) := Aliased_Envir; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Pop_Tops (Interp.all, 2); | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 		return Closure; | 
					
						
							|  |  |  | 	end Make_Closure; | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-18 14:58:46 +00:00
										 |  |  | 	function Is_Closure (Source: in Object_Pointer) return Standard.Boolean is | 
					
						
							|  |  |  | 		pragma Inline (Is_Closure); | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		return Is_Normal_Pointer(Source) and then | 
					
						
							| 
									
										
										
										
											2013-12-18 14:58:46 +00:00
										 |  |  | 		       Source.Tag = Closure_Object; | 
					
						
							|  |  |  | 	end Is_Closure; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Get_Closure_Code (Closure: in Object_Pointer) return Object_Pointer is | 
					
						
							|  |  |  | 		pragma Inline (Get_Closure_Code); | 
					
						
							|  |  |  | 		pragma Assert (Is_Closure(Closure)); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		return Closure.Pointer_Slot(Closure_Code_Index); | 
					
						
							|  |  |  | 	end Get_Closure_Code; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Get_Closure_Environment (Closure: in Object_Pointer) return Object_Pointer is | 
					
						
							|  |  |  | 		pragma Inline (Get_Closure_Environment); | 
					
						
							|  |  |  | 		pragma Assert (Is_Closure(Closure)); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		return Closure.Pointer_Slot(Closure_Environment_Index); | 
					
						
							|  |  |  | 	end Get_Closure_Environment; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-26 16:15:28 +00:00
										 |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 	function Make_Continuation (Interp: access Interpreter_Record; | 
					
						
							| 
									
										
										
										
											2014-02-01 15:59:36 +00:00
										 |  |  | 	                            Frame:  in     Object_Pointer) return Object_Pointer is | 
					
						
							| 
									
										
										
										
											2014-01-26 16:15:28 +00:00
										 |  |  | 		Cont: Object_Pointer; | 
					
						
							|  |  |  | 		Aliased_Frame: aliased Object_Pointer := Frame; | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Push_Top (Interp.all, Aliased_Frame'Unchecked_Access); | 
					
						
							| 
									
										
										
										
											2014-01-28 15:42:28 +00:00
										 |  |  | 		Cont := Allocate_Pointer_Object (Interp, Continuation_Object_Size, Nil_Pointer); | 
					
						
							| 
									
										
										
										
											2014-01-26 16:15:28 +00:00
										 |  |  | 		Cont.Tag := Continuation_Object; | 
					
						
							|  |  |  | 		Cont.Pointer_Slot(Continuation_Frame_Index) := Aliased_Frame; | 
					
						
							|  |  |  | 		Pop_Tops (Interp.all, 1); | 
					
						
							|  |  |  | 		return Cont; | 
					
						
							|  |  |  | 	end Make_Continuation; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Is_Continuation (Source: in Object_Pointer) return Standard.Boolean is | 
					
						
							|  |  |  | 		pragma Inline (Is_Continuation); | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		return Is_Normal_Pointer(Source) and then | 
					
						
							| 
									
										
										
										
											2014-01-26 16:15:28 +00:00
										 |  |  | 		       Source.Tag = Continuation_Object; | 
					
						
							|  |  |  | 	end Is_Continuation; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function Get_Continuation_Frame (Cont: in Object_Pointer) return Object_Pointer is | 
					
						
							|  |  |  | 		pragma Inline (Get_Continuation_Frame); | 
					
						
							|  |  |  | 		pragma Assert (Is_Continuation(Cont)); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		return Cont.Pointer_Slot(Continuation_Frame_Index); | 
					
						
							|  |  |  | 	end Get_Continuation_Frame; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	procedure Deinitialize_Heap (Interp: in out Interpreter_Record) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		for I in Interp.Heap'Range loop | 
					
						
							|  |  |  | 			if Interp.Heap(I) /= null then | 
					
						
							|  |  |  | 				declare | 
					
						
							|  |  |  | 					subtype Target_Heap_Record is Heap_Record (Interp.Heap(I).Size); | 
					
						
							|  |  |  | 					type Target_Heap_Pointer is access all Target_Heap_Record; | 
					
						
							|  |  |  | 					package Pool is new H2.Pool (Target_Heap_Record, Target_Heap_Pointer, Interp.Storage_Pool); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					Heap: Target_Heap_Pointer; | 
					
						
							|  |  |  | 					for Heap'Address use Interp.Heap(I)'Address; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 					pragma Import (Ada, Heap); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 				begin | 
					
						
							|  |  |  | 					Pool.Deallocate (Heap); | 
					
						
							|  |  |  | 				end; | 
					
						
							|  |  |  | 			end if; | 
					
						
							|  |  |  | 		end loop; | 
					
						
							|  |  |  | 	end Deinitialize_Heap; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-01 14:07:03 +00:00
										 |  |  | 	procedure Close_Stream (Stream: in out Stream_Pointer) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Close (Stream.all); | 
					
						
							|  |  |  | 		Stream := null; | 
					
						
							|  |  |  | 	exception | 
					
						
							|  |  |  | 		when others => | 
					
						
							|  |  |  | 			Stream := null; -- ignore exception
 | 
					
						
							|  |  |  | 	end Close_Stream; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Start_Named_Input_Stream (Interp: in out Interpreter_Record; | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 	                                    Name:   access Object_Character_Array) is | 
					
						
							| 
									
										
										
										
											2014-01-01 14:07:03 +00:00
										 |  |  | 		package IO_Pool is new H2.Pool (IO_Record, IO_Pointer, Interp.Storage_Pool); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		IO: IO_Pointer := null; | 
					
						
							|  |  |  | 		Stream: Stream_Pointer := null; | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		begin | 
					
						
							|  |  |  | 			IO := IO_Pool.Allocate; | 
					
						
							|  |  |  | 			Interp.Stream.Allocate (Interp, Name, Stream); | 
					
						
							|  |  |  | 		exception | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 			when others => | 
					
						
							| 
									
										
										
										
											2014-01-01 14:07:03 +00:00
										 |  |  | 				if IO /= null then | 
					
						
							|  |  |  | 					if Stream /= null then | 
					
						
							|  |  |  | 						Interp.Stream.Deallocate (Interp, Stream); | 
					
						
							|  |  |  | 					end if; | 
					
						
							|  |  |  | 					IO_Pool.Deallocate (IO); | 
					
						
							|  |  |  | 				end if; | 
					
						
							|  |  |  | 				raise; | 
					
						
							|  |  |  | 		end; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		--IO.Stream := Stream;
 | 
					
						
							|  |  |  | 		--IO.Pos := IO.Data'First - 1;
 | 
					
						
							|  |  |  | 		--IO.Last := IO.Data'First - 1;
 | 
					
						
							|  |  |  | 		--IO.Flags := 0;
 | 
					
						
							|  |  |  | 		--IO.Next := Interp.Input;
 | 
					
						
							|  |  |  | 		--Interp.Input := IO;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		IO.all := IO_Record'( | 
					
						
							|  |  |  | 			Stream => Stream, | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | 			Data => (others => Object_Character'First), | 
					
						
							| 
									
										
										
										
											2014-01-01 14:07:03 +00:00
										 |  |  | 			Pos | Last => IO.Data'First - 1, | 
					
						
							|  |  |  | 			Flags => 0, | 
					
						
							|  |  |  | 			Next => Interp.Input, | 
					
						
							|  |  |  | 			Iochar => IO_Character_Record'(End_Character, Object_Character'First) | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 		Interp.Input := IO; | 
					
						
							|  |  |  | 	end Start_Named_Input_Stream; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Stop_Named_Input_Stream (Interp: in out Interpreter_Record) is | 
					
						
							|  |  |  | 		package IO_Pool is new H2.Pool (IO_Record, IO_Pointer, Interp.Storage_Pool); | 
					
						
							|  |  |  | 		IO: IO_Pointer; | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		pragma Assert (Interp.Input /= Interp.Base_Input'Unchecked_Access); | 
					
						
							|  |  |  | 		IO := Interp.Input; | 
					
						
							|  |  |  | 		Interp.Input := IO.Next; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		pragma Assert (IO.Stream /= null); | 
					
						
							|  |  |  | 		Close_Stream (IO.Stream); | 
					
						
							|  |  |  | 		Interp.Stream.Deallocate (Interp, IO.Stream); | 
					
						
							|  |  |  | 		IO_Pool.Deallocate (IO); | 
					
						
							|  |  |  | 	end Stop_Named_Input_Stream; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	procedure Open (Interp:            in out Interpreter_Record; | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 	                Initial_Heap_Size: in     Heap_Size; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	                Storage_Pool:      in     Storage_Pool_Pointer := null) is | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 		procedure Initialize_Heap (Size: Heap_Size) is | 
					
						
							| 
									
										
										
										
											2021-08-21 14:31:39 +00:00
										 |  |  | 			subtype Target_Heap_Record is Heap_Record(Size); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 			type Target_Heap_Pointer is access all Target_Heap_Record; | 
					
						
							| 
									
										
										
										
											2021-08-21 14:31:39 +00:00
										 |  |  | 			package Pool is new H2.Pool(Target_Heap_Record, Target_Heap_Pointer, Interp.Storage_Pool); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		begin | 
					
						
							|  |  |  | 			for I in Interp.Heap'Range loop | 
					
						
							|  |  |  | 				Interp.Heap(I) := null; -- just in case
 | 
					
						
							|  |  |  | 			end loop; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			for I in Interp.Heap'Range loop | 
					
						
							|  |  |  | 				declare | 
					
						
							|  |  |  | 					Heap: Target_Heap_Pointer; | 
					
						
							|  |  |  | 					for Heap'Address use Interp.Heap(I)'Address; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 					pragma Import (Ada, Heap); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 				begin | 
					
						
							|  |  |  | 					Heap := Pool.Allocate; | 
					
						
							|  |  |  | 				end; | 
					
						
							|  |  |  | 			end loop; | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		exception | 
					
						
							|  |  |  | 			when others => | 
					
						
							|  |  |  | 				Deinitialize_Heap (Interp); | 
					
						
							|  |  |  | 				raise; | 
					
						
							|  |  |  | 		end Initialize_Heap; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		procedure Make_Syntax_Objects is | 
					
						
							|  |  |  | 			Dummy: Object_Pointer; | 
					
						
							|  |  |  | 		begin | 
					
						
							| 
									
										
										
										
											2021-08-21 14:31:39 +00:00
										 |  |  | 			Dummy := Make_Syntax(Interp.Self, And_Syntax,    Label_And); -- "and"
 | 
					
						
							|  |  |  | 			Dummy := Make_Syntax(Interp.Self, Begin_Syntax,  Label_Begin); -- "begin"
 | 
					
						
							|  |  |  | 			Dummy := Make_Syntax(Interp.Self, Case_Syntax,   Label_Case); -- "case"
 | 
					
						
							|  |  |  | 			Dummy := Make_Syntax(Interp.Self, Cond_Syntax,   Label_Cond); -- "cond"
 | 
					
						
							|  |  |  | 			Dummy := Make_Syntax(Interp.Self, Define_Syntax, Label_Define); -- "define"
 | 
					
						
							|  |  |  | 			Dummy := Make_Syntax(Interp.Self, Do_Syntax,     Label_Do); -- "do"
 | 
					
						
							|  |  |  | 			Dummy := Make_Syntax(Interp.Self, If_Syntax,     Label_If); -- "if"
 | 
					
						
							|  |  |  | 			Dummy := Make_Syntax(Interp.Self, Lambda_Syntax, Label_Lambda); -- "lamba"
 | 
					
						
							|  |  |  | 			Dummy := Make_Syntax(Interp.Self, Let_Syntax,    Label_Let); -- "let"
 | 
					
						
							|  |  |  | 			Dummy := Make_Syntax(Interp.Self, Letast_Syntax, Label_Letast); -- "let*"
 | 
					
						
							|  |  |  | 			Dummy := Make_Syntax(Interp.Self, Letrec_Syntax, Label_Letrec); -- "letrec"
 | 
					
						
							|  |  |  | 			Dummy := Make_Syntax(Interp.Self, Or_Syntax,     Label_Or); -- "or"
 | 
					
						
							|  |  |  | 			Interp.Quote_Symbol := Make_Syntax(Interp.Self, Quote_Syntax,  Label_Quote); -- "quote"
 | 
					
						
							|  |  |  | 			Interp.Quasiquote_Symbol := Make_Syntax(Interp.Self, Quasiquote_Syntax,  Label_Quasiquote); -- "quasiquote"
 | 
					
						
							|  |  |  | 			Dummy := Make_Syntax(Interp.Self, Set_Syntax,    Label_Set); -- "set!"
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		end Make_Syntax_Objects; | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		procedure Make_Procedure_Objects is | 
					
						
							|  |  |  | 			Dummy: Object_Pointer; | 
					
						
							|  |  |  | 		begin | 
					
						
							| 
									
										
										
										
											2014-02-15 03:41:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-21 14:31:39 +00:00
										 |  |  | 			Dummy := Make_Procedure(Interp.Self, Callcc_Procedure,       Label_Callcc); -- "call-with-current-continuation"
 | 
					
						
							|  |  |  | 			Dummy := Make_Procedure(Interp.Self, Car_Procedure,          Label_Car); -- "car"
 | 
					
						
							|  |  |  | 			Dummy := Make_Procedure(Interp.Self, Cdr_Procedure,          Label_Cdr); -- "cdr"
 | 
					
						
							|  |  |  | 			Dummy := Make_Procedure(Interp.Self, Cons_Procedure,         Label_Cons); -- "cons"
 | 
					
						
							|  |  |  | 			Dummy := Make_Procedure(Interp.Self, Not_Procedure,          Label_Not); -- "not"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Dummy := Make_Procedure(Interp.Self, N_Add_Procedure,        Label_N_Add); -- "+"
 | 
					
						
							|  |  |  | 			Dummy := Make_Procedure(Interp.Self, N_EQ_Procedure,         Label_N_EQ); -- "="
 | 
					
						
							|  |  |  | 			Dummy := Make_Procedure(Interp.Self, N_GE_Procedure,         Label_N_GE); -- ">="
 | 
					
						
							|  |  |  | 			Dummy := Make_Procedure(Interp.Self, N_GT_Procedure,         Label_N_GT); -- ">"
 | 
					
						
							|  |  |  | 			Dummy := Make_Procedure(Interp.Self, N_LE_Procedure,         Label_N_LE); -- "<="
 | 
					
						
							|  |  |  | 			Dummy := Make_Procedure(Interp.Self, N_LT_Procedure,         Label_N_LT); -- "<"
 | 
					
						
							|  |  |  | 			Dummy := Make_Procedure(Interp.Self, N_Multiply_Procedure,   Label_N_Multiply); -- "*"
 | 
					
						
							|  |  |  | 			Dummy := Make_Procedure(Interp.Self, N_Quotient_Procedure,   Label_N_Quotient); -- "quotient"
 | 
					
						
							|  |  |  | 			Dummy := Make_Procedure(Interp.Self, N_Remainder_Procedure,  Label_N_Remainder); -- "remainder"
 | 
					
						
							|  |  |  | 			Dummy := Make_Procedure(Interp.Self, N_Subtract_Procedure,   Label_N_Subtract); -- "-"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Dummy := Make_Procedure(Interp.Self, Q_Boolean_Procedure,    Label_Q_Boolean); -- "boolean?"
 | 
					
						
							|  |  |  | 			Dummy := Make_Procedure(Interp.Self, Q_Eq_Procedure,         Label_Q_Eq); -- "eq?"
 | 
					
						
							|  |  |  | 			Dummy := Make_Procedure(Interp.Self, Q_Eqv_Procedure,        Label_Q_Eqv); -- "eqv?"
 | 
					
						
							|  |  |  | 			Dummy := Make_Procedure(Interp.Self, Q_Null_Procedure,       Label_Q_Null); -- "null?"
 | 
					
						
							|  |  |  | 			Dummy := Make_Procedure(Interp.Self, Q_Number_Procedure,     Label_Q_Number); -- "number?"
 | 
					
						
							|  |  |  | 			Dummy := Make_Procedure(Interp.Self, Q_Pair_Procedure,       Label_Q_Pair); -- "pair?"
 | 
					
						
							|  |  |  | 			Dummy := Make_Procedure(Interp.Self, Q_Procedure_Procedure,  Label_Q_Procedure); -- "procedure?"
 | 
					
						
							|  |  |  | 			Dummy := Make_Procedure(Interp.Self, Q_String_Procedure,     Label_Q_String); -- "string?"
 | 
					
						
							|  |  |  | 			Dummy := Make_Procedure(Interp.Self, Q_String_EQ_Procedure,  Label_Q_String_EQ); -- "string=?"
 | 
					
						
							|  |  |  | 			Dummy := Make_Procedure(Interp.Self, Q_Symbol_Procedure,     Label_Q_Symbol); -- "symbol?"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Dummy := Make_Procedure(Interp.Self, Setcar_Procedure,       Label_Setcar); -- "set-car!"
 | 
					
						
							|  |  |  | 			Dummy := Make_Procedure(Interp.Self, Setcdr_Procedure,       Label_Setcdr); -- "set-cdr!"
 | 
					
						
							| 
									
										
										
										
											2014-02-15 03:41:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 		end Make_Procedure_Objects; | 
					
						
							| 
									
										
										
										
											2014-01-20 14:34:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		procedure Make_Common_Symbol_Objects is | 
					
						
							|  |  |  | 		begin | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 			Interp.Arrow_Symbol := Make_Symbol(Interp.Self, Label_Arrow); | 
					
						
							|  |  |  | 			Interp.Else_Symbol := Make_Symbol(Interp.Self, Label_Else); | 
					
						
							| 
									
										
										
										
											2014-01-20 14:34:55 +00:00
										 |  |  | 		end Make_Common_Symbol_Objects; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-03-09 18:01:38 +00:00
										 |  |  | 		-- Initialize child packages in case library-level initialization
 | 
					
						
							|  |  |  | 		-- has been skipped for various reasons.
 | 
					
						
							|  |  |  | 		Bigint.Initialize; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-11 15:40:57 +00:00
										 |  |  | 		declare | 
					
						
							|  |  |  | 			Aliased_Interp: aliased Interpreter_Record; | 
					
						
							|  |  |  | 			for Aliased_Interp'Address use Interp'Address; | 
					
						
							|  |  |  | 			pragma Import (Ada, Aliased_Interp); | 
					
						
							|  |  |  | 		begin | 
					
						
							|  |  |  | 			-- Store a pointer to the interpreter record itself.
 | 
					
						
							|  |  |  | 			-- I use this pointer to call functions that accept the "access"
 | 
					
						
							|  |  |  | 			-- type to work around the ada95 limitation of no "in out" as
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 			-- a function parameter. Accoring to Ada95 RM (6.2), both a
 | 
					
						
							| 
									
										
										
										
											2013-12-11 15:40:57 +00:00
										 |  |  | 			-- non-private limited record type and a private type whose
 | 
					
						
							|  |  |  | 			-- full type is a by-reference type are by-rereference types.
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 			-- So i assume that it's safe to create this aliased overlay
 | 
					
						
							| 
									
										
										
										
											2013-12-11 15:40:57 +00:00
										 |  |  | 			-- to deceive the compiler. If Interpreter_Record is a tagged
 | 
					
						
							|  |  |  | 			-- limited record type, this overlay is not needed since the
 | 
					
						
							|  |  |  | 			-- type is considered aliased. Having this overlay, however,
 | 
					
						
							|  |  |  | 			-- should be safe for both "tagged" and "non-tagged".
 | 
					
						
							|  |  |  | 			-- Note: Making it a tagged limit record caused gnat 3.4.6 to
 | 
					
						
							|  |  |  | 			--       crash with an internal bug report.
 | 
					
						
							|  |  |  | 			--Interp.Self := Interp'Unchecked_Access; -- if tagged limited
 | 
					
						
							|  |  |  | 			Interp.Self := Aliased_Interp'Unchecked_Access; | 
					
						
							|  |  |  | 		end; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-11 09:35:44 +00:00
										 |  |  | 		Interp.State := 0; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		Interp.Storage_Pool := Storage_Pool; | 
					
						
							|  |  |  | 		Interp.Symbol_Table := Nil_Pointer; | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-01 14:07:03 +00:00
										 |  |  | 		Interp.Base_Input.Stream := null; | 
					
						
							|  |  |  | 		Interp.Input := Interp.Base_Input'Unchecked_Access; | 
					
						
							| 
									
										
										
										
											2014-01-02 16:28:18 +00:00
										 |  |  | 		Interp.Token := (End_Token, (null, 0, 0)); | 
					
						
							| 
									
										
										
										
											2014-02-07 09:04:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-15 09:21:26 +00:00
										 |  |  | 		Interp.Top := (Interp.Top.Data'First - 1, (others => null)); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | -- TODO: disallow garbage collecion during initialization.
 | 
					
						
							|  |  |  | 		Initialize_Heap (Initial_Heap_Size); | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 		Interp.Root_Environment := Make_Environment(Interp.Self, Nil_Pointer); | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 		Interp.Root_Frame := Make_Frame(Interp.Self, Nil_Pointer, Opcode_To_Pointer(Opcode_Exit), Nil_Pointer, Interp.Root_Environment, Nil_Pointer); | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 		Interp.Stack := Interp.Root_Frame; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		Make_Syntax_Objects; | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 		Make_Procedure_Objects; | 
					
						
							| 
									
										
										
										
											2014-01-20 14:34:55 +00:00
										 |  |  | 		Make_Common_Symbol_Objects; | 
					
						
							| 
									
										
										
										
											2013-12-18 14:58:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	exception | 
					
						
							|  |  |  | 		when others => | 
					
						
							|  |  |  | 			Deinitialize_Heap (Interp); | 
					
						
							|  |  |  | 	end Open; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-01 14:07:03 +00:00
										 |  |  | 	procedure Close (Interp: in out Interpreter_Record) is | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		-- Destroy all unstacked named input streams
 | 
					
						
							| 
									
										
										
										
											2014-01-01 14:07:03 +00:00
										 |  |  | 		while Interp.Input /= Interp.Base_Input'Unchecked_Access loop | 
					
						
							|  |  |  | 			Stop_Named_Input_Stream (Interp); | 
					
						
							|  |  |  | 		end loop; | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-01 14:07:03 +00:00
										 |  |  | 		if Interp.Base_Input.Stream /= null then | 
					
						
							|  |  |  | 			-- Close the main input stream.
 | 
					
						
							|  |  |  | 			Close_Stream (Interp.Base_Input.Stream); | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 		end if; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		Deinitialize_Heap (Interp); | 
					
						
							| 
									
										
										
										
											2014-01-04 06:31:14 +00:00
										 |  |  | 		Token.Purge (Interp); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	end Close; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 	function Get_Storage_Pool (Interp: in Interpreter_Record) return Storage_Pool_Pointer is | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		return Interp.Storage_Pool; | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 	end Get_Storage_Pool; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	procedure Set_Option (Interp: in out Interpreter_Record; | 
					
						
							|  |  |  | 	                      Option: in     Option_Record) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		case Option.Kind  is | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 			when Trait_Option => | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 				Interp.Trait := Option; | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 			when Stream_Option => | 
					
						
							|  |  |  | 				Interp.Stream := Option; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		end case; | 
					
						
							|  |  |  | 	end Set_Option; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Get_Option (Interp: in out Interpreter_Record; | 
					
						
							|  |  |  | 	                      Option: in out Option_Record) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		case Option.Kind  is | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 			when Trait_Option => | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 				Option := Interp.Trait; | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 			when Stream_Option => | 
					
						
							|  |  |  | 				Option := Interp.Stream; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		end case; | 
					
						
							|  |  |  | 	end Get_Option; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 	procedure Set_Input_Stream  (Interp: in out Interpreter_Record; | 
					
						
							|  |  |  | 	                             Stream: in out Stream_Record'Class) is | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		--Open (Stream, Interp);
 | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 		Open (Stream); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		-- if Open raised an exception, it wouldn't reach here.
 | 
					
						
							|  |  |  | 		-- so the existing stream still remains intact.
 | 
					
						
							| 
									
										
										
										
											2014-01-01 14:07:03 +00:00
										 |  |  | 		if Interp.Base_Input.Stream /= null then | 
					
						
							|  |  |  | 			Close_Stream (Interp.Base_Input.Stream); | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 		end if; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-01 14:07:03 +00:00
										 |  |  | 		Interp.Base_Input := IO_Record'( | 
					
						
							|  |  |  | 			Stream => Stream'Unchecked_Access, | 
					
						
							|  |  |  | 			Data => (others => Object_Character'First), | 
					
						
							|  |  |  | 			Pos | Last => Interp.Base_Input.Data'First - 1, | 
					
						
							|  |  |  | 			Flags => 0, | 
					
						
							|  |  |  | 			Next => null, | 
					
						
							|  |  |  | 			Iochar => IO_Character_Record'(End_Character, Object_Character'First) | 
					
						
							|  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 	end Set_Input_Stream; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	--procedure Set_Output_Stream (Interp: in out Interpreter_Record;
 | 
					
						
							|  |  |  | 	--                             Stream: in out Stream_Record'Class) is
 | 
					
						
							|  |  |  | 	--begin
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 	--
 | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 	--end Set_Output_Stream;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 	procedure Print (Interp: in out Interpreter_Record; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	                 Source: in     Object_Pointer) is | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		procedure Print_Atom (Atom: in Object_Pointer) is | 
					
						
							|  |  |  | 			Ptr_Type: Object_Pointer_Type; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			procedure Print_Pointee is | 
					
						
							|  |  |  | 				W: Object_Word; | 
					
						
							|  |  |  | 				for W'Address use Atom'Address; | 
					
						
							|  |  |  | 			begin | 
					
						
							|  |  |  | 				case W is | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 				when Nil_Word => | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | 					Ada.Text_IO.Put ("()"); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 				when True_Word => | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | 					Ada.Text_IO.Put ("#t"); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 				when False_Word => | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | 					Ada.Text_IO.Put ("#f"); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 				when others => | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 					case Atom.Tag is | 
					
						
							| 
									
										
										
										
											2014-01-10 14:54:46 +00:00
										 |  |  | 						when Cons_Object => | 
					
						
							|  |  |  | 							-- Cons_Object must not reach here.
 | 
					
						
							|  |  |  | 							raise Internal_Error; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-10 14:54:46 +00:00
										 |  |  | 						when Symbol_Object => | 
					
						
							|  |  |  | 							Output_Character_Array (Atom.Character_Slot); | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-10 14:54:46 +00:00
										 |  |  | 						when String_Object => | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 							Ada.Text_IO.Put (""""); | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | 							Output_Character_Array (Atom.Character_Slot); | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 							Ada.Text_IO.Put (""""); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-10 14:54:46 +00:00
										 |  |  | 						when Closure_Object => | 
					
						
							|  |  |  | 							Ada.Text_IO.Put ("#Closure"); | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-10 14:54:46 +00:00
										 |  |  | 						when Continuation_Object => | 
					
						
							| 
									
										
										
										
											2014-01-28 15:42:28 +00:00
										 |  |  | 							declare | 
					
						
							|  |  |  | 								w: object_word; | 
					
						
							|  |  |  | 								for w'address use Atom'address; | 
					
						
							|  |  |  | 							begin | 
					
						
							|  |  |  | 								Ada.Text_IO.Put ("#Continuation[" & object_word'image(w) & "]"); | 
					
						
							|  |  |  | 							end; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-10 14:54:46 +00:00
										 |  |  | 						when Procedure_Object => | 
					
						
							|  |  |  | 							Ada.Text_IO.Put ("#Procedure"); | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-10 14:54:46 +00:00
										 |  |  | 						when Array_Object => | 
					
						
							|  |  |  | 							Ada.Text_IO.Put ("#Array"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 						when Bigint_Object => | 
					
						
							| 
									
										
										
										
											2014-02-24 15:17:57 +00:00
										 |  |  | 							Ada.Text_IO.Put ("#Bigint("); | 
					
						
							|  |  |  | declare | 
					
						
							|  |  |  | package Int_IO is new ada.text_io.modular_IO(object_half_word); | 
					
						
							|  |  |  | begin | 
					
						
							|  |  |  | if Atom.Sign = Negative_Sign then | 
					
						
							|  |  |  | ada.text_io.put ("-"); | 
					
						
							|  |  |  | else | 
					
						
							|  |  |  | ada.text_io.put ("+"); | 
					
						
							|  |  |  | end if; | 
					
						
							|  |  |  | for I in reverse Atom.Half_Word_Slot'Range loop | 
					
						
							|  |  |  | ada.text_io.put (" "); | 
					
						
							|  |  |  | int_io.put (Atom.Half_Word_Slot(I), base=>16); | 
					
						
							|  |  |  | end loop; | 
					
						
							|  |  |  | end; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							Ada.Text_IO.Put(")"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-10 14:54:46 +00:00
										 |  |  | 						when Others => | 
					
						
							|  |  |  | 							if Atom.Kind = Character_Object then | 
					
						
							|  |  |  | 								Output_Character_Array (Atom.Character_Slot); | 
					
						
							|  |  |  | 							else | 
					
						
							| 
									
										
										
										
											2014-01-28 15:42:28 +00:00
										 |  |  | 								Ada.Text_IO.Put ("#NOIMPL# => " & Object_Tag'Image(Atom.Tag)); | 
					
						
							| 
									
										
										
										
											2014-01-10 14:54:46 +00:00
										 |  |  | 							end if; | 
					
						
							|  |  |  | 						end case; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 				end case; | 
					
						
							|  |  |  | 			end Print_Pointee; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			procedure Print_Integer is | 
					
						
							|  |  |  | 				 X: constant Object_Integer := Pointer_To_Integer (Atom); | 
					
						
							|  |  |  | 			begin | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | 				Ada.Text_IO.Put (Object_Integer'Image(X)); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 			end Print_Integer; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			procedure Print_Character is | 
					
						
							|  |  |  | 				 X: constant Object_Character := Pointer_To_Character (Atom); | 
					
						
							|  |  |  | 			begin | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | 				Ada.Text_IO.Put (Object_Character'Image(X)); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 			end Print_Character; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			procedure Print_Byte is | 
					
						
							|  |  |  | 				 X: constant Object_Byte := Pointer_To_Byte (Atom); | 
					
						
							|  |  |  | 			begin | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | 				Ada.Text_IO.Put (Object_Byte'Image(X)); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 			end Print_Byte; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		begin | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 			Ptr_Type := Get_Pointer_Type(Atom); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 			case Ptr_Type is | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 			when Object_Pointer_Type_Pointer => | 
					
						
							|  |  |  | 				Print_Pointee; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 			when Object_Pointer_Type_Integer => | 
					
						
							|  |  |  | 				Print_Integer; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 			when Object_Pointer_Type_Character => | 
					
						
							|  |  |  | 				Print_Character; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 			when Object_Pointer_Type_Byte => | 
					
						
							|  |  |  | 				Print_Byte; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 			end case; | 
					
						
							|  |  |  | 		end Print_Atom; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		procedure Print_Object (Obj: in Object_Pointer) is | 
					
						
							|  |  |  | 			Cons: Object_Pointer; | 
					
						
							|  |  |  | 			Car: Object_Pointer; | 
					
						
							|  |  |  | 			Cdr: Object_Pointer; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		begin | 
					
						
							| 
									
										
										
										
											2014-01-26 16:15:28 +00:00
										 |  |  | 			if Is_Cons(Obj) then | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 				Cons := Obj; | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | 				Ada.Text_IO.Put ("("); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				loop | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 					Car := Get_Car(Cons); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 17:20:59 +00:00
										 |  |  | 					if Is_Cons(Car)  or else Is_Array(Car) then | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 						Print_Object (Car); | 
					
						
							|  |  |  | 					else | 
					
						
							|  |  |  | 						Print_Atom (Car); | 
					
						
							|  |  |  | 					end if; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 					Cdr := Get_Cdr(Cons); | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | 					if Is_Cons(Cdr) then | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | 						Ada.Text_IO.Put (" "); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 						Cons := Cdr; | 
					
						
							|  |  |  | 						exit when Cons = Nil_Pointer; | 
					
						
							|  |  |  | 					else | 
					
						
							|  |  |  | 						if Cdr /= Nil_Pointer then | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | 							Ada.Text_IO.Put (" . "); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 							Print_Atom (Cdr); | 
					
						
							|  |  |  | 						end if; | 
					
						
							|  |  |  | 						exit; | 
					
						
							|  |  |  | 					end if; | 
					
						
							|  |  |  | 				end loop; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | 				Ada.Text_IO.Put (")"); | 
					
						
							| 
									
										
										
										
											2014-02-09 17:20:59 +00:00
										 |  |  | 			elsif Is_Array(Obj) then | 
					
						
							|  |  |  | 				Ada.Text_IO.Put (" #("); | 
					
						
							|  |  |  | 				for X in Obj.Pointer_Slot'Range loop | 
					
						
							|  |  |  | 					if Is_Cons(Obj.Pointer_Slot(X)) or else Is_Array(Obj.Pointer_Slot(X)) then | 
					
						
							|  |  |  | 						Print_Object (Obj.Pointer_Slot(X)); | 
					
						
							|  |  |  | 					else | 
					
						
							|  |  |  | 						Print_Atom (Obj.Pointer_Slot(X)); | 
					
						
							|  |  |  | 					end if; | 
					
						
							|  |  |  | 				end loop; | 
					
						
							|  |  |  | 				Ada.Text_IO.Put (") "); | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 			else | 
					
						
							|  |  |  | 				Print_Atom (Obj); | 
					
						
							|  |  |  | 			end if; | 
					
						
							|  |  |  | 		end Print_Object; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 		Stack: Object_Pointer; -- TODO: make it into the interpreter_Record so that GC can workd
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		Opcode: Object_Integer; | 
					
						
							|  |  |  | 		Operand: Object_Pointer; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | if DEBUG_GC then | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | Print_Object (Source); -- use a recursive version
 | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | Ada.Text_IO.New_Line; | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | return; | 
					
						
							|  |  |  | end if; | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		-- TODO: Let Make_Frame use a dedicated stack space that's apart from the heap.
 | 
					
						
							|  |  |  | 		--       This way, the stack frame doesn't have to be managed by GC.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-19 13:54:47 +00:00
										 |  |  | -- TODO: use a interp.Stack.
 | 
					
						
							|  |  |  | -- TODO: use Push_Frame
 | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 		Stack := Make_Frame (Interp.Self, Nil_Pointer, Integer_To_Pointer(0), Nil_Pointer, Nil_Pointer, Nil_Pointer);  -- just for get_frame_environment...
 | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 		Opcode := 1; | 
					
						
							|  |  |  | 		Operand := Source; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		loop | 
					
						
							|  |  |  | 			case Opcode is | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 				when 1 => | 
					
						
							|  |  |  | 					if Is_Cons(Operand) then | 
					
						
							|  |  |  | 						-- push cdr
 | 
					
						
							|  |  |  | 						Stack := Make_Frame (Interp.Self, Stack, Integer_To_Pointer(2), Get_Cdr(Operand), Nil_Pointer, Nil_Pointer); -- push cdr
 | 
					
						
							|  |  |  | 						Ada.Text_IO.Put ("("); | 
					
						
							|  |  |  | 						Operand := Get_Car(Operand); | 
					
						
							|  |  |  | 						Opcode := 1; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 					else | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 						Print_Atom (Operand); | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 						if Stack = Nil_Pointer then | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 							Opcode := 0; -- stack empty. arrange to exit
 | 
					
						
							|  |  |  | 							Operand := True_Pointer; -- return value
 | 
					
						
							|  |  |  | 						else | 
					
						
							|  |  |  | 							Opcode := Pointer_To_Integer(Stack.Pointer_Slot(Frame_Opcode_Index)); | 
					
						
							|  |  |  | 							Operand := Stack.Pointer_Slot(Frame_Operand_Index); | 
					
						
							|  |  |  | 							Stack := Stack.Pointer_Slot(Frame_Parent_Index); -- pop
 | 
					
						
							|  |  |  | 						end if; | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 					end if; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 				when 2 => | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 					if Is_Cons(Operand) then | 
					
						
							|  |  |  | 						-- push cdr
 | 
					
						
							|  |  |  | 						Stack := Make_Frame (Interp.Self, Stack, Integer_To_Pointer(2), Get_Cdr(Operand), Nil_Pointer, Nil_Pointer); -- push
 | 
					
						
							|  |  |  | 						Ada.Text_IO.Put (" "); | 
					
						
							|  |  |  | 						Operand := Get_Car(Operand); -- car
 | 
					
						
							|  |  |  | 						Opcode := 1; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 					else | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 						if Operand /= Nil_Pointer then | 
					
						
							|  |  |  | 							-- cdr of the last cons cell is not null.
 | 
					
						
							|  |  |  | 							Ada.Text_IO.Put (" . "); | 
					
						
							|  |  |  | 							Print_Atom (Operand); | 
					
						
							|  |  |  | 						end if; | 
					
						
							|  |  |  | 						Ada.Text_IO.Put (")"); | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 						if Stack = Nil_Pointer then | 
					
						
							|  |  |  | 							Opcode := 0; -- stack empty. arrange to exit
 | 
					
						
							|  |  |  | 						else | 
					
						
							|  |  |  | 							Opcode := Pointer_To_Integer(Stack.Pointer_Slot(Frame_Opcode_Index)); | 
					
						
							|  |  |  | 							Operand := Stack.Pointer_Slot(Frame_Operand_Index); | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 							Stack := Stack.Pointer_Slot(Frame_Parent_Index); -- pop
 | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 						end if; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 					end if; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 				when others => | 
					
						
							|  |  |  | 					exit; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 			end case; | 
					
						
							|  |  |  | 		end loop; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | 		Ada.Text_IO.New_Line; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 	end Print; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 	function Insert_Frame (Interp:  access Interpreter_Record; | 
					
						
							|  |  |  | 	                       Parent:  in     Object_Pointer; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 	                       Opcode:  in     Opcode_Type; | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 	                       Operand: in     Object_Pointer; | 
					
						
							|  |  |  | 	                       Envir:   in     Object_Pointer; | 
					
						
							|  |  |  | 	                       Interm:  in     Object_Pointer) return Object_Pointer is | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 		pragma Inline (Insert_Frame); | 
					
						
							|  |  |  | 		pragma Assert (Parent = Nil_Pointer or else Is_Frame(Parent)); | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 		return Make_Frame(Interp, Parent, Opcode_To_Pointer(Opcode), Operand, Envir, Interm); | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 	end Insert_Frame; | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-07 17:02:12 +00:00
										 |  |  | 	procedure Push_Frame (Interp:  in out Interpreter_Record; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 	                      Opcode:  in     Opcode_Type; | 
					
						
							| 
									
										
										
										
											2014-01-07 17:02:12 +00:00
										 |  |  | 	                      Operand: in     Object_Pointer) is | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | 		pragma Inline (Push_Frame); | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-02-07 05:22:41 +00:00
										 |  |  | 		Interp.Stack := Insert_Frame(Interp.Self, Interp.Stack, Opcode, Operand, Get_Frame_Environment(Interp.Stack), Nil_Pointer); | 
					
						
							| 
									
										
										
										
											2014-01-07 17:02:12 +00:00
										 |  |  | 	end Push_Frame; | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-26 14:58:02 +00:00
										 |  |  | 	procedure Push_Frame_With_Environment (Interp:  in out Interpreter_Record; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 	                                       Opcode:  in     Opcode_Type; | 
					
						
							| 
									
										
										
										
											2014-01-26 14:58:02 +00:00
										 |  |  | 	                                       Operand: in     Object_Pointer; | 
					
						
							|  |  |  | 	                                       Envir:   in     Object_Pointer) is | 
					
						
							|  |  |  | 		pragma Inline (Push_Frame_With_Environment); | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 		Interp.Stack := Insert_Frame(Interp.Self, Interp.Stack, Opcode, Operand, Envir, Nil_Pointer); | 
					
						
							| 
									
										
										
										
											2014-01-26 14:58:02 +00:00
										 |  |  | 	end Push_Frame_With_Environment; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 15:28:46 +00:00
										 |  |  | 	procedure Push_Frame_With_Environment_And_Intermediate (Interp:  in out Interpreter_Record; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 	                                                        Opcode:  in     Opcode_Type; | 
					
						
							| 
									
										
										
										
											2014-02-09 15:28:46 +00:00
										 |  |  | 	                                                        Operand: in     Object_Pointer; | 
					
						
							|  |  |  | 	                                                        Envir:   in     Object_Pointer; | 
					
						
							|  |  |  | 	                                                        Interm:  in     Object_Pointer) is | 
					
						
							|  |  |  | 		pragma Inline (Push_Frame_With_Environment_And_Intermediate); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Interp.Stack := Insert_Frame(Interp.Self, Interp.Stack, Opcode, Operand, Envir, Interm); | 
					
						
							|  |  |  | 	end Push_Frame_With_Environment_And_Intermediate; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 	procedure Push_Frame_With_Intermediate (Interp:  in out Interpreter_Record; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 	                                        Opcode:  in     Opcode_Type; | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 	                                        Operand: in     Object_Pointer; | 
					
						
							|  |  |  | 	                                        Interm:  in     Object_Pointer) is | 
					
						
							|  |  |  | 		pragma Inline (Push_Frame_With_Intermediate); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		-- Place a new frame below the existing top frame.
 | 
					
						
							|  |  |  | 		Interp.Stack := Insert_Frame (Interp.Self, Interp.Stack, Opcode, Operand, Get_Frame_Environment(Interp.Stack), Interm); | 
					
						
							|  |  |  | 	end Push_Frame_With_Intermediate; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 	procedure Push_Subframe (Interp:  in out Interpreter_Record; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 	                         Opcode:  in     Opcode_Type; | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 	                         Operand: in     Object_Pointer) is | 
					
						
							|  |  |  | 		pragma Inline (Push_Subframe); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		-- Place a new frame below the existing top frame.
 | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 		Set_Frame_Parent (Interp.Stack, Insert_Frame(Interp.Self, Get_Frame_Parent(Interp.Stack), Opcode, Operand, Get_Frame_Environment(Interp.Stack), Nil_Pointer)); | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 	end Push_Subframe; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Push_Subframe_With_Environment (Interp:  in out Interpreter_Record; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 	                                          Opcode:  in     Opcode_Type; | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 	                                          Operand: in     Object_Pointer; | 
					
						
							|  |  |  | 	                                          Envir:   in     Object_Pointer) is | 
					
						
							|  |  |  | 		pragma Inline (Push_Subframe_With_Environment); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		-- Place a new frame below the existing top frame.
 | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 		Set_Frame_Parent (Interp.Stack, Insert_Frame(Interp.Self, Get_Frame_Parent(Interp.Stack), Opcode, Operand, Envir, Nil_Pointer)); | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 	end Push_Subframe_With_Environment; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Push_Subframe_With_Intermediate (Interp:  in out Interpreter_Record; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 	                                           Opcode:  in     Opcode_Type; | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 	                                           Operand: in     Object_Pointer; | 
					
						
							|  |  |  | 	                                           Interm:  in     Object_Pointer) is | 
					
						
							|  |  |  | 		pragma Inline (Push_Subframe_With_Intermediate); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		-- Place a new frame below the existing top frame.
 | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 		Set_Frame_Parent (Interp.Stack, Insert_Frame(Interp.Self, Get_Frame_Parent(Interp.Stack), Opcode, Operand, Get_Frame_Environment(Interp.Stack), Interm)); | 
					
						
							| 
									
										
										
										
											2014-02-05 15:08:59 +00:00
										 |  |  | 	end Push_Subframe_With_Intermediate; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 15:28:46 +00:00
										 |  |  | 	procedure Push_Subframe_With_Environment_And_Intermediate (Interp:  in out Interpreter_Record; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 	                                                           Opcode:  in     Opcode_Type; | 
					
						
							| 
									
										
										
										
											2014-02-09 15:28:46 +00:00
										 |  |  | 	                                                           Operand: in     Object_Pointer; | 
					
						
							|  |  |  | 	                                                           Envir:   in     Object_Pointer; | 
					
						
							|  |  |  | 	                                                           Interm:  in     Object_Pointer) is | 
					
						
							|  |  |  | 		pragma Inline (Push_Subframe_With_Environment_And_Intermediate); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		-- Place a new frame below the existing top frame.
 | 
					
						
							|  |  |  | 		Set_Frame_Parent (Interp.Stack, Insert_Frame(Interp.Self, Get_Frame_Parent(Interp.Stack), Opcode, Operand, Envir, Interm)); | 
					
						
							|  |  |  | 	end Push_Subframe_With_Environment_And_Intermediate; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-07 17:02:12 +00:00
										 |  |  | 	procedure Pop_Frame (Interp: in out Interpreter_Record) is | 
					
						
							| 
									
										
										
										
											2014-01-17 13:03:05 +00:00
										 |  |  | 		pragma Inline (Pop_Frame); | 
					
						
							| 
									
										
										
										
											2014-01-07 17:02:12 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-01-24 13:57:06 +00:00
										 |  |  | 		pragma Assert (Interp.Stack /= Interp.Root_Frame); | 
					
						
							| 
									
										
										
										
											2014-01-07 17:02:12 +00:00
										 |  |  | 		pragma Assert (Interp.Stack /= Nil_Pointer); | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		Interp.Stack := Interp.Stack.Pointer_Slot(Frame_Parent_Index); -- pop
 | 
					
						
							| 
									
										
										
										
											2014-01-07 17:02:12 +00:00
										 |  |  | 	end Pop_Frame; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 	procedure Return_Frame (Interp: in out Interpreter_Record; | 
					
						
							|  |  |  | 	                        Value:  in     Object_Pointer) is | 
					
						
							|  |  |  | 		pragma Inline (Return_Frame); | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		-- Remove the current frame and return a value
 | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 		-- to a new active(top) frame.
 | 
					
						
							|  |  |  | 		Pop_Frame (Interp); | 
					
						
							|  |  |  | 		Set_Frame_Result (Interp.Stack, Value); | 
					
						
							|  |  |  | 	end Return_Frame; | 
					
						
							| 
									
										
										
										
											2014-02-09 15:28:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	procedure Reload_Frame (Interp:  in out Interpreter_Record; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 	                        Opcode:  in     Opcode_Type; | 
					
						
							| 
									
										
										
										
											2014-02-09 15:28:46 +00:00
										 |  |  | 	                        Operand: in     Object_Pointer) is | 
					
						
							|  |  |  | 		pragma Inline (Reload_Frame); | 
					
						
							|  |  |  | 		Envir: Object_Pointer; | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		-- Change various frame fields keeping the environment.
 | 
					
						
							| 
									
										
										
										
											2014-02-09 17:20:59 +00:00
										 |  |  | 		Envir := Get_Frame_Environment(Interp.Stack); | 
					
						
							| 
									
										
										
										
											2014-02-09 15:28:46 +00:00
										 |  |  | 		Pop_Frame (Interp); | 
					
						
							|  |  |  | 		Push_Frame_With_Environment (Interp, Opcode, Operand, Envir); | 
					
						
							|  |  |  | 	end Reload_Frame; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 17:20:59 +00:00
										 |  |  | 	procedure Reload_Frame_With_Environment (Interp:  in out Interpreter_Record; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 	                                         Opcode:  in     Opcode_Type; | 
					
						
							| 
									
										
										
										
											2014-02-09 17:20:59 +00:00
										 |  |  | 	                                         Operand: in     Object_Pointer; | 
					
						
							|  |  |  | 	                                         Envir:   in     Object_Pointer) is | 
					
						
							|  |  |  | 		pragma Inline (Reload_Frame_With_Environment); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		-- Change various frame fields
 | 
					
						
							|  |  |  | 		Pop_Frame (Interp); | 
					
						
							|  |  |  | 		Push_Frame_With_Environment (Interp, Opcode, Operand, Envir); | 
					
						
							|  |  |  | 	end Reload_Frame_With_Environment; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 15:28:46 +00:00
										 |  |  | 	procedure Reload_Frame_With_Intermediate (Interp:  in out Interpreter_Record; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 	                                          Opcode:  in     Opcode_Type; | 
					
						
							| 
									
										
										
										
											2014-02-09 15:28:46 +00:00
										 |  |  | 	                                          Operand: in     Object_Pointer; | 
					
						
							|  |  |  | 	                                          Interm:  in     Object_Pointer) is | 
					
						
							|  |  |  | 		pragma Inline (Reload_Frame_With_Intermediate); | 
					
						
							|  |  |  | 		Envir: Object_Pointer; | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		-- Change various frame fields keeping the environment.
 | 
					
						
							| 
									
										
										
										
											2014-02-09 17:20:59 +00:00
										 |  |  | 		Envir := Get_Frame_Environment(Interp.Stack); | 
					
						
							| 
									
										
										
										
											2014-02-09 15:28:46 +00:00
										 |  |  | 		Pop_Frame (Interp); | 
					
						
							|  |  |  | 		Push_Frame_With_Environment_And_Intermediate (Interp, Opcode, Operand, Envir, Interm); | 
					
						
							|  |  |  | 	end Reload_Frame_With_Intermediate; | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 	procedure Execute (Interp: in out Interpreter_Record) is separate; | 
					
						
							| 
									
										
										
										
											2014-01-10 08:12:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-07 17:02:12 +00:00
										 |  |  | 	procedure Evaluate (Interp: in out Interpreter_Record; | 
					
						
							|  |  |  | 	                    Source: in     Object_Pointer; | 
					
						
							|  |  |  | 	                    Result: out    Object_Pointer) is | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-01-24 13:57:06 +00:00
										 |  |  | 		Result := Nil_Pointer; | 
					
						
							| 
									
										
										
										
											2014-01-07 17:02:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-24 13:57:06 +00:00
										 |  |  | 		-- Perform some clean ups in case the procedure is called
 | 
					
						
							|  |  |  | 		-- again after an exception is raised
 | 
					
						
							|  |  |  | 		Clear_Tops (Interp); | 
					
						
							|  |  |  | 		Interp.Stack := Interp.Root_Frame; | 
					
						
							|  |  |  | 		Clear_Frame_Result (Interp.Stack); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		-- Push an actual frame for evaluation
 | 
					
						
							| 
									
										
										
										
											2014-01-07 17:02:12 +00:00
										 |  |  | 		Push_Frame (Interp, Opcode_Evaluate_Object, Source); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Execute (Interp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-24 13:57:06 +00:00
										 |  |  | 		pragma Assert (Interp.Stack = Interp.Root_Frame); | 
					
						
							| 
									
										
										
										
											2014-01-07 17:02:12 +00:00
										 |  |  | 		pragma Assert (Get_Frame_Opcode(Interp.Stack) = Opcode_Exit); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-24 13:57:06 +00:00
										 |  |  | 		Result := Get_Frame_Result(Interp.Stack); | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 		Clear_Frame_Result (Interp.Stack); | 
					
						
							| 
									
										
										
										
											2013-12-17 16:04:55 +00:00
										 |  |  | 	end Evaluate; | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 	procedure Run_Loop (Interp: in out Interpreter_Record; | 
					
						
							| 
									
										
										
										
											2014-01-07 17:02:12 +00:00
										 |  |  | 	                    Result: out    Object_Pointer) is | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 		-- standard read-eval-print loop
 | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 		Aliased_Result: aliased Object_Pointer; | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-01-14 14:22:06 +00:00
										 |  |  | 		pragma Assert (Interp.Base_Input.Stream /= null); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | DEBUG_GC := Standard.True; | 
					
						
							| 
									
										
										
										
											2014-01-24 13:57:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-07 17:02:12 +00:00
										 |  |  | 		Result := Nil_Pointer; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-24 13:57:06 +00:00
										 |  |  | 		-- Perform some clean ups in case the procedure is called
 | 
					
						
							|  |  |  | 		-- again after an exception is raised
 | 
					
						
							|  |  |  | 		Clear_Tops (Interp); | 
					
						
							|  |  |  | 		Interp.Stack := Interp.Root_Frame; | 
					
						
							|  |  |  | 		Clear_Frame_Result (Interp.Stack); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 		Push_Top (Interp, Aliased_Result'Unchecked_Access); | 
					
						
							| 
									
										
										
										
											2014-01-07 17:02:12 +00:00
										 |  |  | 		loop | 
					
						
							| 
									
										
										
										
											2014-01-24 12:48:58 +00:00
										 |  |  | 			pragma Assert (Interp.Stack = Interp.Root_Frame); | 
					
						
							|  |  |  | 			pragma Assert (Get_Frame_Result(Interp.Stack) = Nil_Pointer); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-08 14:59:48 +00:00
										 |  |  | 			--Push_Frame (Interp, Opcode_Print_Result, Nil_Pointer);
 | 
					
						
							|  |  |  | 			Push_Frame (Interp, Opcode_Evaluate_Result, Nil_Pointer); | 
					
						
							| 
									
										
										
										
											2014-01-07 17:02:12 +00:00
										 |  |  | 			Push_Frame (Interp, Opcode_Read_Object, Nil_Pointer); | 
					
						
							|  |  |  | 			Execute (Interp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-24 13:57:06 +00:00
										 |  |  | 			pragma Assert (Interp.Stack = Interp.Root_Frame); | 
					
						
							| 
									
										
										
										
											2014-01-07 17:02:12 +00:00
										 |  |  | 			pragma Assert (Get_Frame_Opcode(Interp.Stack) = Opcode_Exit); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 			Aliased_Result := Get_Frame_Result(Interp.Stack); | 
					
						
							| 
									
										
										
										
											2014-01-24 13:57:06 +00:00
										 |  |  | 			Clear_Frame_Result (Interp.Stack); | 
					
						
							| 
									
										
										
										
											2014-01-07 17:02:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | Ada.Text_IO.Put ("RESULT: "); | 
					
						
							|  |  |  | Print (Interp, Aliased_Result); | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | Ada.Text_IO.Put_Line (">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> LOOP ITERATION XXXXXX CHECKPOINT"); | 
					
						
							| 
									
										
										
										
											2014-01-07 17:02:12 +00:00
										 |  |  | 		end loop; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-20 14:51:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 		-- Jump into the exception handler not to repeat the same code here.
 | 
					
						
							|  |  |  | 		-- In fact, this part must not be reached since the loop above can't
 | 
					
						
							|  |  |  | 		-- be broken.
 | 
					
						
							|  |  |  | 		raise Stream_End_Error; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-07 17:02:12 +00:00
										 |  |  | 	exception | 
					
						
							|  |  |  | 		when Stream_End_Error => | 
					
						
							|  |  |  | 			-- this is not a real error. this indicates the end of input stream.
 | 
					
						
							| 
									
										
										
										
											2014-02-21 16:08:43 +00:00
										 |  |  | declare | 
					
						
							| 
									
										
										
										
											2014-03-25 16:43:46 +00:00
										 |  |  | q: object_Pointer; | 
					
						
							|  |  |  | begin | 
					
						
							| 
									
										
										
										
											2014-03-26 07:43:34 +00:00
										 |  |  | q := bigint.from_string (interp.self, String_To_Object_Character_Array("20000000000000000000000000000000000000000"), 10); | 
					
						
							|  |  |  | --q := bigint.from_string (interp.self, String_To_Object_Character_Array("20000000000"), 10);
 | 
					
						
							| 
									
										
										
										
											2014-03-25 16:43:46 +00:00
										 |  |  | q := bigint.to_string (interp.self, q, 10); | 
					
						
							|  |  |  | print (interp, q); | 
					
						
							|  |  |  | end; | 
					
						
							|  |  |  | 			goto SKIP; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-25 16:43:46 +00:00
										 |  |  | declare | 
					
						
							| 
									
										
										
										
											2014-02-21 16:08:43 +00:00
										 |  |  | A: aliased Object_Pointer; | 
					
						
							|  |  |  | B: aliased Object_Pointer; | 
					
						
							|  |  |  | begin | 
					
						
							|  |  |  | Push_Top (Interp, A'Unchecked_Access); | 
					
						
							|  |  |  | Push_Top (Interp, B'Unchecked_Access); | 
					
						
							| 
									
										
										
										
											2014-03-04 14:32:49 +00:00
										 |  |  | --A := Make_Bigint(Interp.Self, Value => 16#0FFFFFFF_FFFFFFFF#);
 | 
					
						
							|  |  |  | --B := Make_Bigint(Interp.Self, Value => 16#0FFFFFFF_FFFFFFFF#);
 | 
					
						
							| 
									
										
										
										
											2014-02-21 16:08:43 +00:00
										 |  |  | --for I in 1 .. 11 loop
 | 
					
						
							| 
									
										
										
										
											2014-03-04 14:32:49 +00:00
										 |  |  | --A := Bigint.Add(Interp.Self, A, B);
 | 
					
						
							| 
									
										
										
										
											2014-02-21 16:08:43 +00:00
										 |  |  | --end loop;
 | 
					
						
							| 
									
										
										
										
											2014-03-07 17:58:01 +00:00
										 |  |  | A := Make_Bigint(Interp.Self, Value => Object_Integer'Last - 16#FFFF#); | 
					
						
							| 
									
										
										
										
											2014-03-04 14:32:49 +00:00
										 |  |  | --B := Make_Bigint(Interp.Self, Value => 16#FFFF_0000000F#);
 | 
					
						
							| 
									
										
										
										
											2014-03-07 17:58:01 +00:00
										 |  |  | B := Make_Bigint(Interp.Self, Value => Object_Integer'Last); | 
					
						
							| 
									
										
										
										
											2014-02-24 15:17:57 +00:00
										 |  |  | B.sign := Negative_Sign; | 
					
						
							| 
									
										
										
										
											2014-02-25 16:10:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | A := Make_Bigint(Interp.Self, Size => 30); | 
					
						
							| 
									
										
										
										
											2014-03-09 18:01:38 +00:00
										 |  |  | A.Half_Word_Slot(30) := Object_Half_Word'Last; | 
					
						
							| 
									
										
										
										
											2014-03-04 14:32:49 +00:00
										 |  |  | Bigint.Multiply(Interp, A, integer_to_pointer(2), A); | 
					
						
							|  |  |  | Bigint.Add(Interp, A, A, A); | 
					
						
							| 
									
										
										
										
											2014-02-25 16:10:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-04 14:32:49 +00:00
										 |  |  | B := Make_Bigint(Interp.Self, Size => 4); | 
					
						
							| 
									
										
										
										
											2014-03-07 17:58:01 +00:00
										 |  |  | B.Half_Word_Slot(4) := Object_Half_Word'Last / 2; | 
					
						
							| 
									
										
										
										
											2014-03-09 18:01:38 +00:00
										 |  |  | Bigint.Subtract(Interp, integer_to_pointer(1), B, B); | 
					
						
							| 
									
										
										
										
											2014-03-04 14:32:49 +00:00
										 |  |  | --A := Bigint.Divide(Interp, A, integer_to_pointer(0));
 | 
					
						
							| 
									
										
										
										
											2014-03-03 15:36:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-09 18:01:38 +00:00
										 |  |  | ada.text_io.put ("A => "); print (interp, A); | 
					
						
							|  |  |  | ada.text_io.put ("B => "); print (interp, B); | 
					
						
							| 
									
										
										
										
											2014-03-03 15:36:03 +00:00
										 |  |  | declare | 
					
						
							|  |  |  | q, r: object_Pointer; | 
					
						
							|  |  |  | begin | 
					
						
							| 
									
										
										
										
											2014-03-04 14:32:49 +00:00
										 |  |  | 	--Bigint.Divide (Interp, integer_to_pointer(-10), integer_to_pointer(6), Q, R);
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-04 14:32:49 +00:00
										 |  |  | 	Bigint.Divide (Interp, A, B, Q, R); | 
					
						
							|  |  |  | ada.text_io.put ("Q => "); print (interp, Q); | 
					
						
							|  |  |  | ada.text_io.put ("R => "); print (interp, R); | 
					
						
							| 
									
										
										
										
											2014-03-05 18:06:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-25 16:43:46 +00:00
										 |  |  | r := bigint.to_string (interp.self, Q, 16); | 
					
						
							|  |  |  | --r := bigint.to_string (interp.self, integer_to_pointer(-2), 10);
 | 
					
						
							| 
									
										
										
										
											2014-03-07 17:58:01 +00:00
										 |  |  | print (interp, r); | 
					
						
							| 
									
										
										
										
											2014-03-05 18:06:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-03 15:36:03 +00:00
										 |  |  | end; | 
					
						
							| 
									
										
										
										
											2014-02-21 16:08:43 +00:00
										 |  |  | Pop_tops (Interp, 2); | 
					
						
							| 
									
										
										
										
											2014-03-09 18:01:38 +00:00
										 |  |  | end; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-25 16:43:46 +00:00
										 |  |  | declare | 
					
						
							|  |  |  | a: object_pointer; | 
					
						
							|  |  |  | b: object_pointer; | 
					
						
							|  |  |  | begin | 
					
						
							|  |  |  | a := Make_Bigint (Interp.Self, Size => 3); | 
					
						
							|  |  |  | b := Make_Bigint (Interp.Self, Size => 1); | 
					
						
							|  |  |  | a.half_word_slot(1) := Object_Half_Word'Last; | 
					
						
							|  |  |  | a.half_word_slot(2) := Object_Half_Word'Last; | 
					
						
							|  |  |  | b.half_word_Slot(1) := 16#10#; | 
					
						
							|  |  |  | bigint.multiply (interp, a, b, a); | 
					
						
							|  |  |  | print (interp, a); | 
					
						
							|  |  |  | end; | 
					
						
							| 
									
										
										
										
											2014-03-09 18:01:38 +00:00
										 |  |  | declare | 
					
						
							|  |  |  | q: object_Pointer; | 
					
						
							|  |  |  | begin | 
					
						
							| 
									
										
										
										
											2014-03-25 16:43:46 +00:00
										 |  |  | q := bigint.from_string (interp.self, String_To_Object_Character_Array("-FFFFFFFFFFFFFFFFAAAAAAAAAAAAAAAA11111111222222223333333344444444"), 16); | 
					
						
							|  |  |  | --q := bigint.from_string (interp.self, String_To_Object_Character_Array("-123456789123456789123456789A"), 15, q);
 | 
					
						
							|  |  |  | --q := bigint.from_string (interp.self, String_To_Object_Character_Array("123456789012345678901234567890"), 10, q);
 | 
					
						
							|  |  |  | --q := bigint.from_string (interp.self, String_To_Object_Character_Array("+123456701234567012345670123456701234567"), 8, q);
 | 
					
						
							|  |  |  | q := bigint.to_string (interp.self, q, 16); | 
					
						
							| 
									
										
										
										
											2014-03-09 18:01:38 +00:00
										 |  |  | print (interp, q); | 
					
						
							| 
									
										
										
										
											2014-02-21 16:08:43 +00:00
										 |  |  | end; | 
					
						
							| 
									
										
										
										
											2014-03-25 16:43:46 +00:00
										 |  |  | <<SKIP>> | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | 			Ada.Text_IO.Put_LINE ("=== BYE ==="); | 
					
						
							| 
									
										
										
										
											2014-02-06 13:29:08 +00:00
										 |  |  | 			Pop_Tops (Interp, 1); | 
					
						
							|  |  |  | 			if Aliased_Result /= null then | 
					
						
							|  |  |  | 				Result := Aliased_Result; | 
					
						
							|  |  |  | 			end if; | 
					
						
							| 
									
										
										
										
											2014-01-07 17:02:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-16 16:52:18 +00:00
										 |  |  | 		when X: others => | 
					
						
							|  |  |  | 			Ada.TEXT_IO.PUT_LINE ("ERROR ERROR ERROR -> " & Ada.Exceptions.Exception_Name(X)); | 
					
						
							| 
									
										
										
										
											2014-01-07 17:02:12 +00:00
										 |  |  | 			raise; | 
					
						
							| 
									
										
										
										
											2013-12-28 16:52:31 +00:00
										 |  |  | 	end Run_Loop; | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-21 04:57:44 +00:00
										 |  |  | 	-----------------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | --
 | 
					
						
							|  |  |  | --	function h2scm_open return Interpreter_Pointer;
 | 
					
						
							|  |  |  | --	pragma Export (C, h2scm_open, "h2scm_open");
 | 
					
						
							|  |  |  | --
 | 
					
						
							|  |  |  | --	procedure h2scm_close (Interp: in out Interpreter_Pointer);
 | 
					
						
							|  |  |  | --	pragma Export (C, h2scm_close, "h2scm_close");
 | 
					
						
							|  |  |  | --
 | 
					
						
							|  |  |  | --	function h2scm_evaluate (Interp: access Interpreter_Record;
 | 
					
						
							|  |  |  | --	                         Source: in     Object_Pointer) return Interfaces.C.int;
 | 
					
						
							|  |  |  | --	pragma Export (C, h2scm_evaluate, "h2scm_evaluate");
 | 
					
						
							|  |  |  | --
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | --	procedure h2scm_dealloc is new
 | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | --		Ada.Unchecked_Deallocation (Interpreter_Record, Interpreter_Pointer);
 | 
					
						
							|  |  |  | --
 | 
					
						
							|  |  |  | --	function h2scm_open return Interpreter_Pointer is
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | --		Interp: Interpreter_Pointer;
 | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | --	begin
 | 
					
						
							|  |  |  | --		begin
 | 
					
						
							|  |  |  | --			Interp := new Interpreter_Record;
 | 
					
						
							|  |  |  | --		exception
 | 
					
						
							|  |  |  | --			when others =>
 | 
					
						
							|  |  |  | --				return null;
 | 
					
						
							|  |  |  | --		end;
 | 
					
						
							|  |  |  | --
 | 
					
						
							|  |  |  | --		begin
 | 
					
						
							|  |  |  | --			Open (Interp.all, 1_000_000, null);
 | 
					
						
							|  |  |  | --		exception
 | 
					
						
							|  |  |  | --			when others =>
 | 
					
						
							|  |  |  | --				h2scm_dealloc (Interp);
 | 
					
						
							|  |  |  | --				return null;
 | 
					
						
							|  |  |  | --		end;
 | 
					
						
							|  |  |  | --
 | 
					
						
							|  |  |  | --		return Interp;
 | 
					
						
							|  |  |  | --	end h2scm_open;
 | 
					
						
							|  |  |  | --
 | 
					
						
							|  |  |  | --	procedure h2scm_close (Interp: in out Interpreter_Pointer) is
 | 
					
						
							|  |  |  | --	begin
 | 
					
						
							|  |  |  | --Text_IO.Put_Line ("h2scm_close");
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | --		Close (Interp.all);
 | 
					
						
							| 
									
										
										
										
											2014-01-09 15:32:36 +00:00
										 |  |  | --		h2scm_dealloc (Interp);
 | 
					
						
							|  |  |  | --	end h2scm_close;
 | 
					
						
							|  |  |  | --
 | 
					
						
							|  |  |  | --	function h2scm_evaluate (Interp: access Interpreter_Record;
 | 
					
						
							|  |  |  | --	                         Source: in     Object_Pointer) return Interfaces.C.int is
 | 
					
						
							|  |  |  | --	begin
 | 
					
						
							|  |  |  | --		return Interfaces.C.int(Interp.Heap(Interp.Current_Heap).Size);
 | 
					
						
							|  |  |  | --	end h2scm_evaluate;
 | 
					
						
							| 
									
										
										
										
											2014-06-02 15:25:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-10 16:14:06 +00:00
										 |  |  | end H2.Scheme; |