Click here to Skip to main content
15,885,366 members
Articles / High Performance Computing / Vectorization

Bird Programming Language: Part 1

Rate me:
Please Sign up or sign in to vote.
4.92/5 (129 votes)
1 Jan 2013GPL312 min read 376.4K   2.7K   153  
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 Anonymus
{
	public enum GetIdMode
	{
		Scope,
		Function,
		Everywhere,
	}

	public abstract class IdContainer
	{
		public IdContainer Parent = null;
		public IdentifierList Identifiers = new IdentifierList();
		public object ArchData;

		public virtual bool CanIdDeclared(Identifier Id)
		{
			if (IsIdDefined<Identifier>(Id.Name.String, GetIdMode.Scope))
			{
				State.Messages.Add(MessageId.IdAlreadyDefined, Id.Name);
				return false;
			}

			if (!Helper.IsValidIdentifierName(Id.Name.String))
			{
				State.Messages.Add(MessageId.NotValidName, Id.Name);
				return false;
			}

			return true;
		}

		public bool DeclareVariables(PString Str, ModifierList Mods = null,
			VarConvMode Mode = VarConvMode.Nothing, GetIdMode IdMode = GetIdMode.Everywhere)
		{
			var List = new VarDeclList();
			if (!List.AddFromString(this, Str)) return false;
			return DeclareVariables(List, Mods, Mode, IdMode);
		}

		public bool DeclareVariables(VarDeclList List, ModifierList Mods = null,
			VarConvMode Mode = VarConvMode.Nothing, GetIdMode IdMode = GetIdMode.Everywhere)
		{
			var Variables = List.ConvToVariables(GetPlugIn(), Mods, Mode);
			return DeclareVariables(Variables, IdMode);
		}

		public virtual bool DeclareVariables(List<Variable> Variables, GetIdMode IdMode = GetIdMode.Everywhere)
		{
			var RetValue = true;
			foreach (var e in Variables)
			{
				if (e == null) RetValue = false;
				else if (CanIdDeclared(e)) Identifiers.Add(e);
				else RetValue = false;
			}

			return RetValue;
		}

		public abstract Variable CreateVariable(PString Name, Type Type, ModifierList Mods = null);

		public virtual Function CreateFunction(PString Name, FuncScopeNode Scope,
			FunctionType FuncType, ModifierList Mods = null)
		{
			var Ret = new Function(this, Name, FuncType, Scope);
			if (Mods != null && !Mods.Apply(this, Ret)) return null;
			State.Arch.OnNewIdentifier(Ret);
			return Ret;
		}

		public Function DeclareFunction(PString TypeName, PString Name, VarDeclList Params,
			PString[] Inner, ModifierList Mods = null, Function Func = null)
		{
			var RetType = GetId<Type>(TypeName, FuncRet: true);
			if (RetType == null) return null;

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

			return DeclareFunction(RetType, Name, Params, Inner, Mods, Func);
		}

		public CodeScopeNode CreateCodeScopeNode(PString[] Inner)
		{
			var Ret = new CodeScopeNode(this, Inner);
			State.Arch.OnNewContainer(Ret);
			return Ret;
		}

		public StructuredTypeScope CreateStructuredTypeScope(PString[] Inner, StructuredType Type)
		{
			var Ret = new StructuredTypeScope(this, Inner, Type);
			State.Arch.OnNewContainer(Ret);
			return Ret;
		}

		public EnumTypeScope CreateEnumTypeScope(PString[] Inner, EnumType Type)
		{
			var Ret = new EnumTypeScope(this, Inner, Type);
			State.Arch.OnNewContainer(Ret);
			return Ret;
		}

		public virtual Function DeclareFunction(FunctionType Type, PString Name,
			FuncScopeNode Scope, ModifierList Mods = null, Function Func = null)
		{
			if (Func == null)
			{
				Func = CreateFunction(Name, Scope, Type, Mods);
				if (Func == null) return null;
			}
			else
			{
				Func.FunctionScope = Scope;
				Func.Type = Type;
				Func.Name = Name;
			}

			if (this is GlobalScopeNode && State.HasMainFunc && Name.String == State.Entry)
				Func.SetUsed();

			if (!CanIdDeclared(Func)) return null;
			Identifiers.Add(Func);
			return Func;
		}

		public virtual Function DeclareFunction(Type RetType, PString Name, VarDeclList Params,
			PString[] Inner, ModifierList Mods = null, Function Func = null)
		{
			var Type = new FunctionType(this, Name, CallConv.AsCall, RetType, Params);
			Type.SetUsed();

			var Static = Mods != null ? Mods.Contains(ModifierType.Static) : false;
			var FuncScope = State.Arch.CreateFuncScope(this, Name, Type, Static, Inner);
			return DeclareFunction(Type, Name, FuncScope, Mods, Func);
		}

		public virtual void InitCodeChk(bool Unreachable = true)
		{
			foreach (var Ch in EnumChildren)
				Ch.InitCodeChk(Unreachable);
		}

		public virtual bool ChkCodeRec(CodeChkData Data, ref bool Succeeded)
		{
			Data.ChkVars(this);
			return false;
		}

		public virtual bool FinishCodeChk()
		{
			var Ret = true;
			foreach (var Ch in EnumChildren)
				if (!Ch.FinishCodeChk()) Ret = false;

			return Ret;
		}

		public bool IsSubContainer(IdContainer Container)
		{
			if (this == Container) return true;
			else if (Parent != null) return Parent.IsSubContainer(Container);
			else return false;
		}

		public virtual void CalcExprRegs()
		{
			foreach (var Ch in EnumChildren)
				Ch.CalcExprRegs();
		}

		public IdContainer(IdContainer Parent)
		{
			this.Parent = Parent;
		}

		public virtual MultiPlugIn GetPlugIn()
		{
			return new GlobalPlugIn(this);
		}

		public virtual IEnumerable<IdContainer> EnumChildren
		{
			get { yield break; }
		}

		public IEnumerable<LocalVariable> EnumLocals
		{
			get
			{
				foreach (var e in Identifiers)
					if (e is LocalVariable)
						yield return e as LocalVariable;
			}
		}

		public virtual CompilerState State
		{
			get { return GlobalScope.State; }
		}

		public virtual PreprocessorState PreState
		{
			get { return GlobalScope.PreState; }
		}

		public T GetScope<T>() where T : IdContainer
		{
			var Scope = this;
			while (Scope != null && !(Scope is T))
				Scope = Scope.Parent;

			return Scope as T;
		}

		GlobalScopeNode _GblScope;
		public GlobalScopeNode GlobalScope
		{
			get
			{
				if (_GblScope == null) _GblScope = GetScope<GlobalScopeNode>();
				return _GblScope;
			}
		}

		FuncScopeNode _FuncScope;
		public FuncScopeNode FuncScope
		{
			get
			{
				if (_FuncScope == null) _FuncScope = GetScope<FuncScopeNode>();
				return GetScope<FuncScopeNode>();
			}
		}

		public Type GetRetType(Type Type0, Type Type1)
		{
			if (Type0 is AutomaticType) return Type1;
			if (Type1 is AutomaticType) return Type0;

			if (Type0 is NumberType && Type1 is NumberType)
			{
				System.Type Tp = null;
				if (Type0 is FloatType || Type1 is FloatType) Tp = typeof(FloatType);
				else if (Type0 is SignedType || Type1 is SignedType) Tp = typeof(SignedType);
				else Tp = typeof(UnsignedType);

				var mSize = Type0.Size;
				if (Type1.Size > mSize) mSize = Type1.Size;
				return GetType(Tp, mSize);
			}

			var Tuple0 = Type0 as TupleType;
			var Tuple1 = Type1 as TupleType;
			if (Tuple0 != null && Tuple1 != null && Tuple0.Members.Count == Tuple1.Members.Count)
			{
				var Members = new IdentifierList();
				for (var i = 0; i < Tuple0.Members.Count; i++)
				{
					var Var0 = Tuple0.Members[i] as MemberVariable;
					var Var1 = Tuple1.Members[i] as MemberVariable;

					var Name = new PString("%" + i.ToString());
					var T = GetRetType(Var0.Type, Var1.Type);
					var Member = new MemberVariable(this, Name, T);
					State.Arch.OnNewIdentifier(Member);
					Members.Add(Member);
				}

				var RetType = new TupleType(this, Members);
				State.Arch.OnNewIdentifier(RetType);
				return RetType;
			}

			return Type0;
		}

		private T GetBasicType<T>(string Name) where T : Identifier
		{
			foreach (var Id in GlobalScope.BasicTypes)
				if (Id.Name.String == Name && Id is T)
					return Id as T;

			return null;
		}

		public NumberType GetType(System.Type Type, int Size)
		{
			foreach (var Id in GlobalScope.NumTypes)
			{
				var nt = Id as NumberType;
				if (nt != null && nt.Size == Size && Type.IsInstanceOfType(Id))
					return nt;
			}

			return null;
		}

		public virtual void ChkUnusedIds()
		{
			return;
			foreach (var e in Identifiers)
				if (!e.Used && e.DeclInThis)
					State.Messages.Add(MessageId.UnusedId, e.Name);

			foreach (var Ch in EnumChildren)
				Ch.ChkUnusedIds();
		}

		public virtual ExpressionNode GetExprRec(PString Name,
			ExprPlugIn PlugIn = null, GetIdMode Mode = GetIdMode.Everywhere)
		{
			return null;
		}

		public T GetId<T>(PString Code, GetIdMode Mode = GetIdMode.Everywhere,
			bool FuncRet = false, bool EnableMessages = true) where T : Identifier
		{
			Code = BracketHelper.TrimFZ(Code);
			if (Code.StrLen > 0 && Code[Code.StrLen - 1] == '*')
			{
				var ChildC = Code.TrimmedSubstring(0, Code.Length - 1);
				var Child = GetId<Type>(ChildC, Mode, FuncRet, EnableMessages);
				if (Child == null) return null;

				var Ret = Child.CreatePointerType() as T;
				if (Ret == null && EnableMessages)
					State.Messages.Add(MessageId.UnknownId, Code);

				return Ret;
			}

			//--------------------------------------------------------------------------
			if (Code.String.StartsWith("ref"))
			{
				var ChildC = Code.TrimmedSubstring(3);
				var Child = GetId<Type>(ChildC, Mode, FuncRet, EnableMessages);
				if (Child == null) return null;

				var Ret = Child.CreateRefType() as T;
				if (Ret == null && EnableMessages)
					State.Messages.Add(MessageId.UnknownId, Code);

				return Ret;
			}

			//--------------------------------------------------------------------------
			var Pos = Code.String.Find('.', InZ: true, Back: true);
			if (Pos != -1)
			{
				var Left = Code.Substring(0, Pos);
				var Right = Code.Substring(Pos + 1);

				var Type = GetId<StructuredType>(Left, Mode, FuncRet, EnableMessages);
				if (Type == null) return null;

				var Ret = Type.GetId<T>(Right.String);
				if (Ret == null && EnableMessages)
					State.Messages.Add(MessageId.UnknownId, Right);

				return Ret;
			}

			//--------------------------------------------------------------------------
			Pos = Code.String.Find(',', InZ: true, Back: true);
			if (Pos != -1) return CreateTupleType(Code, EnableMessages: EnableMessages) as T;

			if (!Helper.IsValidIdentifierName(Code.String))
			{
				if (FuncRet)
				{
					var Name = Code.Word(InZ: true, Back: true);
					if (!Helper.IsValidIdentifierName(Name.String))
					{
						if (EnableMessages)
						{
							if (Name == null) Name = Code;
							State.Messages.Add(MessageId.NotValidName, Name);
						}

						return null;
					}

					var Type = GetId<Type>(Code, Mode, FuncRet, EnableMessages);
					if (Type == null) return null;

					if (Type is VoidType)
					{
						if (EnableMessages) State.Messages.Add(MessageId.CannotBeThisType, Code);
						return null;
					}
					else if (Type is AutomaticType)
					{
						if (EnableMessages) State.Messages.Add(MessageId.Untyped, Code);
						return null;
					}

					var Ret = new NamedFuncRetType(this, Name, Type) as T;
					if (Ret == null && EnableMessages)
						State.Messages.Add(MessageId.UnknownId, Code);

					return Ret;
				}

				return null;
			}


			//--------------------------------------------------------------------------
			var Id = GetIdRec<T>(Code, Mode);
			if (Id == null && EnableMessages)
				State.Messages.Add(MessageId.UnknownId, Code);

			return Id;
		}

		public virtual T GetIdRec<T>(PString Name, GetIdMode Mode = GetIdMode.Everywhere,
			bool SearchedInBasicTypes = false) where T : Identifier
		{
			if (!SearchedInBasicTypes)
			{
				var Ret = GetBasicType<T>(Name.String);
				if (Ret != null) return Ret;
				else SearchedInBasicTypes = true;
			}

			var Id = Identifiers.GetIdRec<T>(Name.String);
			if (Id != null) return Id;

			if (Parent != null && Mode != GetIdMode.Scope)
			{
				var F = FuncScope;
				if (Mode != GetIdMode.Function || (Parent.FuncScope == F && F != null))
					return Parent.GetIdRec<T>(Name, Mode, SearchedInBasicTypes);
			}

			return null;
		}

		public TupleType CreateTupleType(PString Name, bool EnableUnnamed = true, bool EnableMessages = true)
		{
			var Type = new TupleType(this, null);
			Type.Members = new IdentifierList();
			var DeclList = new VarDeclList();
			if (!DeclList.AddFromString(this, Name, EnableUnnamed, false, EnableMessages))
				return null;

			for (var i = 0; i < DeclList.Count; i++)
			{
				var Decl = DeclList[i];
				if (Decl.InitString != null)
				{
					if (EnableMessages) State.Messages.Add(MessageId.NotExpected, Decl.InitString);
					return null;
				}

				if (Decl.Name == null)
					Decl.Name = new PString("%" + i.ToString());
				else Type.Named = true;

				var Var = new MemberVariable(this, Decl.Name, Decl.Type);
				State.Arch.OnNewIdentifier(Var);
				Type.Members.Add(Var);
			}

			Type.CalcName();
			Type.CalcPositions();
			State.Arch.OnNewIdentifier(Type);
			return Type;
		}

		public bool IsIdDefined<T>(string Name, GetIdMode Mode = GetIdMode.Everywhere) where T : Identifier
		{
			var Id = Identifiers.GetIdRec<T>(Name);
			if (Id != null) return true;

			if (Parent != null && Mode != GetIdMode.Scope)
			{
				var F = FuncScope;
				if (Mode != GetIdMode.Function || (Parent.FuncScope == F && F != null))
					return Parent.IsIdDefined<T>(Name, Mode);
			}

			return false;
		}

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

		public bool StartsWithType(PString Str)
		{
			var T = Str.Word(ModThis: false, WordStart: true);
			return T.String == "var" || T.String == "ref" || GetId<Type>(T, EnableMessages: false) != null;
		}

	}

}

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