Click here to Skip to main content
11,634,815 members (68,471 online)
Click here to Skip to main content
Add your own
alternative version

Bird Programming Language: Part 1

, 1 Jan 2013 GPL3 217.6K 2.4K 153
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 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)

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.

You may also be interested in...

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.150728.1 | Last Updated 1 Jan 2013
Article Copyright 2011 by Dávid Kocsis
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid