Click here to Skip to main content
15,884,472 members
Articles / Programming Languages / ASM

Bird Programming Language: Part 3

Rate me:
Please Sign up or sign in to vote.
4.88/5 (5 votes)
1 Jan 2013GPL35 min read 29.8K   282   14  
A new general purpose language that aims to be fast, high level and simple to use.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Bird
{
	public abstract class IdContainer
	{
		public DataList Data = new DataList();
		public IdContainer Parent;
        public CompilerState State;
		public FunctionScope FunctionScope;
		public int LocalIndex = -1;

		public AutoAllocatedList<Identifier> IdentifierList;
		public AutoAllocatedList<FunctionOverloads> FunctionOverloads;
		public AutoAllocatedList<IdContainer> Children;

		public void ReplaceChild(IdContainer From, IdContainer To)
		{
			for (var i = 0; i < Children.Count; i++)
			{
				if (Children[i] == From)
					Children[i] = To;
			}
		}

		public virtual void ForEachId(Action<Identifier> Func)
		{
			IdentifierList.ForEach(Func);
		}

		public virtual bool TrueForAllId(Predicate<Identifier> Func)
		{
			return IdentifierList.TrueForAll(Func);
		}

		public void ForEachParent<T>(Action<T> Action, IdContainer Until = null)
			where T : IdContainer
		{
			if (this is T) Action(this as T);
			if (Parent != null && Parent != Until)
				Parent.ForEachParent(Action, Until);
		}

		public bool TrueForAllParent<T>(Predicate<T> Func, IdContainer Until = null)
			where T : IdContainer
		{
			if (this is T && !Func(this as T)) return false;
			if (Parent != null && Parent != Until)
				return Parent.TrueForAllParent(Func, Until);

			return true;
		}

		public void ForEach(Action<IdContainer> Action)
		{
			Action(this);

			for (var i = 0; i < Children.Count; i++)
				Children[i].ForEach(Action);
		}

		public int GetIndirectChildIndex(IdContainer Container)
		{
			var Index = GetChildIndex(Container);
			while (Index == -1)
			{
				Container = Container.Parent;
				if (Container == this || Container == null)
					return -1;

				Index = GetChildIndex(Container);
			}

			return Index;
		}

		public int GetChildIndex(IdContainer Container)
		{
			for (var i = 0; i < Children.Count; i++)
				if (Children[i] == Container) return i;

			return -1;
		}

		public virtual void AddIdentifier(Identifier Id)
		{
			if (FunctionScope != null)
			{
				Id.LocalIndex = FunctionScope.LocalIdentifiers.Count;
				FunctionScope.LocalIdentifiers.Add(Id);
			}

			IdentifierList.Add(Id);
		}

		public virtual void GetAssembly(CodeGenerator CG, GetAssemblyMode Mode = GetAssemblyMode.Code)
		{
			for (var i = 0; i < IdentifierList.Count; i++)
				IdentifierList[i].GetAssembly(CG, Mode);

			for (var i = 0; i < Children.Count; i++)
				Children[i].GetAssembly(CG, Mode);
		}

		public List<string> GetGlobalPointers()
		{
			var Ret = new List<string>();
			GetGlobalPointers(Ret);
			return Ret;
		}

		public virtual void GetGlobalPointers(List<string> Out)
		{
			for (var i = 0; i < IdentifierList.Count; i++)
				IdentifierList[i].GetGlobalPointers(Out);

			for (var i = 0; i < Children.Count; i++)
				Children[i].GetGlobalPointers(Out);
		}

		protected virtual string CalculateAssemblyName()
		{
			if (Parent != null)
				return Parent.AssemblyName;

			return "";
		}

		string _AssemblyName = null;
		public string AssemblyName
		{
			get
			{
				if (_AssemblyName == null)
					_AssemblyName = CalculateAssemblyName();

				return _AssemblyName;
			}
		}

		public virtual IdContainer RealContainer
		{
			get { return this; }
		}
		
		public virtual CallingConvention DefaultCallConv
		{
			get { return State.DefaultCallConv; }
		}

		public virtual IdentifierAccess DefaultAccess
		{
			get { return IdentifierAccess.Unknown; }
		}

		static bool SameTypes(VarDeclarationList A, VarDeclarationList B)
		{
			if (A.Count != B.Count)
				return false;

			for (var i = 0; i < A.Count; i++)
				if (!A[i].Type.IsEquivalent(B[i].Type))
					return false;

			return true;
		}

		public virtual bool CanIdDeclared(Identifier Id)
		{
			var StructuredContainer = Id.Container.RealContainer as StructuredScope;
			var IsLocal = Id.Container.FunctionScope != null;

			if (Id.Access == IdentifierAccess.Unknown)
			{
				if (!IsLocal)
					throw new ApplicationException("Only locals' access can be unknown");
			}
			else
			{
				if (IsLocal)
					throw new ApplicationException("Locals' access must be unknown");

				if (((int)Id.Access & 3) != 0 && StructuredContainer == null)
				{
					State.Messages.Add(MessageId.ProtPrivInNonStructured, Id.Declaration);
					return false;
				}
			}
			/*
			if (Id.Name.IsValid && !Id.Name.IsValidIdentifierName)
			{
				State.Messages.Add(MessageId.NotValidName, Id.Name);
				return false;
			}
			*/

			if (Id is Namespace)
			{
				if (!(this is NamespaceScope))
					throw new ApplicationException("Namespaceses cannot be declared here");
			}
			else if (Id is Property)
			{
				var Property = Id as Property;
				var PropScope = Property.PropertyScope;
				var Type = Id.Children[0];

				if (Identifiers.IsLessAccessable(Type, Id))
				{
					State.Messages.Add(MessageId.LessAccessable, Id.Name, Type.Name.ToString());
					return false;
				}

				for (var i = 0; i < PropScope.IdentifierList.Count; i++)
				{
					var Ch = PropScope.IdentifierList[i];
					if (Ch != null && Identifiers.IsLessAccessable(Id, Ch))
					{
						State.Messages.Add(MessageId.LessAccessable, Ch.Name, Id.Name.ToString());
						return false;
					}
				}
			}
			else if (Id is Variable)
			{
				var Var = Id as Variable;
				var Type = Id.Children[0];
				/*
				if (Var is ConstVariable && Var.GlbInitVal == null)
					throw new ApplicationException("Constants must have a value");
				*/
				if (!IsLocal && Identifiers.IsLessAccessable(Type, Id))
				{
					State.Messages.Add(MessageId.LessAccessable, Id.Name, Type.Name.ToString());
					return false;
				}
			}
			else if (Id is Function)
			{
				if (Id.Name.StartsWith("%Operator_"))
				{
					if ((Id.Flags & IdentifierFlags.Static) == 0 || Id.Access != IdentifierAccess.Public)
					{
						State.Messages.Add(MessageId.OperatorModifiers, Id.Declaration);
						return false;
					}

					if (!(this is StructuredScope))
					{
						State.Messages.Add(MessageId.CannotDeclFunc, Id.Declaration);
						return false;
					}
				}

				if ((Id is Constructor || Id is Destructor) && !(this is StructuredScope))
				{
					State.Messages.Add(MessageId.CannotDeclFunc, Id.Declaration);
					return false;
				}

				var Func = Id as Function;
				var FuncType = Func.TypeOfSelf.RealId as TypeOfFunction;
				var RetType = FuncType.Children[0];

				if (Identifiers.IsLessAccessable(RetType, Id))
				{
					State.Messages.Add(MessageId.LessAccessable, Id.Declaration, RetType.Name.ToString());
					return false;
				}

				var DefaultValues = false;
				var CantBeMore = false;
				for (var i = 1; i < FuncType.Children.Length; i++)
				{
					var e = FuncType.Children[i] as FunctionParameter;
					if (Identifiers.IsLessAccessable(e.Children[0], Id))
					{
						State.Messages.Add(MessageId.LessAccessable, e.Declaration, e.TypeOfSelf.Name.ToString());
						return false;
					}
					else if (CantBeMore)
					{
						State.Messages.Add(MessageId.ParamArrayMustBeTheLast, e.Declaration);
						return false;
					}
					else if ((e.ParamFlags & ParameterFlags.ParamArray) != 0)
					{
						CantBeMore = true;
					}
					else if (e.ConstInitValue != null)
					{
						DefaultValues = true;
					}
					else if (DefaultValues)
					{
						State.Messages.Add(MessageId.ParamIsntOptional, e.Declaration);
						return false;
					}
				}

				var Overload = Func.Overload;
				if (Overload.OverloadCount > 0)
				{
					for (var i = 0; i < Overload.Functions.Count; i++)
					{
						var e = Overload.Functions[i];
						if (e == Id) continue;

						if (Func is Constructor && e is Constructor)
						{
							if ((Func.Flags & IdentifierFlags.Static) != 0 && (e.Flags & IdentifierFlags.Static) != 0)
							{
								State.Messages.Add(MessageId.IdAlreadyDefined, Func.Declaration);
								return false;
							}
							else if ((Func.Flags & IdentifierFlags.Static) != 0 || (e.Flags & IdentifierFlags.Static) != 0)
							{
								continue;
							}
						}

                        if (Identifiers.AreParametersSame(Func, e))
						{
							State.Messages.Add(MessageId.SameOverloads, Id.Declaration);
							return false;
						}
					}
				}

				return true;
			}
			else if (Id is IdentifierAlias)
			{
				if (Identifiers.IsLessAccessable(Id.RealId, Id))
				{
					State.Messages.Add(MessageId.LessAccessable, Id.Declaration, Id.RealId.Name.ToString());
					return false;
				}
			}
			else if (!(Id is Type))
			{
				throw new NotImplementedException();
			}

			if (Id.Name.IsValid && (Id.Flags & IdentifierFlags.Override) == 0)
			{
				if (IsAlreadyDefined(Id.Name.ToString()))
				{
					State.Messages.Add(MessageId.IdAlreadyDefined, Id.Declaration);
					return false;
				}
			}

			return true;
		}

		public bool DeclareIdentifier(Identifier Id)
		{
			if (!CanIdDeclared(Id)) return false;
			AddIdentifier(Id);
			return true;
		}

		public bool DeclareVariables(CodeString Str, List<Modifier> Mods = null,
			VarDeclConvMode Mode = VarDeclConvMode.Nothing, GetIdMode IdMode = GetIdMode.Everywhere)
		{
			var List = VarDeclarationList.Create(this, Str, Mods);
			if (List == null) return false;

			return DeclareVariables(List, Mode, IdMode);
		}

		public bool DeclareVariables(VarDeclarationList List, VarDeclConvMode Mode = VarDeclConvMode.Nothing, 
			GetIdMode IdMode = GetIdMode.Everywhere)
		{
			var Variables = List.ToVariables(GetPlugin(), BeginEndMode.Both, Mode);
			return DeclareVariables(Variables, IdMode);
		}

		public virtual bool DeclareVariables(Variable[] Variables, GetIdMode IdMode = GetIdMode.Everywhere)
		{
			var RetValue = true;
            for (var i = 0; i < Variables.Length; i++)
			{
				if (Variables[i] == null || !DeclareIdentifier(Variables[i]))
					RetValue = false;
			}

			return RetValue;
		}

		public Variable CreateVariableHelper(CodeString Name, Identifier Type, List<Modifier> Mods = null)
		{
			if (Mods != null)
			{
				if (Modifiers.Contains<ConstModifier>(Mods)) 
					return new ConstVariable(this, Name, Type, null);
				else if ((Modifiers.GetFlags(Mods) & IdentifierFlags.Static) != 0)
					return new GlobalVariable(this, Name, Type);
			}

			return null;
		}

		public FunctionOverloads GetOverload(string Name)
		{
			for (var i = 0; i < FunctionOverloads.Count; i++)
			{
				var Overload = FunctionOverloads[i];
				if (Overload.Name == Name) return Overload;
			}

			var Ret = new FunctionOverloads(Name);
			FunctionOverloads.Add(Ret);
			return Ret;
		}

		public Namespace CreateNamespace(CodeString Name, List<Modifier> Mods = null)
		{
			var Ret = new Namespace(this, Name);
			if (Mods != null && !Modifiers.Apply(Mods, Ret)) return null;
			return Ret;
		}

		public Property CreateProperty(CodeString Name, Identifier Type, FunctionParameter[] Parameters = null, List<Modifier> Mods = null)
		{
			var ParameterCount = Parameters == null ? 0 : Parameters.Length;
			var Children = new Identifier[ParameterCount + 1];
			Children[0] = Type;

			if (ParameterCount > 0)
			{
				for (var i = 0; i < ParameterCount; i++)
					Children[i + 1] = Parameters[i];
			}

			return CreateProperty(Name, Children, Mods);
		}

		public Property CreateProperty(CodeString Name, Identifier[] Children, List<Modifier> Mods = null)
		{
			var Type = Children[0].RealId as Type;
			if ((Type.TypeFlags & TypeFlags.CanBeVariable) == 0)
			{
				State.Messages.Add(MessageId.CannotBeThisType, Name);
				return null;
			}

			var Ret = new Property(this, Name, Children);
			if (Mods != null && !Modifiers.Apply(Mods, Ret)) return null;
			return Ret;
		}

		public Variable CreateVariable(CodeString Name, Identifier Type, List<Modifier> Mods = null)
		{
			var RType = Type.RealId as Type;
			if ((RType.TypeFlags & TypeFlags.CanBeVariable) == 0)
			{
				State.Messages.Add(MessageId.CannotBeThisType, Name);
				return null;
			}

			var Ret = OnCreateVariable(Name, Type, Mods);
			if (Ret == null) return null;

			if (Mods != null && !Modifiers.Apply(Mods, Ret)) return null;
			return Ret;
		}

		public Variable CreateAndDeclareVariable(CodeString Name, Identifier Type, List<Modifier> Mods = null)
		{
			var Ret = CreateVariable(Name, Type, Mods);
			if (Ret == null || !DeclareIdentifier(Ret)) return null;
			return Ret;
		}

		public Function CreateFunction(CodeString Name, TypeOfFunction FuncType, List<Modifier> Mods = null)
		{
			var Overload = GetOverload(Name.ToString());
			var Ret = OnCreateFunction(Name, FuncType, Overload, Mods);
			if (Ret == null) return null;

			if (!AdjustFunction(Ret, Mods)) return null;
			return Ret;
		}

		public bool AdjustFunction(Function Func, List<Modifier> Mods = null)
		{
			var Overload = Func.Overload;
			if (Overload != null)
			{
				Func.OverloadIndex = Overload.OverloadCount;
				Overload.Functions.Add(Func);
			}

			if (Mods != null)
			{
				if (!Modifiers.Apply(Mods, Func)) return false;
				Func.TypeOfSelf.GenerateName(); 
			}

			return true;
		}

		public bool AdjustAndDeclareFunction(Function Func, List<Modifier> Mods = null)
		{
			if (!AdjustFunction(Func, Mods)) return false;
			return DeclareIdentifier(Func);
		}

		public virtual Function OnCreateFunction(CodeString Name, TypeOfFunction FuncType,
			FunctionOverloads Overload = null, List<Modifier> Mods = null)
		{
			return new Function(this, Name, FuncType, Overload);
		}

		public virtual Variable OnCreateVariable(CodeString Name, Identifier Type, List<Modifier> Mods = null)
		{
			var Ret = CreateVariableHelper(Name, Type, Mods);
			if (Ret == null) Ret = new GlobalVariable(this, Name, Type);
			return Ret;
		}

		public Function CreateFunction(CodeString Name, CodeString SRetType, FunctionParameter[] Params, List<Modifier> Mods = null)
		{
			var RetType = RecognizeIdentifier(SRetType, GetIdOptions.DefaultForType);
			if (RetType == null) return null;

			if (RetType.RealId is AutomaticType)
			{
				State.Messages.Add(MessageId.VarFuncRetType, SRetType);
				return null;
			}

			var FuncType = new TypeOfFunction(this, DefaultCallConv, RetType, Params);
			return CreateFunction(Name, FuncType, Mods);
		}

		public Function CreateAndDeclareFunction(CodeString Name, TypeOfFunction Type, List<Modifier> Mods = null)
		{
			var Func = CreateFunction(Name, Type, Mods);
			if (Func == null) return null;

			if (!DeclareIdentifier(Func)) return null;
			return Func;
		}

		public Function CreateAndDeclareFunction(CodeString Name, CodeString SRetType,
			FunctionParameter[] Params, List<Modifier> Mods = null)
		{
			var Func = CreateFunction(Name, SRetType, Params, Mods);
			if (Func == null) return null;

			if (!DeclareIdentifier(Func)) return null;
			return Func;
		}

		public Function CreateDeclaredFunctionAndScope(CodeString Name, TypeOfFunction Type, CodeString Inner, List<Modifier> Mods = null)
		{
			var Func = CreateAndDeclareFunction(Name, Type, Mods);
			if (Func == null) return null;

			if (Func.HasCode)
			{
				Func.FunctionScope = new FunctionScope(this, Func, Inner);
				if (!Func.FunctionScope.Initialize()) return null;
			}

			return Func;
		}

		public Function CreateDeclaredFunctionAndScope(CodeString Name, CodeString SRetType,
			FunctionParameter[] Params, CodeString Inner, List<Modifier> Mods = null)
		{
			var Func = CreateAndDeclareFunction(Name, SRetType, Params, Mods);
			if (Func == null || CreateScopeForFunction(Func, Inner) == null) return null;
			return Func;
		}

		public FunctionScope CreateScopeForFunction(Function Function, CodeString Inner)
		{
			if (Function.NeedsToBeCompiled)
			{
				Function.FunctionScope = new FunctionScope(this, Function, Inner);
				if (!Function.FunctionScope.Initialize()) return null;
			}
			else if (Inner.IsValid)
			{
				State.Messages.Add(MessageId.FuncCannotHaveInnerScope, Function.Declaration);
				return null;
			}

			return Function.FunctionScope;
		}

		public IdContainer GetCommonContainer(IdContainer Container)
		{
			if (Container == this || Container.IsSubContainerOf(this)) return this;
			else if (Parent != null) return Parent.GetCommonContainer(Container);
			else return null;
		}

		public bool IsSubContainerOf(IdContainer Container)
		{
			var Current = Parent;
			while (Container != Current)
			{
				if (Current == null) return false;
				Current = Current.Parent;
			}

			return true;
		}

		public Command GetParent(CommandType Type, IdContainer Until = null)
		{
			return GetParent<Command>(x => x.Type == Type, Until);
		}

		public T GetParent<T>(IdContainer Until)
			where T : IdContainer
		{
			return GetParent<T>(x => true, Until);
		}

		public T GetParent<T>(Predicate<T> Func, IdContainer Until)
			where T : IdContainer
		{
			if (Parent == Until)
				return null;

			var Current = Parent;
			while (!(Current is T) || !Func(Current as T))
			{
				if (Current == null || Current.Parent == Until)
					return null;

				Current = Current.Parent;
			}

			return Current as T;
		}

		public bool IsSubContainerOf<T>(Predicate<T> Func, IdContainer Until = null)
			where T : IdContainer
		{
			return GetParent(Func, Until) != null;
		}

		public IdContainer(IdContainer Parent)
		{
			this.Parent = Parent;
			
			if (Parent == null)
			{
				if (!(this is GlobalContainer))
					throw new ArgumentNullException("Parent");
			}
			else
            {
                if (State == null) State = Parent.State;
                if (FunctionScope == null) FunctionScope = Parent.FunctionScope;

				if (FunctionScope != null)
				{
					LocalIndex = FunctionScope.ContainerLocalIndexCount;
					FunctionScope.ContainerLocalIndexCount++;
				}
			}
		}

		public virtual PluginRoot GetPlugin()
		{
			return new PluginForGlobals(this);
		}

		public T GetParent<T>(Predicate<T> Func = null) where T : IdContainer
		{
			var Scope = this;
			while (Scope != null)
			{
				var TScope = Scope as T;
				if (TScope != null && (Func == null || Func(TScope)))
					return TScope;

				Scope = Scope.Parent;
			}

			return null;
		}

		public bool Contains(IdContainer Container)
		{
			for (var i = 0; i < Children.Count; i++)
				if (Children[i].Contains(Container)) return true;

			return false;
		}

		GlobalContainer _GblScope;
		public GlobalContainer GlobalContainer
		{
			get
			{
				if (_GblScope == null)
					_GblScope = GetParent<GlobalContainer>();

				return _GblScope;
			}
		}

		AssemblyScope _AssemblyScope;
		public AssemblyScope AssemblyScope
		{
			get
			{
				if (_AssemblyScope == null)
					_AssemblyScope = GetParent<AssemblyScope>();

				return _AssemblyScope;
			}
		}

		StructuredScope _TypeScope;
		public StructuredScope StructuredScope
		{
			get
			{
				if (_TypeScope == null)
					_TypeScope = GetParent<StructuredScope>();

				return _TypeScope;
			}
		}

		public bool IsScopeOfAssembly(Assembly Assembly)
		{
			var Scope = AssemblyScope;
			if (Scope == null) return false;
			else return Scope.Assembly == Assembly;
		}

		public bool IsNotLoadedAssemblyScope()
		{
			var Scope = AssemblyScope;
			return Scope == null || Scope.Assembly == GlobalContainer.OutputAssembly;
		}

		public bool IsScopeOfAssembly()
		{
			return IsScopeOfAssembly(GlobalContainer.OutputAssembly);
		}

		public Identifier GetRetType(Identifier Type0, Identifier Type1)
		{
			var RType0 = Type0.RealId;
			var RType1 = Type1.RealId;

			if (RType0 is AutomaticType || RType0 is CharType) return Type1;
			if (RType1 is AutomaticType || RType1 is CharType) return Type0;
			if (RType0 is StringType || RType0 is PointerType) return Type0;
			if (RType1 is StringType || RType1 is PointerType) return Type1;

			if (RType0 is NumberType && RType1 is NumberType)
				return GetNumberRetType(RType0 as NumberType, RType1 as NumberType);

			var Tuple0 = RType0 as TupleType;
			var Tuple1 = RType1 as TupleType;
			if (Tuple0 != null && Tuple1 != null)
			{
				var Members0 = Tuple0.StructuredScope.IdentifierList;
				var Members1 = Tuple1.StructuredScope.IdentifierList;
				if (Members0.Count == Members1.Count)
				{
					var Members = new List<Identifier>();
					for (var i = 0; i < Members0.Count; i++)
					{
						var Var0 = Members0[i] as MemberVariable;
						var Var1 = Members1[i] as MemberVariable;

						var T = GetRetType(Var0.TypeOfSelf, Var1.TypeOfSelf);
						if (T == null) return null;

						var MemVar = new MemberVariable(this, new CodeString(), T);
						MemVar.Access = T.Access;
						Members.Add(MemVar);
					}

					return new TupleType(this, Members);
				}
			}

			return Type0;
		}

		public Identifier GetNumberRetType(Identifier Type0, Identifier Type1)
		{
			var RType0 = Type0.RealId as Type;
			var RType1 = Type1.RealId as Type;

			var mSize = RType0.Size;
			if (RType1.Size > mSize) mSize = RType1.Size;

			if (RType0 is FloatType && RType1 is FloatType)
				return GlobalContainer.CommonIds.GetIdentifier<FloatType>(mSize);

			if (RType0 is FloatType) return Type0;
			if (RType1 is FloatType) return Type1;

			if (RType0 is SignedType && RType1 is SignedType)
				return GlobalContainer.CommonIds.GetIdentifier<SignedType>(mSize);

			SignedType Signed;
			UnsignedType Unsigned;
			if (RType0 is SignedType)
			{
				Signed = RType0 as SignedType;
				Unsigned = RType1 as UnsignedType;
			}
			else
			{
				Signed = RType1 as SignedType;
				Unsigned = RType0 as UnsignedType;
			}

			if (Signed != null && Unsigned != null)
			{
				if (Signed.Size > Unsigned.Size) return Signed;
				return GlobalContainer.CommonIds.GetIdentifier<SignedType>(mSize * 2);
			}

			return GlobalContainer.CommonIds.GetIdentifier<UnsignedType>(mSize);
		}

		private Identifier GetPredeclaredIdentifier(string Name)
		{
			var Ids = GlobalContainer.CommonIds.Predeclared;
			for (var i = 0; i < Ids.Count; i++)
				if (Ids[i].Name.IsEqual(Name)) return Ids[i];

			return null;
		}

		public Identifier RecognizeIdentifier(CodeString Code)
		{
			return Identifiers.Recognize(this, Code);
		}

		public Identifier RecognizeIdentifier(CodeString Code, GetIdOptions Options)
		{
			return Identifiers.Recognize(this, Code, Options);
		}

		public Identifier RecognizeIdentifier(CodeString Code, GetIdOptions Options, IList<IIdRecognizer> Recognizers)
		{
			return Identifiers.Recognize(this, Code, Options, Recognizers);
		}

		public virtual bool GetContainerId(string Name, List<IdentifierFound> Out, Predicate<Identifier> Func = null)
		{
			return Identifiers.Search(this, IdentifierList, Name, Out, Func);
		}

		public List<IdentifierFound> GetContainerId(string Name, Predicate<Identifier> Func = null)
		{
			var Out = new List<IdentifierFound>();
			GetContainerId(Name, Out, Func);
			return Out;
		}

		public virtual bool IsAlreadyDefined(string Name, Predicate<Identifier> Func = null)
		{
			return Identifiers.Search(this, IdentifierList, Name, Func).Count > 0;
		}

		public bool GetIdentifier(string Name, List<IdentifierFound> Out, GetIdMode Mode = GetIdMode.Everywhere,
			bool SearchedInBasicTypes = false, Predicate<Identifier> Func = null)
		{
			/*if (FunctionScope != null && Mode != GetIdMode.Scope)
			{
				Predicate<T> LFunc = x =>
				{
					if (x.Container != this && !IsSubContainerOf(x.Container))
						return false;

					return Func == null || Func(x);
				};

				FunctionScope.LocalIdentifiers.Get<T>(Name, Out, LFunc);
				if (Mode == GetIdMode.Everywhere && FunctionScope.Parent != null)
					FunctionScope.Parent.GetIdentifier(Name, Out, Mode, SearchedInBasicTypes, Func);
			}
			else
			{*/
				if (!SearchedInBasicTypes)
				{
					var R = GetPredeclaredIdentifier(Name);
					if (R != null && (Func == null || Func(R)))
					{
						Out.Add(new IdentifierFound(GlobalContainer, R));
						return true;
					}

					SearchedInBasicTypes = true;
				}

				var RetValue = GetContainerId(Name, Out, Func);
				if (Parent != null && Mode != GetIdMode.Container)
				{
					var F = FunctionScope;
					if (Mode != GetIdMode.Function || (Parent.FunctionScope == F && F != null))
					{
						if (Parent.GetIdentifier(Name, Out, Mode, SearchedInBasicTypes, Func))
							RetValue = true;
					}
				}

				return RetValue;
			//}
		}

		public List<IdentifierFound> GetIdentifier(string Name, GetIdMode Mode = GetIdMode.Everywhere,
			Predicate<Identifier> Func = null)
		{
			var Out = new List<IdentifierFound>();
			GetIdentifier(Name, Out, Mode, Func: Func);
			return Out;
		}

		public bool IsIdDefined(string Name, GetIdMode Mode = GetIdMode.Everywhere, Predicate<Identifier> Func = null)
		{
			return GetIdentifier(Name, Mode, Func).Count > 0;
		}

		public bool IsIdDefined(Identifier Id)
		{
			if (IdentifierList.Contains(Id)) return true;
			else if (Parent != null) return Parent.IsIdDefined(Id);
			else return false;
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)


Written By
Software Developer
Hungary Hungary
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions