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.Text;
using System.Threading;
using System.Linq;

namespace Bird
{
	[Flags]
	public enum CommandFlags : byte
	{
		None = 0,
		Unreachable = 1,
		Breakable = 2,
		Continueable = 4,
		TryHasCatchVariable = 8,
		CatchesAllException = 16
	}

	public enum CommandType : byte
	{
		Unknown,
		Expression,
		Cycle,
		While,
		DoWhile,
		For,
		If,
		Try,

		Return,
		Break,
		Continue,
		Goto,
		Label,
		Throw,
		Rethrow,
	}

	public static class Commands
	{
		public static bool IsJumpCommand(CommandType Type)
		{
			return Type == CommandType.Return || Type == CommandType.Break ||
				Type == CommandType.Continue || Type == CommandType.Goto;
		}

		public static bool IsLoopCommand(CommandType Type)
		{
			return Type == CommandType.Cycle || Type == CommandType.While ||
				Type == CommandType.DoWhile || Type == CommandType.For;
		}

		public static bool IsBreakableCommand(CommandType Type)
		{
			return IsLoopCommand(Type);
		}

		public static bool CreateCatchVariable(Command TryComm,
			Identifier Type = null, CodeString Name = new CodeString())
		{
			var State = TryComm.State;
			if (!Name.IsValid)
				Name = State.AutoVarName;

			if (Type == null)
			{
				Type = Identifiers.GetByFullNameFast<ClassType>(State, "System.Exception");
				if (Type == null) throw new ApplicationException();
			}

			var Var = TryComm.CatchScope.CreateVariable(Name, Type);
			if (Var == null) return false;

			if (!TryComm.CatchScope.CanIdDeclared(Var)) return false;
			TryComm.CatchScope.IdentifierList.Insert(0, Var);
			TryComm.Flags |= CommandFlags.TryHasCatchVariable;

			var Loc = Var as LocalVariable;
			Loc.PreAssigned = true;
			return true;
		}

		public static Identifier GetOrCreateCatchVariable(Command TryComm)
		{
			if ((TryComm.Flags & CommandFlags.TryHasCatchVariable) == 0)
			{
				if (!CreateCatchVariable(TryComm))
					return null;
			}

			return TryComm.CatchScope.IdentifierList[0];
		}

		static void CreateRootCatchScope(Command TryComm)
		{
			TryComm.CatchScope = new CodeScopeNode(TryComm, TryComm.Code);
			TryComm.Children.Add(TryComm.CatchScope);
		}

		static bool CopyCatchVar(CodeScopeNode Scope, Identifier From, Identifier To, CodeString Code)
		{
			var Plugin = Scope.GetPlugin();
			if (!Plugin.Begin()) return false;

			var Ch = new ExpressionNode[]
			{
				Plugin.NewNode(new IdExpressionNode(To, Code)),
				Plugin.NewNode(new IdExpressionNode(From, Code)),
			};

			if (Ch[0] == null || Ch[1] == null)
				return false;

			if (!To.Children[0].IsEquivalent(From.Children[0]))
			{
				var CastCh1 = Plugin.NewNode(new IdExpressionNode(To.Children[0], Code));
				if (CastCh1 == null) return false;

				var CastCh = new ExpressionNode[] { Ch[1], CastCh1 };
				Ch[1] = Plugin.NewNode(new OpExpressionNode(Operator.Cast, CastCh, Code));
				if (Ch[1] == null) return false;
			}

			var Node = Plugin.NewNode(new OpExpressionNode(Operator.Assignment, Ch, Code));
			if (Node == null || Plugin.End(ref Node) == PluginResult.Failed)
				return false;

			var Comm = new Command(Scope, Code, CommandType.Expression);
			Comm.Expressions = new List<ExpressionNode>() { Node };
			Scope.Children.Add(Comm);
			return true;
		}

		static bool CopyCatchVar(Command TryComm, CodeScopeNode Scope, Identifier Type, CodeString Name, CodeString Code)
		{
			var CatchVar = GetOrCreateCatchVariable(TryComm);
			var NewVar = Scope.CreateAndDeclareVariable(Name, Type);
			if (NewVar == null || CatchVar == null) return false;

			return CopyCatchVar(Scope, CatchVar, NewVar, Code);
		}

		static ExpressionNode CreateCatchCondition(Command TryComm, Command Condition, Identifier Type, CodeString Code)
		{
			var CatchVar = GetOrCreateCatchVariable(TryComm);
			if (CatchVar == null) return null;

			var Plugin = Condition.GetPlugin();
			if (!Plugin.Begin()) return null;

			var Ch = new ExpressionNode[]
			{
				Plugin.NewNode(new IdExpressionNode(CatchVar, Code)),
				Plugin.NewNode(new IdExpressionNode(Type, Code)),
			};
			
			var Node = Plugin.NewNode(new OpExpressionNode(Operator.Is, Ch, Code));
			if (Node == null || Plugin.End(ref Node) == PluginResult.Failed)
				return null;

			return Node;
		}

		public static bool CreateDefaultCatchScope(Command TryComm)
		{
			if ((TryComm.Flags & CommandFlags.CatchesAllException) != 0)
				throw new ApplicationException();

			var Scope = CreateCatchScope(TryComm, TryComm.Code, TryComm.Code);
			var CatchVar = GetOrCreateCatchVariable(TryComm);
			if (Scope == null || CatchVar == null) return false;

			var Plugin = Scope.GetPlugin();
			if (!Plugin.Begin()) return false;

			var Node = Plugin.NewNode(new IdExpressionNode(CatchVar, TryComm.Code));
			if (Node == null || Plugin.End(ref Node) == PluginResult.Failed)
				return false;

			var Comm = new Command(Scope, TryComm.Code, CommandType.Rethrow);
			Comm.Expressions = new List<ExpressionNode>() { Node };
			Scope.Children.Add(Comm);
			return true;
		}

		public static CodeScopeNode CreateCatchScope(Command TryComm, CodeString CommandCode, CodeString Inner,
			Identifier Type = null, CodeString Name = new CodeString())
		{
			var State = TryComm.State;
			if ((TryComm.Flags & CommandFlags.CatchesAllException) != 0)
			{
				State.Messages.Add(MessageId.CatchesAllException, CommandCode);
				return null;
			}

			if (TryComm.CatchScope == null)
				CreateRootCatchScope(TryComm);

			var ExceptionClass = Identifiers.GetByFullNameFast<ClassType>(State, "System.Exception");
			if (ExceptionClass == null) throw new ApplicationException();

			if (Type == null || Type.IsEquivalent(ExceptionClass))
			{
				TryComm.Flags |= CommandFlags.CatchesAllException;
				if (TryComm.CatchScope.Children.Count == 0)
				{
					if ((TryComm.Flags & CommandFlags.TryHasCatchVariable) != 0)
						throw new ApplicationException();

					if (Type != null && !CreateCatchVariable(TryComm, Type, Name))
						return null;

					TryComm.CatchScope.Code = Inner;
					return TryComm.CatchScope;
				}
				else
				{
					var Cond = TryComm.CatchScope.Children[0] as Command;
					var ElseScope = new CodeScopeNode(Cond, Inner);
					Cond.Children.Add(ElseScope);

					if (Type != null && !CopyCatchVar(TryComm, ElseScope, Type, Name, CommandCode))
						return null;

					return ElseScope;
				}
			}
			else
			{
				if (!Identifiers.IsSubtypeOf(Type, ExceptionClass))
				{
					State.Messages.Add(MessageId.CannotBeThisType, Name);
					return null;
				}

				Command Cond;
				if (TryComm.CatchScope.Children.Count == 0)
				{
					Cond = new Command(TryComm.CatchScope, TryComm.Code, CommandType.If);
					Cond.Expressions = new List<ExpressionNode>();
					TryComm.CatchScope.Children.Add(Cond);
				}
				else
				{
					Cond = TryComm.CatchScope.Children[0] as Command;
				}

				var Condition = CreateCatchCondition(TryComm, Cond, Type, CommandCode);
				if (Condition == null) return null;

				var ThenScope = new CodeScopeNode(Cond, Inner);
				Cond.Expressions.Add(Condition);
				Cond.Children.Add(ThenScope);

				if (!CopyCatchVar(TryComm, ThenScope, Type, Name, CommandCode))
					return null;

				return ThenScope;
			}
		}
	}

	public interface ICommandExtension
	{
		void GetAssembly(CodeGenerator CG);
	}

	public class Command : IdContainer
	{
		public CommandType Type;
		public CommandFlags Flags;
		public CodeString Code;

		public List<ExpressionNode> Expressions;
		public ICommandExtension Extension;

		// Breakable
		public int BreakLabel = -1;
		public int ContinueLabel = -1;

		// Jump, Label Command
		public int Label = -1;

		// Try
		public CodeScopeNode CatchScope;
		public int CatchLabel;
		public CodeScopeNode FinallyScope;
		public int FinallyLabel;

		// Goto Command
		public Command JumpTo;
		public CodeString LabelName;

		public Command(IdContainer Parent, CodeString Code, CommandType Type)
			: base(Parent)
		{
			this.Type = Type;
			this.Code = Code;

			if (Commands.IsLoopCommand(Type))
			{
				BreakLabel = State.AutoLabel;
				ContinueLabel = State.AutoLabel;

				Flags |= CommandFlags.Breakable;
				Flags |= CommandFlags.Continueable;
			}
			else if (Type == CommandType.Try)
			{
				CatchLabel = State.AutoLabel;
				FinallyLabel = State.AutoLabel;
			}
		}

		public void ForEachJumpedOver<T>(Action<T> Func)
			where T : IdContainer
		{
			if (Type == CommandType.Return)
			{
				ForEachParent<T>(Func, FunctionScope.Parent);
			}
			else if (Type == CommandType.Break || Type == CommandType.Continue)
			{
				var NeededFlag = Type == CommandType.Break ?
					CommandFlags.Breakable : CommandFlags.Continueable;

				var Loop = GetParent<Command>(x => (x.Flags & NeededFlag) != 0);
				ForEachParent<T>(Func, Loop.Children[0]);
			}
			else if (Type == CommandType.Goto)
			{
				ForEachParent<T>(Func, JumpTo.Parent);
			}
			else
			{
				throw new InvalidOperationException();
			}
		}

		public T JumpsOver<T>(Predicate<T> Func)
			where T : IdContainer
		{
			if (Type == CommandType.Return)
			{
				return GetParent<T>(Func, FunctionScope.Parent);
			}
			else if (Type == CommandType.Break || Type == CommandType.Continue)
			{
				var NeededFlag = Type == CommandType.Break ?
					CommandFlags.Breakable : CommandFlags.Continueable;

				var Loop = GetParent<Command>(x => (x.Flags & NeededFlag) != 0);
				return GetParent<T>(Func, Loop.Children[0]);
			}
			else if (Type == CommandType.Goto)
			{
				return GetParent<T>(Func, JumpTo.Parent);
			}
			else
			{
				throw new InvalidOperationException();
			}
		}

		public JumpDestination GetJumpDestination()
		{
			if (Type == CommandType.Break || Type == CommandType.Continue)
			{
				var Breakable = GetParent<Command>(x => (x.Flags & CommandFlags.Breakable) != 0);
				return new JumpDestination(Breakable, JumpMode.Leave);
			}
			else
			{
				if (Type == CommandType.Goto)
					return new JumpDestination(JumpTo);
				else if (Type == CommandType.Return)
					return new JumpDestination(FunctionScope, JumpMode.Leave);
				else
					throw new InvalidOperationException();
			}
		}

		public bool ReplaceExpressions(Func<ExpressionNode, ExpressionNode> Func)
		{
			var RetValue = true;
			if (Expressions != null)
			{
				for (var i = 0; i < Expressions.Count; i++)
				{
					Expressions[i] = Func(Expressions[i]);
					if (Expressions[i] == null) RetValue = false;
				}
			}

			return RetValue;
		}

		public override Variable OnCreateVariable(CodeString Name, Identifier Type, List<Modifier> Mods = null)
		{
			var Ret = CreateVariableHelper(Name, Type, Mods);
			if (Ret == null) Ret = new LocalVariable(this, Name, Type);
			return Ret;
		}

		public override PluginRoot GetPlugin()
		{
			return new PluginForCodeScope(this);
		}

		public override void GetAssembly(CodeGenerator CG, GetAssemblyMode Mode = GetAssemblyMode.Code)
		{ 
			CG.Container = this;
			if (Extension != null)
			{
				Extension.GetAssembly(CG);
				return;
			}

			if (Type == CommandType.Expression)
			{
				CG.EmitExpression(Expressions[0]);
			}
			else if (Type == CommandType.Cycle)
			{
				CG.InsContainer.Label(ContinueLabel);
				Children[0].GetAssembly(CG);
				CG.InsContainer.Jump(ContinueLabel);
				CG.InsContainer.Label(BreakLabel);
			}
			else if (Type == CommandType.While || Type == CommandType.DoWhile)
			{
				GetWhileAssembly(CG, Expressions[0], Type == CommandType.DoWhile);
			}
			else if (Type == CommandType.For)
			{
				if (Expressions[0] != null)
					CG.EmitExpression(Expressions[0]);

				var DoWhile = WillRun == ConditionResult.True;
				GetWhileAssembly(CG, Expressions[1], DoWhile, Expressions[2]);
			}
			else if (Type == CommandType.If)
			{
				NextLabel = State.AutoLabel;
				CalcIfAssembly(CG, 0);
				CG.InsContainer.Label(NextLabel);
			}
			else if (Type == CommandType.Label)
			{
				CG.InsContainer.Label(Label);
			}
			else if (Type == CommandType.Try)
			{
				Children[0].GetAssembly(CG);
				if (CatchScope != null)
					CG.InsContainer.Jump(FinallyLabel);

				CG.InsContainer.Label(CatchLabel);
				if (CatchScope != null)
					CatchScope.GetAssembly(CG);

				CG.InsContainer.Label(FinallyLabel);
				if (FinallyScope != null)
					FinallyScope.GetAssembly(CG);
			}
			else if (Commands.IsJumpCommand(Type))
			{
				if (Type == CommandType.Return && Expressions != null && Expressions.Count > 0)
					CG.EmitExpression(Expressions[0]);

				CG.InsContainer.Jump(Label);
			}
			else if (Type != CommandType.Unknown)
			{
				throw new NotImplementedException();
			}
		}

		Command GetCommand(IdContainer Container)
		{
			var Scope = Container as CodeScopeNode;
			if (Scope == null) return null;

			if (Scope.Children.Count != 1) return null;
			else return Scope.Children[0] as Command;
		}

		int NextLabel;
		void CalcIfAssembly(CodeGenerator CG, int Pos)
		{
			for (var i = Pos; i < Children.Count; i++)
			{
				var Res = ConditionResult.True;
				if (Expressions.Count > i)
					Res = Expressions[i].ConditionResult;

				if (Res == ConditionResult.Unknown)
				{
					var Cond = Expressions[i];
					var Container = Children[i];

					var ThenCmd = GetCommand(Container);
					var HasCondLessElse = i + 1 < Children.Count && i + 1 >= Expressions.Count;
					var ElseCmd = HasCondLessElse ? GetCommand(Children[i + 1]) : null;

					var Branches = State.Arch.GetBranches(GlobalContainer, ThenCmd, ElseCmd, ref Cond);
					if (Branches[0] == null)
						Branches[0] = new CodeCondBranch(_CG => Container.GetAssembly(_CG));

					if (Branches[1] == null && i + 1 < Children.Count)
						Branches[1] = new CodeCondBranch(_CG => CalcIfAssembly(_CG, i + 1));

					CG.EmitCondition(Cond, Branches[0], Branches[1], NextLabel: NextLabel);
					break;
				}
				else if (Res == ConditionResult.True)
				{
					Children[i].GetAssembly(CG);
					break;
				}
			}
		}

		private void GetWhileAssembly(CodeGenerator CG, ExpressionNode Condition,
			bool DoWhile = false, ExpressionNode Loop = null)
		{
			var Then = State.AutoLabel;
			var CondLbl = State.AutoLabel;

			//--------------------------------------------------------
			if (State.Arch.IsSimpleCompareNode(Condition))
			{
				CG.SetJumpReplacing(CondLbl, () =>
				{
					CG.EmitCondition(Condition, Then, BreakLabel, true);
					CG.InsContainer.Jump(DoWhile ? Then : BreakLabel);
				});
			}

			//--------------------------------------------------------
			if (!DoWhile)
			{
				CG.InsContainer.Label(CondLbl);
				CG.EmitCondition(Condition, Then, BreakLabel, false);
			}

			CG.InsContainer.Label(Then);
			Children[0].GetAssembly(CG);

			CG.InsContainer.Label(ContinueLabel);
			if (Loop != null) CG.EmitExpression(Loop);

			if (DoWhile)
			{
				CG.InsContainer.Label(CondLbl);
				CG.EmitCondition(Condition, Then, BreakLabel, true);
			}
			else
			{
				CG.InsContainer.Jump(CondLbl);
			}

			CG.InsContainer.Label(BreakLabel);
		}

		ConditionResult _WillRun;
		bool _WillRun_Calced = false;
		public ConditionResult WillRun
		{
			get
			{
				if (!_WillRun_Calced)
				{
					if (Type == CommandType.Cycle)
					{
						_WillRun = ConditionResult.True;
					}
					else if (Type == CommandType.While || Type == CommandType.DoWhile)
					{
						_WillRun = Expressions[0].ConditionResult;
					}
					else if (Type == CommandType.For)
					{
						_WillRun = Expressions[1].ConditionResult;
						if (_WillRun == ConditionResult.Unknown)
						{
							ExpressionNode AssignTo = null;
							Variable AssignVar = null;

							if (Expressions[0] is OpExpressionNode)
							{
								var OpNode = Expressions[0] as OpExpressionNode;
								if (OpNode.Operator == Operator.Assignment)
								{
									var Ch = OpNode.Children;
									AssignTo = Ch[1];
									OpNode.GetAssignVar(ref AssignVar);
								}
							}

							if (AssignVar != null && !AssignTo.IdUsed())
							{
								var ConstAssignTo = AssignTo as ConstExpressionNode;
								if (ConstAssignTo == null) return ConditionResult.Unknown;

								var OpCondition = Expressions[1] as OpExpressionNode;
								if (OpCondition == null) return ConditionResult.Unknown;
								var Op = OpCondition.Operator;
								var Ch = OpCondition.Children;

								if (!Operators.IsRelEquality(Op)) return ConditionResult.Unknown;
								var IdCh0 = Ch[0] as IdExpressionNode;
								if (IdCh0 == null || IdCh0.Identifier != AssignVar) return ConditionResult.Unknown;
								var ConstCh1 = Ch[1] as ConstExpressionNode;
								if (ConstCh1 == null) return ConditionResult.Unknown;

								var Ret = ConstAssignTo.Value.DoOperation(ConstCh1.Value, Op);
								if (!(Ret is BooleanValue)) return ConditionResult.Unknown;

								var BoolRet = Ret as BooleanValue;
								_WillRun = BoolRet.Value ? ConditionResult.True : ConditionResult.False;
							}
						}
					}
					else
					{
						throw new NotImplementedException();
					}

					_WillRun_Calced = true;
				}

				return _WillRun;
			}
		}

		public bool HasExpressions
		{
			get { return Expressions != null && Expressions.Count > 0; }
		}

		public void AddExpression(ExpressionNode Node)
		{
			if (Expressions == null)
				Expressions = new List<ExpressionNode>();

			Expressions.Add(Node);
		}
	}
}

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