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

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;
using System.Numerics;

namespace Bird
{
	public class CodeFile
	{
		struct LineData
		{
			public int Position;
			public int Indent;
			public ConditionResult IsEmtpy;

			public void Update()
			{
				Indent = -1;
				IsEmtpy = ConditionResult.Unknown;
			}
		}

		public DataList Data = new DataList();
		public string Path;
		public string Content;

		LineData[] Lines;
		int TabSize;

		public void Update()
		{
			for (var i = 0; i < Lines.Length; i++)
				Lines[i].Update();
		}

		public void Update(int Line, int Count = 1)
		{
			if (Line < 0 || Line >= Lines.Length)
				throw new ArgumentOutOfRangeException("Line");
			
			if (Count < 0 || Line + Count > Lines.Length)
				throw new ArgumentOutOfRangeException("Count");

			for (var i = Line; i < Line + Count; i++)
				Lines[i].Update();
		}

		public void VerifyLineIndex(int Position, int Line)
		{
			if (Line < 0 || Line >= Lines.Length)
				throw new ArgumentOutOfRangeException("Line");

			if (Lines[Line].Position > Position)
				throw new ArgumentOutOfRangeException("Line");

			if (Line + 1 < Lines.Length && Lines[Line + 1].Position <= Position)
				throw new ArgumentOutOfRangeException("Line");
		}

		public unsafe void RemoveCode(int Index, int Length)
		{
			RemoveCode(Index, Length, GetLine(Index));
		}

		public unsafe void RemoveCode(int Index, int Length, int Line)
		{
			if (Index < 0 || Index >= Content.Length)
				throw new ArgumentOutOfRangeException("Index");

			if (Length < 0 || Index + Length > Content.Length)
				throw new ArgumentOutOfRangeException("Length");

			fixed (char* Ptr = Content)
			{
				for (var i = Index; i < Index + Length; i++)
				{
					if (Ptr[i] != '\n' && Ptr[i] != '\r')
						Ptr[i] = ' ';
				}
			}

			Update(Line, GetLineCount(Line, Index + Length - 1));
		}

		public void RemoveCode(CodeString String)
		{
			if (String.File != this)
				throw new ArgumentException(null, "String");

			RemoveCode(String.Index, String.Length, String.Line);
		}

		public int GetLinePosition(int Line)
		{
			if (Line < 0 || Line >= Lines.Length)
				throw new ArgumentOutOfRangeException("Line");

			return Lines[Line].Position;
		}

		public CodeFile(string Path, string Content, int TabSize = 1)
		{
			this.Path = Path;
			this.Content = Content;
			this.TabSize = TabSize;

			if (Path == null) throw new ArgumentNullException("Path");
			if (Content == null) throw new ArgumentNullException("Content");
			if (TabSize < 0) throw new ArgumentOutOfRangeException("TabSize");

			InitializeLines();
		}

		public void InitializeLines()
		{
			var LineCount = Helper.GetLineCount(Content);
			Lines = new LineData[LineCount];

			LineCount = 0;
			Helper.ProcessNewLines(Content, Pos =>
				{
					if (LineCount > 0 && Lines[LineCount - 1].Position >= Pos)
						throw new ApplicationException("Invalid line position");

					Lines[LineCount].Position = Pos;
					LineCount++;
				});

			Update();
		}

		int CalculateLineIndent(int Line)
		{
			var Indent = 0;
			for (var i = Lines[Line].Position; i < Content.Length; i++)
			{
				var Chr = Content[i];
				if (Chr == '\t') Indent += TabSize;
				else if (Chr == ' ') Indent++;
				else if (Chr == '\r' || Chr == '\n') return 0;
				else break;
			}

			return Indent;
		}

		ConditionResult CalculateIsEmpty(int Line)
		{
			var Until = Lines[Line].Position + GetLineLength(Line);
			for (var i = Lines[Line].Position; i < Until; i++)
				if (!char.IsWhiteSpace(Content[i])) return ConditionResult.False;

			return ConditionResult.True;
		}

		public bool IsEmptyLine(int Line)
		{
			if (Line < 0 || Line >= Lines.Length)
				throw new ArgumentOutOfRangeException("Line");

			var Result = Lines[Line].IsEmtpy;
			if (Result == ConditionResult.Unknown)
			{
				Result = CalculateIsEmpty(Line);
				Lines[Line].IsEmtpy = Result;
			}

			return Result == ConditionResult.True;
		}

		public int GetLineCount()
		{
			return Lines.Length;
		}

		public int GetLineCount(int FirstLine, int End = int.MaxValue)
		{
			if (FirstLine < 0 || FirstLine >= Lines.Length)
				throw new ArgumentOutOfRangeException("FirstLine");

			var Result = 0;
			for (var i = FirstLine; i < Lines.Length; i++)
			{
				if (Lines[i].Position > End) break;
				else Result++;
			}

			return Result;
		}

		public int GetIndent(int Line)
		{
			if (Line < 0 || Line >= Lines.Length)
				throw new ArgumentOutOfRangeException("Line");

			if (IsEmptyLine(Line))
				return 0;

			var Result = Lines[Line].Indent;
			if (Result == -1)
			{
				Result = CalculateLineIndent(Line);
				Lines[Line].Indent = Result;
			}

			return Result;
		}

		public int GetDistance(int Line, int Position)
		{
			if (Line < 0 || Line >= Lines.Length)
				throw new ArgumentOutOfRangeException("Line");

			if (Position < 0 || Position > Content.Length)
				throw new ArgumentOutOfRangeException("Position");

			if (TabSize == 1)
			{
				return Position - Lines[Line].Position;
			}
			else
			{
				var Result = 0;
				for (var i = Lines[Line].Position; i < Position; i++)
				{
					if (Content[i] != '\t') Result++;
					else Result += TabSize;
				}

				return Result;
			}
		}

		public int GetDistanceOrIndent(int Line, int Position)
		{
			if (Line < 0 || Line >= Lines.Length)
				throw new ArgumentOutOfRangeException("Line");

			if (Position < 0 || Position > Content.Length)
				throw new ArgumentOutOfRangeException("Position");

			var Distance = GetDistance(Line, Position);
			var Indent = GetIndent(Line);
			return Distance < Indent ? Indent : Distance;
		}

		public int GetLineLength(int Line)
		{
			if (Line < 0 || Line >= Lines.Length)
				throw new ArgumentOutOfRangeException("Line");

			var Start = Lines[Line].Position;
			if (Line + 1 == Lines.Length) return Content.Length - Start;
			else return Lines[Line + 1].Position - Start;
		}

		public int GetLineLength(int Line, int Position)
		{
			if (Line < 0 || Line >= Lines.Length)
				throw new ArgumentOutOfRangeException("Line");

			if (Position < 0 || Position > Content.Length)
				throw new ArgumentOutOfRangeException("Position");

			if (Line + 1 == Lines.Length) return Content.Length - Position;
			else return Lines[Line + 1].Position - Position;
		}

		public CodeString GetLines(int Line, int Count = 1)
		{
			if (Line < 0 || Line >= Lines. Length)
				throw new ArgumentOutOfRangeException("Line");

			if (Count < 0 || Line + Count > Lines.Length)
				throw new ArgumentOutOfRangeException("Count");

			if (Line + Count == Lines.Length)
			{
				var Pos = Lines[Line].Position;
				return new CodeString(this, Pos, Content.Length - Pos, Line);
			}
			else
			{
				var Pos = Lines[Line].Position;
				var Length = Lines[Line + Count].Position - Pos;
				return new CodeString(this, Pos, Length, Line);
			}
		}

		public int GetLine(int Index)
		{
			if (Index < 0 || Index >= Content.Length)
				throw new ArgumentOutOfRangeException("Index");

			for (var i = 0; i < Lines.Length; i++)
				if (Lines[i].Position > Index) return i - 1;

			return Lines.Length;
		}
	}

	public struct CodeString
	{
		public CodeFile File;
		public StringSlice String;
		public int Line;

		public bool IsValid
		{
			get { return String.String != null; } 
		}

		public int Length
		{
			get { return String.Length; }
		}

		public int Index
		{
			get { return String.Index; }
		}

		public CodeString(CodeFile File, int Index, int Length, int Line)
		{
			this.File = File;
			this.String = new StringSlice(File.Content, Index, Length);
			this.Line = Line;
			File.VerifyLineIndex(String.Index, Line);
		}

		public CodeString(CodeFile File, int Index, int Length)
		{
			this.File = File;
			this.String = new StringSlice(File.Content, Index, Length);
			this.Line = File.GetLineCount(0, Index) - 1;
		}

		public CodeString(CodeFile File, StringSlice String)
		{
			if (!object.ReferenceEquals(File.Content, String.String))
				throw new ArgumentException("The string can't be part of the file", "String");

			this.File = File;
			this.String = String;
			this.Line = File.GetLineCount(0, String.Index) - 1;
		}

		public CodeString(CodeFile File)
		{
			this.File = File;
			this.String = new StringSlice(File.Content);
			this.Line = 0;
		}

		public CodeString(StringSlice String)
		{
			this.File = null;
			this.String = String;
			this.Line = 0;
		}

		public CodeString(string String)
		{
			this.File = null;
			this.String = new StringSlice(String);
			this.Line = 0;
		}

		public bool Contains(char Char)
		{
			return Find(Char) != -1;
		}

		public bool Contains(string String)
		{
			return Find(String) != -1;
		}

		public IEnumerable<CodeString> EnumLines()
		{
			var Line = this.Line;
			while (HasLine(Line))
			{
				yield return GetLine(Line);
				Line++;
			}
		}

		public CodeString Intersection(int Index, int Length)
		{
			if (!IsValid) throw new InvalidOperationException();
			if (Index < this.Index)
			{
				Length -= this.Index - Index;
				Index = this.Index;
			}

			var MinLength = Length < this.Length ? Length : this.Length;
			var NewLine = Line;
			if (Line < File.GetLineCount() - 1)
				NewLine += File.GetLineCount(Line + 1, Index);

			return new CodeString(File, Index, MinLength, NewLine);
		}

		public CodeString GetLine(int Line)
		{
			if (!IsValid) throw new InvalidOperationException();
			if (Line < 0 || Line >= File.GetLineCount())
				throw new ArgumentOutOfRangeException("Line");

			if (this.Line == Line) return FirstLine;
			if (!HasLine(Line)) return new CodeString();

			var Start = File.GetLinePosition(Line);
			var Length = File.GetLineLength(Line);
			return Intersection(Start, Length);
		}

		public CodeString GetLines(int Line, int Count = 1)
		{
			if (!IsValid) throw new InvalidOperationException();
			var AllLines = File.GetLineCount();
			if (Line < 0 || Line >= AllLines)
				throw new ArgumentOutOfRangeException("Line");

			if (Count < 0 || Line + Count > AllLines)
				throw new ArgumentOutOfRangeException("Count");

			var Start = File.GetLinePosition(Line);
			var EndPos = Line + Count == AllLines ? File.Content.Length
				: File.GetLinePosition(Line + Count);

			return Intersection(Start,  EndPos - Start);
		}

		public int LeftWhiteSpaces
		{
			get { return String.LeftWhiteSpaces; }
		}

		public int RightWhiteSpaces
		{
			get { return String.RightWhiteSpaces; }
		}

		public bool HasLine(int Line)
		{
			if (!IsValid) throw new InvalidOperationException();

			if (Length == 0) return false;
			if (this.Line > Line || File.GetLineCount() <= Line) return false;
			return File.GetLinePosition(Line) <= End;
		}

		public int LineCount
		{
			get
			{
				if (!IsValid) throw new InvalidOperationException();
				return 1 + File.GetLineCount(Line + 1, End);
			}
		}

		public char this[int Index]
		{
			get { return String[Index]; }
		}

		public int FirstLineLength
		{
			get
			{
				if (!IsValid) throw new InvalidOperationException();
				var Ret = File.GetLineLength(Line, Index);
				return Ret > Length ? Length : Ret;
			}
		}

		public CodeString FirstLine
		{
			get
			{
				if (!IsValid) throw new InvalidOperationException();
				return Substring(0, FirstLineLength);
			}
		}

		public int End
		{
			get
			{
				if (!IsValid) throw new InvalidOperationException(); 
				return Index + Length - 1;
			}
		}

		public CodeString Substring(StringSlice String)
		{
			if (!object.ReferenceEquals(this.String.String, String.String))
				throw new ArgumentException("The string must be part of the file", "String");

			return Substring(String.Index - this.String.Index, String.Length);
		}

		public CodeString Substring(int Index, int Length)
		{
			if (!IsValid) throw new InvalidOperationException();
			Helper.Verify(this.Length, Index, Length);

			if (File == null)
				return new CodeString(String.Substring(Index, Length));

			var NewPosition = String.Index + Index;
			var NewLine = Line;
			if (Line < File.GetLineCount() - 1)
				NewLine += File.GetLineCount(Line + 1, NewPosition);

			return new CodeString(File, NewPosition, Length, NewLine);
		}

		public CodeString Substring(int Index)
		{
			if (!IsValid) throw new InvalidOperationException();
			Helper.Verify(this.Length, Index);

			if (File == null)
				return new CodeString(String.Substring(Index));

			var NewPosition = String.Index + Index;
			var NewLine = Line;
			if (Line < File.GetLineCount() - 1)
				NewLine += File.GetLineCount(Line + 1, NewPosition);

			return new CodeString(File, NewPosition, this.Length - Index, NewLine);
		}

		public CodeString Substring(FindResult FindRes)
		{
			return Substring(FindRes.Index, FindRes.String.Length);
		}

		public CodeString TrimmedSubstring(CompilerState State, int Index, int Length, bool EnableMessages = true)
		{
			var Ret = Substring(Index, Length).Trim();
			if (Ret.Length == 0)
			{
				if (EnableMessages)
					State.Messages.Add(MessageId.DeficientExpr, this);

				return new CodeString();
			}

			return Ret;
		}

		public bool VerifyNotEmpty(CompilerState State, CodeString Code, bool EnableMessages = true)
		{
			if (Length == 0)
			{
				if (EnableMessages)
					State.Messages.Add(MessageId.DeficientExpr, Code);

				return false;
			}

			return true;
		}

		public CodeString TrimmedSubstring(CompilerState State, int Index, bool EnableMessages = true)
		{
			var Ret = Substring(Index).Trim();
			if (!Ret.VerifyNotEmpty(State, this, EnableMessages)) return new CodeString();
			return Ret;
		}

		public CodeString Trim()
		{
			var i = LeftWhiteSpaces;
			if (i == Length) return Substring(0, 0);

			var j = RightWhiteSpaces;
			return Substring(i, Length - i - j);
		}

		public IEnumerable<SplitRes> EnumSplit(string Separator, StringSplitOptions SplitOptions = StringSplitOptions.None,
			bool Trim = false, IList<IResultSkippingHandler> Handlers = null)
		{
			return String.EnumSplit(Separator, SplitOptions, Trim, Handlers);
		}

		public IEnumerable<SplitRes> EnumSplit(char Separator, StringSplitOptions SplitOptions = StringSplitOptions.None,
			bool Trim = false, IList<IResultSkippingHandler> Handlers = null)
		{
			return String.EnumSplit(Separator, SplitOptions, Trim, Handlers);
		}

		public List<CodeString> Split(String Separator, StringSplitOptions SplitOptions = StringSplitOptions.None,
			bool Trim = false, IList<IResultSkippingHandler> Handlers = null)
		{
			var Ret = new List<CodeString>();
			foreach (var e in EnumSplit(Separator, SplitOptions, Trim, Handlers))
				if (!e.IsSeparator) Ret.Add(Substring(e.String));

			return Ret;
		}

		public List<CodeString> Split(char Separator, StringSplitOptions SplitOptions = StringSplitOptions.None,
			bool Trim = false, IList<IResultSkippingHandler> Handlers = null)
		{
			var Ret = new List<CodeString>();
			foreach (var e in EnumSplit(Separator, SplitOptions, Trim, Handlers))
				if (!e.IsSeparator) Ret.Add(Substring(e.String));

			return Ret;
		}

		public int WordEnd(bool WordStart = false, bool Back = false, Func<char, bool> Func = null,
			IList<IResultSkippingHandler> Handlers = null)
		{
			return String.WordEnd(WordStart, Back, Func, Handlers);
		}

		public CodeString Word(bool WordStart = false, bool Back = false, Func<char, bool> Func = null,
			bool ModThis = true, IList<IResultSkippingHandler> Handlers = null)
		{
			var p = WordEnd(WordStart, Back, Func, Handlers);
			if (p == -1) return Substring(0, 0);

			CodeString Ret;
			if (!Back) Ret = Substring(0, p + 1).Trim();
			else Ret = Substring(p).Trim();

			if (ModThis)
			{
				CodeString String;
				if (!Back) String = Substring(p + 1).Trim();
				else String = Substring(0, p).Trim();

				this.File = String.File;
				this.String = String.String;
				this.Line = String.Line;
			}

			return Ret;
		}

		public bool SubstringEqualsS(int Index, string CmpWith, IdCharCheck IdCharCheck = new IdCharCheck())
		{
			return String.SubstringEqualsS(Index, CmpWith, IdCharCheck);
		}

		public bool StartsWith(string CmpWith, IdCharCheck IdCharCheck = new IdCharCheck())
		{
			return String.StartsWith(CmpWith, IdCharCheck);
		}

		public bool EndsWith(string CmpWith, IdCharCheck IdCharCheck = new IdCharCheck())
		{
			return String.EndsWith(CmpWith, IdCharCheck);
		}

		public int SubstringEquals(int Index, string CmpWith, string[] Skip = null, bool Back = false,
			IdCharCheck IdCharCheck = new IdCharCheck())
		{
			return String.SubstringEquals(Index, CmpWith, Skip, Back, IdCharCheck);
		}

		public FindResult SubstringEquals(int Index, string[] CmpWith, string[] Skip = null,
			bool Back = false, IdCharCheck IdCharCheck = new IdCharCheck())
		{
			return String.SubstringEquals(Index, CmpWith, Skip, Back, IdCharCheck);
		}

		public FindResult StartsWith(string[] CmpWith, string[] Skip = null, IdCharCheck IdCharCheck = new IdCharCheck())
		{
			return String.StartsWith(CmpWith, Skip, IdCharCheck);
		}

		public FindResult EndsWith(string[] CmpWith, string[] Skip = null, IdCharCheck IdCharCheck = new IdCharCheck())
		{
			return String.EndsWith(CmpWith, Skip, IdCharCheck);
		}

		public IEnumerable<FindResult> EnumFind(string[] CmpWith, string[] Skip = null, bool Back = false,
			IdCharCheck IdCharCheck = new IdCharCheck(), IList<IResultSkippingHandler> Handlers = null)
		{
			return String.EnumFind(CmpWith, Skip, Back, IdCharCheck, Handlers);
		}

		public FindResult Find(string[] CmpWith, string[] Skip = null, bool Back = false,
			IdCharCheck IdCharCheck = new IdCharCheck(), IList<IResultSkippingHandler> Handlers = null)
		{
			return String.Find(CmpWith, Skip, Back, IdCharCheck, Handlers);
		}

		public IEnumerable<int> EnumFind(string CmpWith, string[] Skip = null, bool Back = false,
			IdCharCheck IdCharCheck = new IdCharCheck(), IList<IResultSkippingHandler> Handlers = null)
		{
			return String.EnumFind(CmpWith, Skip, Back, IdCharCheck, Handlers);
		}

		public int Find(string CmpWith, string[] Skip = null, bool Back = false,
			IdCharCheck IdCharCheck = new IdCharCheck(), IList<IResultSkippingHandler> Handlers = null)
		{
			return String.Find(CmpWith, Skip, Back, IdCharCheck, Handlers);
		}

		public int Find(char CmpWith, bool Back = false, IList<IResultSkippingHandler> Handlers = null)
		{
			return String.Find(CmpWith, Back, Handlers);
		}
		
		public static bool operator ==(CodeString Str1, CodeString Str2)
		{
			return Str1.IsEqual(Str2);
		}

		public static bool operator !=(CodeString Str1, CodeString Str2)
		{
			return !Str1.IsEqual(Str2);
		}

		public static bool operator ==(CodeString Str1, string Str2)
		{
			return Str1.IsEqual(Str2);
		}

		public static bool operator !=(CodeString Str1, string Str2)
		{
			return !Str1.IsEqual(Str2);
		}

		public static bool operator ==(string Str1, CodeString Str2)
		{
			return Str2.IsEqual(Str1);
		}

		public static bool operator !=(string Str1, CodeString Str2)
		{
			return !Str2.IsEqual(Str1);
		}
		
		public bool IsEqual(string String)
		{
			return this.String.IsEqual(String);
		}

		public bool IsEqual(StringSlice String)
		{
			return this.String.IsEqual(String);
		}

		public bool IsEqual(CodeString String)
		{
			return this.String.IsEqual(String.String);
		}

		public override bool Equals(object obj)
		{
			if (obj is CodeString)
			{
				var CodeStr = (CodeString)obj;
				return CodeStr.File == File && CodeStr.Index == Index &&
					CodeStr.Length == Length;
			}

			return false;
		}

		public override int GetHashCode()
		{
			return Index ^ Length;
		}

		public bool IsValidIdentifierName
		{
			get { return String.ValidIdentifierName; }
		}

		public bool HasNonIdChar
		{
			get { return String.HasNonIdChar; }
		}

		public bool IsNumber
		{
			get { return String.IsNumber; }
		}

		public bool ToNumber(int Radix, LetterCase Case, out BigInteger Ret)
		{
			return String.ToNumber(Radix, Case, out Ret);
		}

		public int StrEndLetterCount(LetterCase Case = LetterCase.Both)
		{
			return String.StrEndLetterCount(Case);
		}

		public CodeString CutEndStr(LetterCase Case = LetterCase.Both)
		{
			var C = StrEndLetterCount(Case);
			return C == 0 ? this : Substring(0, String.Length - C);
		}

		public CodeString EndStr(LetterCase Case = LetterCase.Both)
		{
			var C = StrEndLetterCount(Case);
			return C == 0 ? Substring(Length) : Substring(String.Length - C);
		}

		public int TrimmableBracketCount(IList<IResultSkippingHandler> Handlers = null)
		{
			return String.TrimmableBracketCount();
		}

		public int GetBracketPos(bool Back = false, IList<IResultSkippingHandler> Handlers = null)
		{
			return String.GetBracketPos(Back, Handlers);
		}

		public int GetBracketPos(CompilerState State, bool Back = false, bool EnableMessages = true)
		{
			var Handlers = State.Language.GlobalHandlers;
			var Res = String.GetBracketPos(Back, Handlers);
			if (Res == -1)
			{
				var ErrStr = Back ? Substring(Length - 1) : Substring(0, 1);
				if (EnableMessages) State.Messages.Add(MessageId.ZNumErr, ErrStr);
			}

			return Res;
		}

		public bool CanTrimOneBracket(IList<IResultSkippingHandler> Handlers = null)
		{
			return String.CanTrimOneBracket(Handlers);
		}

		public CodeString TrimOneBracket(IList<IResultSkippingHandler> Handlers = null)
		{
			if (CanTrimOneBracket())
				return Substring(1, String.Length - 2).Trim();

			return this;
		}

		public int LeftBracketPos(int Depth)
		{
			return String.LeftBracketPos(Depth);
		}

		public int RightBracketPos(int Depth)
		{
			return String.RightBracketPos(Depth);
		}

		public CodeString TrimBrackets(int Count)
		{
			if (Count == 0) return Trim();
			var Left = LeftBracketPos(Count);
			var Right = RightBracketPos(Count);

			if (Left == -1 || Right == -1) return Substring(Length).Trim();
			else return Substring(Left + 1, Right - Left - 1).Trim();
		}

		public CodeString TrimBrackets(IList<IResultSkippingHandler> Handlers = null)
		{
			var Count = TrimmableBracketCount(Handlers);
			return Count == 0 ? this : TrimBrackets(Count);
		}

		public CodeString TrimBrackets(CompilerState State, int Count, bool Messages = true)
		{
			var Ret = TrimBrackets(Count);
			if (!Ret.IsValid)
			{
				State.Messages.Add(MessageId.ZNumErr, this);
				return new CodeString();
			}
			else if (Ret.Length == 0)
			{
				State.Messages.Add(MessageId.DeficientExpr, this);
				return new CodeString();
			}

			return Ret;
		}

		public CodeString TrimBrackets(CompilerState State, bool Messages = true)
		{
			var Handlers = State.Language.GlobalHandlers;
			var Count = TrimmableBracketCount(Handlers);
			return TrimBrackets(State, Count, Messages);
		}

		public override string ToString()
		{
			return String.ToString();
		}

		public IEnumerable<CodeString> EnumWords(Func<char, bool> Func = null)
		{
			foreach (var e in String.EnumWords(Func))
				yield return Substring(e);
		}
	}
}

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.140827.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