Click here to Skip to main content
15,891,905 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 382K   2.7K   153  
A new general purpose language that aims to be fast, high level and simple to use.
using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;

namespace Anonymus
{
	public class IdentifierList : List<Identifier>
	{
		public T GetIdRec<T>(string Name) where T : Identifier
		{
			var PrevList = new IdentifierList();
			PrevList.AddRange(this);

			foreach (var Id in this)
				if ((Name == null || Id.Name.String == Name) && Id is T)
					return Id as T;

			return null;
		}
	}

	public abstract class Identifier
	{
		public IdContainer Container;
		public Architecture Arch;
		public PString Name;
		public object ArchData;

		public bool IsStatic = false;
		public bool IsSealed = false;

		public bool CanBeInReg;
		public bool Used = false;
		public bool DeclInThis = true;

		public virtual void SetUsed()
		{
			Used = true;
		}

		string _AsmName = null;
		public string AsmName
		{
			get
			{
				if (_AsmName == null)
				{
					_AsmName = "_" + Name.String;

					var Structured = Container as StructuredTypeScope;
					if (Structured != null) _AsmName = Structured.GetAsmName() + _AsmName;
				}

				return _AsmName;
			}

			set
			{
				_AsmName = value;
			}
		}

		public Identifier(IdContainer Container, PString Name)
		{
			this.Name = Name;
			this.CanBeInReg = true;
			this.IsStatic = false;
			this.Container = Container;

			if (Container != null)
				this.Arch = Container.State.Arch;
		}

		public virtual void GetAsmCode(Compiler Comp, GetAsmCodeMode Mode)
		{
		}
	}

	public class ChkAssignedId
	{
		public Identifier Id;
		public List<ExpressionNode> Nodes;
		public bool Used;

		public ChkAssignedId(Identifier Id, ExpressionNode Node, bool Used = false)
			: this(Id, new List<ExpressionNode>() { Node })
		{
		}

		public ChkAssignedId(Identifier Id, List<ExpressionNode> Nodes, bool Used = false)
		{
			this.Id = Id;
			this.Nodes = Nodes;
			this.Used = Used;
		}
	}

	public class CodeChkData
	{
		public List<ChkAssignedId> Vars = new List<ChkAssignedId>();

		public ChkAssignedId GetId(Identifier Id)
		{
			foreach (var e in Vars)
				if (e.Id == Id) return e;

			return null;
		}

		public void ChkVars(IdContainer Container)
		{
			for (var i = 0; i < Vars.Count; i++)
				if (!Container.IsSubContainer(Vars[i].Id.Container))
				{
					Vars.RemoveAt(i);
					i--;
				}
		}

		public bool IsAssigned(Identifier Id)
		{
			foreach (var e in Vars)
				if (e.Id == Id) return true;

			return false;
		}

		public void OnAssign(CompilerState State, Identifier Id, ExpressionNode Node)
		{
			var I = GetId(Id);
			if (I == null)
			{
				I = new ChkAssignedId(Id, Node);
				Vars.Add(I);
			}
			else
			{
				I.Nodes.Clear();
				I.Nodes.Add(Node);

				if (I.Used)
				{
#warning WARNING
				}
			}
		}

		public CodeChkData Copy()
		{
			var Ret = new CodeChkData();
			Ret.Vars.AddRange(Vars);
			return Ret;
		}
	}

	public static class CodeChkDataExtensions
	{
		public static CodeChkData Intersect(this IEnumerable<CodeChkData> Datas)
		{
			var Ret = new CodeChkData();
			var First = true;

			foreach (var Data in Datas)
			{
				if (First)
				{
					Ret.Vars.AddRange(Data.Vars);
					First = false;
					continue;
				}

				var Old = Ret.Vars.ToArray();
				Ret.Vars.Clear();

				foreach (var e in Data.Vars)
					foreach (var f in Old)
						if (f.Id == e.Id)
						{
							var Nodes = f.Nodes.Union(e.Nodes).ToList();
							Ret.Vars.Add(new ChkAssignedId(e.Id, Nodes, f.Used && e.Used));
							break;
						}
			}

			return Ret;
		}
	}

	public enum ModifierType
	{
		Static,
		Final,

		Public,
		Private,
		Protected,

		StdCall,
		CDecl,
		AsCall,

		AsmName,
	}

	public class Modifier
	{
		public ModifierType Type;
		public PString FLine;
		public PString Name;
		public List<PString> Params;

		public Modifier(ModifierType Type, PString Name, PString FLine, List<PString> Params = null)
		{
			this.Type = Type;
			this.Name = Name;
			this.FLine = FLine;
			this.Params = Params;
		}
	}

	public class ModifierList : List<Modifier>
	{
		public Modifier GetModifier(ModifierType ModType)
		{
			foreach (var e in this)
				if (e.Type == ModType) return e;

			return null;
		}

		public bool Contains(ModifierType ModType)
		{
			return GetModifier(ModType) != null;
		}

		bool ChkCallConv(CompilerState State, Identifier Id, ModifierType ModType, ref bool CallConv)
		{
			var Mod = GetModifier(ModType);
			if (Mod == null) return false;

			if (!(Id is Function))
			{
				State.Messages.Add(MessageId.CallConvErr, Mod.Name);
				return false;
			}
			else if (CallConv)
			{
				State.Messages.Add(MessageId.NotExpected, Mod.Name);
				return false;
			}

			return true;
		}

		public bool Apply(IdContainer Container, Identifier Id)
		{
			var State = Container.State;
			var CallConv = false;
			var Mod = (Modifier)null;

			//--------------------------------------------------------------------------------------
			if ((Mod = GetModifier(ModifierType.Static)) != null)
			{
				if (!(Id is ClassType) && !(Id.Container is StructuredTypeScope))
				{
					State.Messages.Add(MessageId.StaticErr, Mod.Name);
					return false;
				}

				Id.IsStatic = true;
			}
			else
			{
				var SCont = Id.Container as StructuredTypeScope;
				if (SCont != null && SCont.Type.IsStatic)
				{
					State.Messages.Add(MessageId.NonStaticInStaticClass, Id.Name);
					return false;
				}
			}

			//--------------------------------------------------------------------------------------
			if ((Mod = GetModifier(ModifierType.Final)) != null)
			{
				if (!(Id is StructuredType) && !(Id.Container is StructuredTypeScope))
				{
					State.Messages.Add(MessageId.SealedErr, Mod.Name);
					return false;
				}
				else if (Id.IsStatic)
				{
					State.Messages.Add(MessageId.StaticSealed, Mod.Name);
					return false;
				}

				Id.IsSealed = true;
			}

			//--------------------------------------------------------------------------------------
			if ((Mod = GetModifier(ModifierType.AsmName)) != null)
			{
				if (Mod.Params.Count != 1)
				{
					State.Messages.Add(MessageId.ParamCount, Mod.FLine);
					return false;
				}

				var PlugIn = new GlobalPlugIn(Container);
				PlugIn.GetPlugIn<TypeMgrPlugIn>().RetType = Container.GlobalScope.CStrType;
				var Node = Expressions.Recognize(Mod.Params[0], PlugIn, false);
				if (Node == null) return false;
				Id.AsmName = (Node as ConstExpressionNode).String;
			}

			//--------------------------------------------------------------------------------------
			if (ChkCallConv(State, Id, ModifierType.StdCall, ref CallConv))
			{
				var Func = Id as Function;
				Func.Type.Conv = Anonymus.CallConv.StdCall;
			}

			if (ChkCallConv(State, Id, ModifierType.CDecl, ref CallConv))
			{
				var Func = Id as Function;
				Func.Type.Conv = Anonymus.CallConv.CDecl;
			}

			if (ChkCallConv(State, Id, ModifierType.AsCall, ref CallConv))
			{
				var Func = Id as Function;
				Func.Type.Conv = Anonymus.CallConv.AsCall;
			}

			//--------------------------------------------------------------------------------------
			return true;
		}
	}

	public class ModifierAttributes
	{
		public ModifierType Type;
		public string Name;
		public bool AllowParameters;

		public ModifierAttributes(ModifierType Type, string Name, bool AllowParameters = false)
		{
			this.Type = Type;
			this.Name = Name;
			this.AllowParameters = AllowParameters;
		}
	}

	public static class Modifiers
	{
		public static List<ModifierAttributes> ModifiersLst;

		static Modifiers()
		{
			ModifiersLst = new List<ModifierAttributes>();
			ModifiersLst.Add(new ModifierAttributes(ModifierType.Static, "static"));
			ModifiersLst.Add(new ModifierAttributes(ModifierType.Final, "final"));

			ModifiersLst.Add(new ModifierAttributes(ModifierType.Public, "public"));
			ModifiersLst.Add(new ModifierAttributes(ModifierType.Protected, "protected"));
			ModifiersLst.Add(new ModifierAttributes(ModifierType.Private, "private"));

			ModifiersLst.Add(new ModifierAttributes(ModifierType.StdCall, "stdcall"));
			ModifiersLst.Add(new ModifierAttributes(ModifierType.CDecl, "cdecl"));
			ModifiersLst.Add(new ModifierAttributes(ModifierType.AsCall, "ascall"));

			ModifiersLst.Add(new ModifierAttributes(ModifierType.AsmName, "asmname", true));
		}

		public static ModifierList GetModifiers(CompilerState State, ref PString Line)
		{
			var Ret = new ModifierList();
			while (true)
			{
				var FLine = Line.Copy();
				var ModifierStr = Line.Word(WordStart: true, InZ: true);
				var Word = ModifierStr.Word();

				var Index = 0;
				var Found = false;
				foreach (var e in ModifiersLst)
				{
					if (e.Name == Word.String)
					{
						if (Ret.Contains(e.Type))
						{
							State.Messages.Add(MessageId.NotExpected, Word);
							return null;
						}

						var Params = (List<PString>)null;
						if (ModifierStr.StrLen > 0 && ModifierStr[0] == '(')
						{
							var ZPos = BracketHelper.ZPos(ModifierStr.String);
							if (ZPos == -1)
							{
								State.Messages.Add(MessageId.ZNumErr, FLine);
								return null;
							}

							var StrParams = ModifierStr.TrimmedSubstring(1, ZPos - 1);
							ModifierStr = ModifierStr.TrimmedSubstring(ZPos + 1);
							Params = new List<PString>();
							var Recognizer = State.Language.ArgRecognizer;
							if (!Recognizer.SplitArgs(State, StrParams, Params))
								return null;

							if (!e.AllowParameters)
							{
								State.Messages.Add(MessageId.ModParamsNotAllowed, StrParams);
								return null;
							}
						}
						else if (e.AllowParameters)
						{
							State.Messages.Add(MessageId.MissingParam, Word);
							return null;
						}

						if (ModifierStr.StrLen > 0)
						{
							State.Messages.Add(MessageId.NotExpected, ModifierStr);
							return null;
						}

						Ret.Add(new Modifier(e.Type, Word, ModifierStr, Params));
						Found = true;
						break;
					}

					Index++;
				}

				if (!Found)
				{
					Line = FLine;
					break;
				}
			};

			return Ret;
		}
	}

	public enum CallConv
	{
		StdCall,
		CDecl,
		AsCall,
	}

	public class Function : Identifier
	{
		public FuncScopeNode FunctionScope;
		public FunctionType Type;

		public Function(IdContainer Container, PString Name, FunctionType Type, FuncScopeNode Scope)
			: base(Container, Name)
		{
			this.Type = Type;
			this.FunctionScope = Scope;
		}

		public override void GetAsmCode(Compiler Comp, GetAsmCodeMode Mode)
		{
			if (Mode == GetAsmCodeMode.Code && FunctionScope != null)
			{
				Comp.Label(AsmName);
				Comp.Append(FunctionScope.GetFunctionCode());
				Comp.Append("\n");
			}
		}
	}

	public class MemberFunction : Function
	{
		public int Offset = -1;

		public MemberFunction(IdContainer Container, PString Name, FunctionType Type, FuncScopeNode Scope)
			: base(Container, Name, Type, Scope)
		{
		}
	}

	public class ConstructorFunction : Function
	{
		public ConstructorFunction(IdContainer Container, PString Name, FunctionType Type, FuncScopeNode Scope)
			: base(Container, Name, Type, Scope)
		{
			;
		}
	}

	public abstract class Variable : Identifier
	{
		public Type Type;
		public ExpressionNode InitValue;
		public ConstData GlbInitVal;
		public PString InitString;
		public bool ReadOnly = false;

		public Variable(IdContainer Container, PString Name, Type Type)
			: base(Container, Name)
		{
			this.Type = Type;
		}

		public bool CalcValue(ExprPlugIn PlugIn, bool CreateAssignInitValues = false)
		{
			var TypeMgrPlugIn = PlugIn.GetPlugIn<TypeMgrPlugIn>();
			if (TypeMgrPlugIn != null)
			{
				if (!(Type is AutomaticType))
					TypeMgrPlugIn.RetType = Type;
				else TypeMgrPlugIn.RetType = null;
			}

			InitValue = null;
			if (InitString != null)
			{
				InitValue = Expressions.NewExpressionTree(InitString, PlugIn, End: !CreateAssignInitValues);
				if (InitValue == null) return false;

				if (InitValue is ConstExpressionNode)
				{
					var ConstVal = InitValue as ConstExpressionNode;
					GlbInitVal = ConstVal.Value;
				}

				if (Type is AutomaticType)
					Type = InitValue.Type;

				if (CreateAssignInitValues)
				{
					InitValue = InitValue.CreateAssignExpr(this, InitString, PlugIn, true);
					if (InitValue == null) return false;
				}
			}
			else if (Type is AutomaticType)
			{
				PlugIn.State.Messages.Add(MessageId.Untyped, Name);
				return false;
			}

			return true;
		}
	}

	public class GlobalVariable : Variable
	{
		public GlobalVariable(IdContainer Container, PString Name, Type Type)
			: base(Container, Name, Type)
		{
		}

		public override void GetAsmCode(Compiler Comp, GetAsmCodeMode Mode)
		{
			if (Mode == GetAsmCodeMode.Data)
			{
				Comp.Label(AsmName);
				Type.Declare(Comp, GlbInitVal);
				Comp.Append("\n");
			}
		}
	}

	public class LocalVariable : Variable
	{
		public bool IsParameter;
		public bool PreAssigned;
		public bool RetVar = false;

		public LocalVariable(IdContainer Container, PString Name, Type Type)
			: base(Container, Name, Type)
		{
		}
	}

	public class MemberVariable : Variable
	{
		public int Offset;

		public MemberVariable(IdContainer Container, PString Name, Type Type)
			: base(Container, Name, Type)
		{
		}
	}

	public abstract class PackedId : Identifier
	{
		public Type Type;
		public abstract ExpressionNode Extract(ExprPlugIn PlugIn);

		public PackedId(IdContainer Container, PString Name, Type Type)
			: base(Container, Name)
		{
			this.Type = Type;
		}
	}

	public class PackedMemberId : PackedId
	{
		public Identifier Id;
		public Identifier Member;

		public PackedMemberId(IdContainer Container, PString Name, Type Type, Identifier Id, Identifier Member)
			: base(Container, Name, Type)
		{
			this.Id = Id;
			this.Member = Member;
		}

		public override ExpressionNode Extract(ExprPlugIn PlugIn)
		{
			var Id = (ExpressionNode)new IdExpressionNode(this.Id, Name);
			var Member = (ExpressionNode)new IdExpressionNode(this.Member, Name);
			if (PlugIn != null && (Id = PlugIn.NewNode(Id)) == null) return null;
			if (PlugIn != null && (Member = PlugIn.NewNode(Member)) == null) return null;

			var NewCh = new List<ExpressionNode>() { Id, Member };
			var Ret = (ExpressionNode)new OpExpressionNode(Operator.Member, NewCh, Name);
			if (Ret != null && (Ret = PlugIn.NewNode(Ret)) == null) return null;
			return Ret;
		}
	}
}

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