public override void visit(un_expr _un_expr)
        {
            try
            {
                _un_expr.subnode.visit(this);
                TypeScope tleft = returned_scope as TypeScope;
                if (cnst_val.prim_val != null)
                {
                    ev.eval_stack.Push(cnst_val);
                    switch (_un_expr.operation_type)
                    {
                        case Operators.BitwiseNOT:
                            ev.EvalNot(); break;
                        case Operators.LogicalNOT:
                            ev.EvalNot(); returned_scope = entry_scope.FindName(PascalABCCompiler.TreeConverter.compiler_string_consts.bool_type_name); break;
                        case Operators.Minus:
                            ev.EvalUnmin(); break;
                    }
                    if (ev.eval_stack.Count > 0)
                    {
                        cnst_val = ev.eval_stack.Pop();
                        returned_scope = TypeTable.get_type(cnst_val.prim_val);
                    }
                    else
                    {
                        cnst_val.prim_val = null;
                        returned_scope = tleft;
                    }
                }
            }
            catch (Exception e)
            {
                cnst_val.prim_val = null;
                ev.eval_stack.Clear();
                returned_scope = null;
            }
			
        }
        public override void visit(bin_expr _bin_expr)
        {
        	try
        	{
        		_bin_expr.left.visit(this);
        		RetValue left = cnst_val;
        		TypeScope tleft = returned_scope as TypeScope;
        		cnst_val.prim_val = null;
        		_bin_expr.right.visit(this);
        		TypeScope tright = returned_scope as TypeScope;
        		RetValue right = cnst_val;
        		cnst_val.prim_val = null;
        		if (left.prim_val != null && right.prim_val != null)
        		{
        			ev.eval_stack.Push(left);
        			ev.eval_stack.Push(right);
        			switch (_bin_expr.operation_type)
					{
						case Operators.Plus : ev.EvalPlus(); break;
						case Operators.Minus : ev.EvalMinus(); break;
						case Operators.Multiplication: ev.EvalMult(); break;
						case Operators.Division: ev.EvalDiv(); break;
						case Operators.IntegerDivision: ev.EvalIDiv(); break;
						case Operators.BitwiseAND: ev.EvalAnd(); break;
						case Operators.BitwiseOR: ev.EvalOr(); break;
						case Operators.BitwiseXOR: ev.EvalXor(); break;
						case Operators.BitwiseLeftShift: ev.EvalBitwiseLeft(); break;
						case Operators.BitwiseRightShift: ev.EvalBitwiseRight(); break;
						case Operators.Equal: ev.EvalEqual(); break;
						case Operators.NotEqual: ev.EvalNotEqual(); break;
						case Operators.Less: ev.EvalLess(); break;
						case Operators.LessEqual: ev.EvalLessEqual(); break;
						case Operators.Greater: ev.EvalGreater(); break;
						case Operators.GreaterEqual: ev.EvalGreaterEqual(); break;
						case Operators.LogicalAND: ev.EvalAnd(); break;
						case Operators.LogicalOR: ev.EvalOr(); break;
						case Operators.ModulusRemainder: ev.EvalRem(); break;
					}
        			if (ev.eval_stack.Count > 0)
        			{
        				cnst_val = ev.eval_stack.Pop();
        				returned_scope = TypeTable.get_type(cnst_val.prim_val);
        			}
        			else 
        			{
        				cnst_val.prim_val = null;
        				
        			}
        		}
        		else
        		{
        			cnst_val.prim_val = null;
        		}
        		
        		if (tleft != null && tright != null)
        		{
                    RetValue tmp = cnst_val;
                    List<SymScope> lst = tleft.FindOverloadNamesOnlyInType
        				(PascalABCCompiler.TreeConverter.name_reflector.get_name(_bin_expr.operation_type));
        			ProcScope ps = select_method(lst.ToArray(),tleft,tright,_bin_expr.left,_bin_expr.right);
        			if (ps != null)
        				returned_scope = ps.return_type;
        			else
        				returned_scope = tleft;
                    cnst_val = tmp;
        		}
        		else if (tleft != null)
        			returned_scope = tleft;
        		else
        			returned_scope = tright;
        	}
        	catch (Exception e)
        	{
        		cnst_val.prim_val = null;
        		ev.eval_stack.Clear();
        		returned_scope = null;
        	}
        	
        }
		public void EvalUnmin()
		{
			RetValue left = eval_stack.Pop();
			RetValue res = new RetValue();
			if (left.prim_val != null)
			{
				TypeCode lcode = Type.GetTypeCode(left.prim_val.GetType());
				switch (lcode) 
				{
					case TypeCode.Byte: res.prim_val = -(byte)left.prim_val; break;
					case TypeCode.Int16: res.prim_val = -(System.Int16)left.prim_val; break;
					case TypeCode.Int32: res.prim_val = -(System.Int32)left.prim_val; break;
					case TypeCode.Int64: res.prim_val = -(System.Int64)left.prim_val; break;
					case TypeCode.SByte: res.prim_val = -(sbyte)left.prim_val; break;
					case TypeCode.UInt16: res.prim_val = -(System.UInt16)left.prim_val; break;
					case TypeCode.UInt32: res.prim_val = -(System.UInt32)left.prim_val; break;
					//case TypeCode.UInt64: res.prim_val = -(System.UInt64)left.prim_val; break;
					case TypeCode.Double: res.prim_val = -(double)left.prim_val; break;
					case TypeCode.Single: res.prim_val = -(System.Single)left.prim_val; break;
				}
				eval_stack.Push(res);
			}
		}
		public void EvalIDiv()
		{
			RetValue right = eval_stack.Pop();
			RetValue left = eval_stack.Pop();
			RetValue res = new RetValue();
			if (left.prim_val != null && right.prim_val != null)
			{
				TypeCode lcode = Type.GetTypeCode(left.prim_val.GetType());
				TypeCode rcode = Type.GetTypeCode(right.prim_val.GetType());
				switch (lcode) 
				{
					case TypeCode.Int32:
						{
							switch(rcode)
							{
								case TypeCode.Byte : res.prim_val = (int)left.prim_val / (byte)right.prim_val; break;
								case TypeCode.Int32 : res.prim_val = (int)left.prim_val / (int)right.prim_val; break;
								case TypeCode.Double : res.prim_val = (int)left.prim_val / (double)right.prim_val; break;
								case TypeCode.Int64 : res.prim_val = (int)left.prim_val / (long)right.prim_val; break;
								//case TypeCode.String : res.prim_val = ((int)left.prim_val).ToString() + (string)right.prim_val; break;
								case TypeCode.Int16 : res.prim_val = (int)left.prim_val / (System.Int16)right.prim_val; break;
								case TypeCode.SByte : res.prim_val = (int)left.prim_val / (sbyte)right.prim_val; break;
								case TypeCode.UInt16 : res.prim_val = (int)left.prim_val / (System.UInt16)right.prim_val; break;
								case TypeCode.UInt32 : res.prim_val = (int)left.prim_val / (System.UInt32)right.prim_val; break;
								case TypeCode.UInt64 : res.prim_val = (System.UInt64)((int)left.prim_val) / (System.UInt64)right.prim_val; break;
								case TypeCode.Single : res.prim_val = (int)left.prim_val / (System.Single)right.prim_val; break;
							}
						}
						break;
					case TypeCode.Double:
						{
							switch(rcode)
							{
								case TypeCode.Byte : res.prim_val = (double)left.prim_val / (byte)right.prim_val; break;
								case TypeCode.Int32 : res.prim_val = (double)left.prim_val / (int)right.prim_val; break;
								case TypeCode.Double : res.prim_val = (double)left.prim_val / (double)right.prim_val; break;
								case TypeCode.Int64 : res.prim_val = (double)left.prim_val / (long)right.prim_val; break;
								//case TypeCode.String : res.prim_val = ((double)left.prim_val).ToString() + (string)right.prim_val; break;
								case TypeCode.Int16 : res.prim_val = (double)left.prim_val / (System.Int16)right.prim_val; break;
								case TypeCode.SByte : res.prim_val = (double)left.prim_val / (sbyte)right.prim_val; break;
								case TypeCode.UInt16 : res.prim_val = (double)left.prim_val / (System.UInt16)right.prim_val; break;
								case TypeCode.UInt32 : res.prim_val = (double)left.prim_val / (System.UInt32)right.prim_val; break;
								case TypeCode.UInt64 : res.prim_val = (double)left.prim_val / (System.UInt64)right.prim_val; break;
								case TypeCode.Single : res.prim_val = (double)left.prim_val / (System.Single)right.prim_val; break;
							}
						}
						break;
					case TypeCode.Byte:
						{
							switch(rcode)
							{
								case TypeCode.Byte : res.prim_val = (byte)left.prim_val / (byte)right.prim_val; break;
								case TypeCode.Int32 : res.prim_val = (byte)left.prim_val / (int)right.prim_val; break;
								case TypeCode.Double : res.prim_val = (byte)left.prim_val / (double)right.prim_val; break;
								case TypeCode.Int64 : res.prim_val = (byte)left.prim_val / (long)right.prim_val; break;
								//case TypeCode.String : res.prim_val = ((byte)left.prim_val).ToString() + (string)right.prim_val; break;
								case TypeCode.Int16 : res.prim_val = (byte)left.prim_val / (System.Int16)right.prim_val; break;
								case TypeCode.SByte : res.prim_val = (byte)left.prim_val / (sbyte)right.prim_val; break;
								case TypeCode.UInt16 : res.prim_val = (byte)left.prim_val / (System.UInt16)right.prim_val; break;
								case TypeCode.UInt32 : res.prim_val = (byte)left.prim_val / (System.UInt32)right.prim_val; break;
								case TypeCode.UInt64 : res.prim_val = (byte)left.prim_val / (System.UInt64)right.prim_val; break;
								case TypeCode.Single : res.prim_val = (byte)left.prim_val / (System.Single)right.prim_val; break;
							}
						}
						break;
					case TypeCode.Int16:
						{
							switch(rcode)
							{
								case TypeCode.Byte : res.prim_val = (System.Int16)left.prim_val / (byte)right.prim_val; break;
								case TypeCode.Int32 : res.prim_val = (System.Int16)left.prim_val / (int)right.prim_val; break;
								case TypeCode.Double : res.prim_val = (System.Int16)left.prim_val / (double)right.prim_val; break;
								case TypeCode.Int64 : res.prim_val = (System.Int16)left.prim_val / (long)right.prim_val; break;
								//case TypeCode.String : res.prim_val = ((System.Int16)left.prim_val).ToString() + (string)right.prim_val; break;
								case TypeCode.Int16 : res.prim_val = (System.Int16)left.prim_val / (System.Int16)right.prim_val; break;
								case TypeCode.SByte : res.prim_val = (System.Int16)left.prim_val / (sbyte)right.prim_val; break;
								case TypeCode.UInt16 : res.prim_val = (System.Int16)left.prim_val / (System.UInt16)right.prim_val; break;
								case TypeCode.UInt32 : res.prim_val = (System.Int16)left.prim_val / (System.UInt32)right.prim_val; break;
								case TypeCode.UInt64 : res.prim_val = (System.UInt64)((System.Int16)left.prim_val) / (System.UInt64)right.prim_val; break;
								case TypeCode.Single : res.prim_val = (System.Int16)left.prim_val / (System.Single)right.prim_val; break;
							}
						}
						break;
					case TypeCode.Int64:
						{
							switch(rcode)
							{
								case TypeCode.Byte : res.prim_val = (System.Int64)left.prim_val / (byte)right.prim_val; break;
								case TypeCode.Int32 : res.prim_val = (System.Int64)left.prim_val / (int)right.prim_val; break;
								case TypeCode.Double : res.prim_val = (System.Int64)left.prim_val / (double)right.prim_val; break;
								case TypeCode.Int64 : res.prim_val = (System.Int64)left.prim_val / (long)right.prim_val; break;
								//case TypeCode.String : res.prim_val = ((System.Int64)left.prim_val).ToString() + (string)right.prim_val; break;
								case TypeCode.Int16 : res.prim_val = (System.Int64)left.prim_val / (System.Int16)right.prim_val; break;
								case TypeCode.SByte : res.prim_val = (System.Int64)left.prim_val / (sbyte)right.prim_val; break;
								case TypeCode.UInt16 : res.prim_val = (System.Int64)left.prim_val / (System.UInt16)right.prim_val; break;
								case TypeCode.UInt32 : res.prim_val = (System.Int64)left.prim_val / (System.UInt32)right.prim_val; break;
								case TypeCode.UInt64 : res.prim_val = (System.Int64)left.prim_val / (System.Int64)((System.UInt64)right.prim_val); break;
								case TypeCode.Single : res.prim_val = (System.Int64)left.prim_val / (System.Single)right.prim_val; break;
							}
						}
						break;
					
					case TypeCode.SByte:
						{
							switch(rcode)
							{
								case TypeCode.Byte : res.prim_val = (System.SByte)left.prim_val / (byte)right.prim_val; break;
								case TypeCode.Int32 : res.prim_val = (System.SByte)left.prim_val / (int)right.prim_val; break;
								case TypeCode.Double : res.prim_val = (System.SByte)left.prim_val / (double)right.prim_val; break;
								case TypeCode.Int64 : res.prim_val = (System.SByte)left.prim_val / (long)right.prim_val; break;
								//case TypeCode.String : res.prim_val = ((System.SByte)left.prim_val).ToString() + (string)right.prim_val; break;
								case TypeCode.Int16 : res.prim_val = (System.SByte)left.prim_val / (System.Int16)right.prim_val; break;
								case TypeCode.SByte : res.prim_val = (System.SByte)left.prim_val / (sbyte)right.prim_val; break;
								case TypeCode.UInt16 : res.prim_val = (System.SByte)left.prim_val / (System.UInt16)right.prim_val; break;
								case TypeCode.UInt32 : res.prim_val = (System.SByte)left.prim_val / (System.UInt32)right.prim_val; break;
								case TypeCode.UInt64 : res.prim_val = (System.UInt64)((System.SByte)left.prim_val) / (System.UInt64)right.prim_val; break;
								case TypeCode.Single : res.prim_val = (System.SByte)left.prim_val / (System.Single)right.prim_val; break;
							}
						}
						break;
					case TypeCode.UInt16:
						{
							switch(rcode)
							{
								case TypeCode.Byte : res.prim_val = (System.UInt16)left.prim_val / (byte)right.prim_val; break;
								case TypeCode.Int32 : res.prim_val = (System.UInt16)left.prim_val / (int)right.prim_val; break;
								case TypeCode.Double : res.prim_val = (System.UInt16)left.prim_val / (double)right.prim_val; break;
								case TypeCode.Int64 : res.prim_val = (System.UInt16)left.prim_val / (long)right.prim_val; break;
								//case TypeCode.String : res.prim_val = ((System.UInt16)left.prim_val).ToString() + (string)right.prim_val; break;
								case TypeCode.Int16 : res.prim_val = (System.UInt16)left.prim_val / (System.Int16)right.prim_val; break;
								case TypeCode.SByte : res.prim_val = (System.UInt16)left.prim_val / (sbyte)right.prim_val; break;
								case TypeCode.UInt16 : res.prim_val = (System.UInt16)left.prim_val / (System.UInt16)right.prim_val; break;
								case TypeCode.UInt32 : res.prim_val = (System.UInt16)left.prim_val / (System.UInt32)right.prim_val; break;
								case TypeCode.UInt64 : res.prim_val = (System.UInt16)left.prim_val / (System.UInt64)right.prim_val; break;
								case TypeCode.Single : res.prim_val = (System.UInt16)left.prim_val / (System.Single)right.prim_val; break;
							}
						}
						break;
					case TypeCode.UInt32:
						{
							switch(rcode)
							{
								case TypeCode.Byte : res.prim_val = (System.UInt32)left.prim_val / (byte)right.prim_val; break;
								case TypeCode.Int32 : res.prim_val = (System.UInt32)left.prim_val / (int)right.prim_val; break;
								case TypeCode.Double : res.prim_val = (System.UInt32)left.prim_val / (double)right.prim_val; break;
								case TypeCode.Int64 : res.prim_val = (System.UInt32)left.prim_val / (long)right.prim_val; break;
								//case TypeCode.String : res.prim_val = ((System.UInt32)left.prim_val).ToString() + (string)right.prim_val; break;
								case TypeCode.Int16 : res.prim_val = (System.UInt32)left.prim_val / (System.Int16)right.prim_val; break;
								case TypeCode.SByte : res.prim_val = (System.UInt32)left.prim_val / (sbyte)right.prim_val; break;
								case TypeCode.UInt16 : res.prim_val = (System.UInt32)left.prim_val / (System.UInt16)right.prim_val; break;
								case TypeCode.UInt32 : res.prim_val = (System.UInt32)left.prim_val / (System.UInt32)right.prim_val; break;
								case TypeCode.UInt64 : res.prim_val = (System.UInt32)left.prim_val / (System.UInt64)right.prim_val; break;
								case TypeCode.Single : res.prim_val = (System.UInt32)left.prim_val / (System.Single)right.prim_val; break;
							}
						}
						break;
					case TypeCode.UInt64:
						{
							switch(rcode)
							{
								case TypeCode.Byte : res.prim_val = (System.UInt64)left.prim_val / (byte)right.prim_val; break;
								case TypeCode.Int32 : res.prim_val = (System.UInt64)left.prim_val / (System.UInt64)((int)right.prim_val); break;
								case TypeCode.Double : res.prim_val = (System.UInt64)left.prim_val / (double)right.prim_val; break;
								case TypeCode.Int64 : res.prim_val = (long)((System.UInt64)left.prim_val) / (long)right.prim_val; break;
								//case TypeCode.String : res.prim_val = ((System.UInt64)left.prim_val).ToString() + (string)right.prim_val; break;
								case TypeCode.Int16 : res.prim_val = (System.UInt64)left.prim_val / (System.UInt64)((System.Int16)right.prim_val); break;
								case TypeCode.SByte : res.prim_val = (System.UInt64)left.prim_val / (System.UInt64)((sbyte)right.prim_val); break;
								case TypeCode.UInt16 : res.prim_val = (System.UInt64)left.prim_val / (System.UInt16)right.prim_val; break;
								case TypeCode.UInt32 : res.prim_val = (System.UInt64)left.prim_val / (System.UInt32)right.prim_val; break;
								case TypeCode.UInt64 : res.prim_val = (System.UInt64)left.prim_val / (System.UInt64)right.prim_val; break;
								case TypeCode.Single : res.prim_val = (System.UInt64)left.prim_val / (System.Single)right.prim_val; break;
							}
						}
						break;
					case TypeCode.Single:
						{
							switch(rcode)
							{
								case TypeCode.Byte : res.prim_val = (System.Single)left.prim_val / (byte)right.prim_val; break;
								case TypeCode.Int32 : res.prim_val = (System.Single)left.prim_val / (int)right.prim_val; break;
								case TypeCode.Double : res.prim_val = (System.Single)left.prim_val / (double)right.prim_val; break;
								case TypeCode.Int64 : res.prim_val = (System.Single)left.prim_val / (long)right.prim_val; break;
								//case TypeCode.String : res.prim_val = ((System.Single)left.prim_val).ToString() + (string)right.prim_val; break;
								case TypeCode.Int16 : res.prim_val = (System.Single)left.prim_val / (System.Int16)right.prim_val; break;
								case TypeCode.SByte : res.prim_val = (System.Single)left.prim_val / (sbyte)right.prim_val; break;
								case TypeCode.UInt16 : res.prim_val = (System.Single)left.prim_val / (System.UInt16)right.prim_val; break;
								case TypeCode.UInt32 : res.prim_val = (System.Single)left.prim_val / (System.UInt32)right.prim_val; break;
								case TypeCode.UInt64 : res.prim_val = (System.Single)left.prim_val / (System.UInt64)right.prim_val; break;
								case TypeCode.Single : res.prim_val = (System.Single)left.prim_val / (System.Single)right.prim_val; break;
							}
						}
						break;
				}
				eval_stack.Push(res);
			}
		}
		public void EvalNot()
		{
			RetValue left = eval_stack.Pop();
			RetValue res = new RetValue();
			if (left.prim_val != null)
			{
				TypeCode lcode = Type.GetTypeCode(left.prim_val.GetType());
				switch (lcode) 
				{
					case TypeCode.Boolean : res.prim_val = !(bool)left.prim_val; break;
					case TypeCode.Byte: res.prim_val = ~(byte)left.prim_val; break;
					case TypeCode.Int16: res.prim_val = ~(System.Int16)left.prim_val; break;
					case TypeCode.Int32: res.prim_val = ~(System.Int32)left.prim_val; break;
					case TypeCode.Int64: res.prim_val = ~(System.Int64)left.prim_val; break;
					case TypeCode.SByte: res.prim_val = ~(sbyte)left.prim_val; break;
					case TypeCode.UInt16: res.prim_val = ~(System.UInt16)left.prim_val; break;
					case TypeCode.UInt32: res.prim_val = ~(System.UInt32)left.prim_val; break;
					case TypeCode.UInt64: res.prim_val = ~(System.UInt64)left.prim_val; break;
				}
				eval_stack.Push(res);
			}
		}