Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version
Go to top

Bird Programming Language: Part 1

, 1 Jan 2013
A new general purpose language that aims to be fast, high level and simple to use.
Bird-noexe.zip
Bird
Archives
crt2.o
crtbegin.o
crtend.o
libadvapi32.a
libcomctl32.a
libcomdlg32.a
libgcc.a
libgdi32.a
libglu32.a
libkernel32.a
libmingw32.a
libmingwex.a
libmoldname.a
libmsvcrt.a
libopengl32.a
libshell32.a
libstdc++.a
libuser32.a
libwinmm.a
libwsock32.a
Libraries
BirdCore
Array.bird
BigInteger.bird
BinaryRW.bird
BirdCore.a
BirdCore.blib
CategoryData.dat
Console.bird
Convert.bird
Debug.bird
Entry.bird
Environment.bird
Exception.bird
Float.bird
LEB128.bird
Math.bird
Memory.bird
Object.bird
Random.bird
Reflection.bird
StandardC.bird
Stream.bird
String.bird
ToLowerData.dat
ToUpperData.dat
Types.bird
ValueType.bird
Win32.bird
x86Helper.bird
BlitzMax
.bmx
Launcher.bmx.gui.release.win32.x86.o
appstub.release.win32.x86.a
bank.release.win32.x86.a
bankstream.release.win32.x86.a
blitz.release.win32.x86.a
BlitzMax.a
BlitzMax.bird
BlitzMax.blib
d3d7max2d.release.win32.x86.a
d3d9max2d.release.win32.x86.a
directx.release.win32.x86.a
dxgraphics.release.win32.x86.a
event.release.win32.x86.a
filesystem.release.win32.x86.a
font.release.win32.x86.a
glgraphics.release.win32.x86.a
glmax2d.release.win32.x86.a
graphics.release.win32.x86.a
hook.release.win32.x86.a
keycodes.release.win32.x86.a
Launcher.bmx
libpng.release.win32.x86.a
linkedlist.release.win32.x86.a
math.release.win32.x86.a
max2d.release.win32.x86.a
opengl.release.win32.x86.a
pixmap.release.win32.x86.a
pngloader.release.win32.x86.a
polledinput.release.win32.x86.a
standardio.release.win32.x86.a
stdc.release.win32.x86.a
stream.release.win32.x86.a
system.release.win32.x86.a
textstream.release.win32.x86.a
win32.release.win32.x86.a
zlib.release.win32.x86.a
PrgLinec.bmx
Samples
Circles
Circles.bird
CppMain.bird
Fire
Fire.bird
Higher Order Functions
C#
Higher Order Functions.v11.suo
Properties
Test.bird
msvcrt.lib
Reflection
Reflection.bird
Squares
Squares.bird
Template
Template.bird
Source
Base
Bird.v11.suo
Expressions
Identifiers
Languages
NativeCode
Properties
Recognizers
Expressions
Scopes
x86
Thumbs.db
Bird.zip
crt2.o
crtbegin.o
crtend.o
libadvapi32.a
libcomctl32.a
libcomdlg32.a
libgcc.a
libgdi32.a
libglu32.a
libkernel32.a
libmingw32.a
libmingwex.a
libmoldname.a
libmsvcrt.a
libopengl32.a
libshell32.a
libstdc++.a
libuser32.a
libwinmm.a
libwsock32.a
Binaries
ar.exe
Bird.exe
fasm.exe
ld.exe
libiconv-2.dll
libintl-8.dll
Array.bird
BigInteger.bird
BinaryRW.bird
BirdCore.a
BirdCore.blib
CategoryData.dat
Console.bird
Convert.bird
Debug.bird
Entry.bird
Environment.bird
Exception.bird
Float.bird
LEB128.bird
Math.bird
Memory.bird
Object.bird
Random.bird
Reflection.bird
StandardC.bird
Stream.bird
String.bird
ToLowerData.dat
ToUpperData.dat
Types.bird
ValueType.bird
Win32.bird
x86Helper.bird
Launcher.bmx.gui.release.win32.x86.o
appstub.release.win32.x86.a
bank.release.win32.x86.a
bankstream.release.win32.x86.a
blitz.release.win32.x86.a
BlitzMax.a
BlitzMax.bird
BlitzMax.blib
d3d7max2d.release.win32.x86.a
d3d9max2d.release.win32.x86.a
directx.release.win32.x86.a
dxgraphics.release.win32.x86.a
event.release.win32.x86.a
filesystem.release.win32.x86.a
font.release.win32.x86.a
glgraphics.release.win32.x86.a
glmax2d.release.win32.x86.a
graphics.release.win32.x86.a
hook.release.win32.x86.a
keycodes.release.win32.x86.a
Launcher.bmx
libpng.release.win32.x86.a
linkedlist.release.win32.x86.a
math.release.win32.x86.a
max2d.release.win32.x86.a
opengl.release.win32.x86.a
pixmap.release.win32.x86.a
pngloader.release.win32.x86.a
polledinput.release.win32.x86.a
standardio.release.win32.x86.a
stdc.release.win32.x86.a
stream.release.win32.x86.a
system.release.win32.x86.a
textstream.release.win32.x86.a
win32.release.win32.x86.a
zlib.release.win32.x86.a
PrgLinec.bmx
PrgLinec.exe
Circles.bird
CppMain.bird
Fire.bird
Higher Order Functions.v11.suo
Test.bird
msvcrt.lib
Reflection.bird
Squares.bird
Template.bird
Bird.v11.suo
Thumbs.db
examples.zip
Examples
As.exe
AsLibs.a
PerfTest
Launcher.bmx
Squares
.bmx
Launcher.bmx
Template
Launcher.bmx
source.zip
Anonymus 7_1
Anonymus.csproj.user
Anonymus.idc
Anonymus.pidb
Anonymus.suo
Anonymus.userprefs
Base
Expressions
Lib
Long
LongDivTest.bmx
ULongConv.bmx
Math
MISZ
AsLibs.a
PerfTest
Launcher.bmx
Squares
Launcher.bmx
Template
Launcher.bmx
PrgLinec.bmx
PrgLinec.exe
Properties
Scopes
Txt
Asm.docx
Code.docx
Lib.aslib
~$Code.docx
x86
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)

Share

About the Author

Dávid Kocsis
Student
Hungary Hungary
I've been programming for 8 years. My first big project was a remake of a nice bomberman game called Dyna Blaster. When i was little i played a lot with it. Now i'm working on a new programming language and code generator.
I would like to work with someone, so feel free to contact me about it.

| Advertise | Privacy | Mobile
Web01 | 2.8.140922.1 | Last Updated 1 Jan 2013
Article Copyright 2011 by Dávid Kocsis
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid