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;

namespace Anonymus.x86
{
	public partial class x86PlugIn : ExprPlugIn
	{
		public x86Architecture Arch;
		public List<x86ExprScope> AllScopes;
		public x86RegList AllUsedRegs;

        public ExpressionNode CreateLinkingNode(ExpressionNode Node, ExpressionNode Parent, x86DataPosition AssignPos)
        {
            if (Parent.LinkedNodes == null)
                Parent.LinkedNodes = new List<LinkedExprNode>();

            var Linked = new LinkedExprNode(Node);
            Linked.ArchData = new x86LinkedNodeData(AssignPos);
            Parent.LinkedNodes.Add(Linked);
            Node = Root.NewNode(new LinkingNode(Linked, Parent.Code));
            return Node;
        }

		public void CalcExprScopes(ExpressionNode Node)
		{
			AllScopes = new List<x86ExprScope>() { };
			AllUsedRegs = new x86RegList(Arch.RegCount);
			CalcExprScopes_Rec(Node, null);

			var Data = Node.ArchData as x86NodeData;
			Data.AllScopes = AllScopes;
			Data.AllUsedRegs = AllUsedRegs;
		}

		public void CalcExprScopes_Rec(ExpressionNode Node, x86ExprScope Scope)
		{
			var Data = Node.ArchData as x86NodeData;
			if (Data.UsedRegs != null) AllUsedRegs.SetUsed(Data.UsedRegs);

			if (Data.NewScope)
			{
				var NewScope = new x86ExprScope(Scope, Container);
                if (Scope != null) Scope.Children.Add(NewScope);
                AllScopes.Add(NewScope);
                Scope = NewScope;
			}

			if (Node.LinkedNodes != null)
			{
				foreach (var e in Node.LinkedNodes)
				{
					var LData = e.ArchData as x86LinkedNodeData;
					if (LData.Specified != null)
					{
						if (Scope.PreAllocated == null)
							Scope.PreAllocated = new x86DataAllocator(Container);

						Scope.PreAllocated.SetUsed(LData.Specified);
					}
				}
			}

			if (Data.PreAllocate != null)
			{
				if (Scope.PreAllocated == null)
					Scope.PreAllocated = new x86DataAllocator(Container);

				Scope.PreAllocated.UsedRegs.SetUsed(Data.PreAllocate);
			}

			Scope.NewDataPosition(Node);
			foreach (var e in Node.EnumChildren)
				CalcExprScopes_Rec(e, Scope);
		}

		public x86PlugIn(x86Architecture Arch, IdContainer Container)
			: base(Container)
		{
			this.Arch = Arch;
		}

		public override PlugInRes End(ref ExpressionNode Node)
        {
            var Data = Node.ArchData as x86NodeData;
            Data.NewScope = true;

            var OpNode = Node as OpExpressionNode;
            if (OpNode != null && OpNode.Operator == Operator.CreateTuple)
                Data.Index = -1;

			CalcExprScopes(Node);
			return PlugInRes.Succeeded;
		}

		public PlugInRes NewOpNode_NonFloat(ref ExpressionNode Node)
		{
			var OpNode = Node as OpExpressionNode;
			var Ch = OpNode.Children;
			var Op = OpNode.Operator;
			var Data = Node.ArchData as x86NodeData;
			var Type = Ch[0].Type;

			//--------------------------------------------------------------------------------------
			if (Operators.IsMathsOp(Op))
			{
				if (Op == Operator.Abs)
				{
					var LinkedNode = new LinkedExprNode(Ch[0]);

					var Zero = Root.NewNode(Expressions.GetIntValue(Container, 0, Node.Code));
					if (Zero == null) return PlugInRes.Failed;
					var CmpWith = Root.NewNode(new LinkingNode(LinkedNode, Node.Code));
					if (CmpWith == null) return PlugInRes.Failed;
					var CondCh = new List<ExpressionNode>() { Ch[0], Zero };
					var Cond = new OpExpressionNode(Operator.Less, CondCh, Node.Code);

					var Then = Root.NewNode(new LinkingNode(LinkedNode, Node.Code));
					if (Then == null) return PlugInRes.Failed;

					var Else = Root.NewNode(new LinkingNode(LinkedNode, Node.Code));
					if (Else == null) return PlugInRes.Failed;
					var ElseCh = new List<ExpressionNode>() { Else };
					Else = Root.NewNode(new OpExpressionNode(Operator.Neg, ElseCh, Node.Code));
					if (Else == null) return PlugInRes.Failed;

					var NewCh = new List<ExpressionNode>() { Cond, Then, Else };
					var Ret = new OpExpressionNode(Operator.Condition, NewCh, Node.Code);
					Ret.LinkedNodes = new List<LinkedExprNode>() { LinkedNode };
					Node = Root.NewNode(Ret);
					if (Node == null) return PlugInRes.Failed;
					else return PlugInRes.Ready;
				}
				else
				{
					Ch[0] = Root.NewNode(new CastExpressionNode(Node.Type, Ch[0], Node.Code));
					if (Ch[0] == null) return PlugInRes.Failed;
					return NewOpNode_Float(ref Node);
				}
			}

			//--------------------------------------------------------------------------------------
			if (Operators.IsShiftOp(Op))
			{
				if (Type.Size > Arch.RegSize)
				{
					var Func = (string)null;
					if (Op == Operator.ShiftLeft) Func = "LongShiftLeft";
					else if (Op == Operator.ShiftRight) Func = Type is UnsignedType ? "ULongShiftRight" : "LongShiftRight";

					Node = Expressions.CreateCallIndexExpr(Node.Code, Root,
						Operator.Call, new PString(Func), Ch);

					if (Node == null) return PlugInRes.Failed;
					Node.Type = OpNode.Type;
					return PlugInRes.Ready;
				}
				else
				{
					Data.Index = AdjustRegs(OpNode, true);
				}
			}

			//--------------------------------------------------------------------------------------
			else if (Operators.IsBitwiseOp(Op))
			{
				Data.Index = AdjustRegs(OpNode, true);
			}

			//--------------------------------------------------------------------------------------
			else if (Operators.IsArithmeticalOp(Op))
			{
				if (NeedSwap(Ch)) OpNode.Swap();

				var CalcedNew = false;
				if ((Op == Operator.Multiply || Op == Operator.Divide) && Ch[1].Type is NonFltNumType)
				{
					var ConstCh1 = Ch[1] as ConstExpressionNode;
					if (ConstCh1 != null)
					{
						var V = ConstCh1.Unsigned;
						if (Helper.Pow2(V) == V)
						{
							var NewOp = Op == Operator.Multiply ? Operator.ShiftLeft : Operator.ShiftRight;
							var CNode = Root.NewNode(new ConstExpressionNode(Ch[1].Type, Helper.Pow2Sqrt(V), Node.Code));
							Ch = new List<ExpressionNode>() { Ch[0], CNode };
							Node = Root.NewNode(new OpExpressionNode(NewOp, Ch, Node.Code));
							CalcedNew = true;

							if (Node != null)
							{
								Data = Node.ArchData as x86NodeData;
								return PlugInRes.Ready;
							}

							return PlugInRes.Failed;
						}
					}
				}

				if (!CalcedNew)
				{
					var Size = Node.Type.Size;
					if (Op == Operator.Multiply || Op == Operator.Divide || Op == Operator.Modolus)
					{
						if (Size > Arch.RegSize)
						{
							var Func = (string)null;
							if (Op == Operator.Multiply) Func = "LongMul";
							else if (Op == Operator.Divide) Func = Type is UnsignedType ? "ULongDiv" : "LongDiv";
							else if (Op == Operator.Modolus) Func = Type is UnsignedType ? "ULongMod" : "LongMod";

							Node = Expressions.CreateCallIndexExpr(Node.Code, Root,
								Operator.Call, new PString(Func), Ch);

							if (Node == null) return PlugInRes.Failed;
							Node.Type = OpNode.Type;
							return PlugInRes.Ready;
						}
						else
						{
							/* imul 1:
							 *		dst: r16/r32
							 *		src: m16/m32/r16/r32/i16/i32
							 *		
							 * imul 2 / idiv / div:
							 *		dst: accumulator
							 *		src: m8/m16/m32/r8/r16/r32
							 *		
							 * remainder (except imul 1):
							 *		byte: ah
							 *		word: dx
							 *		dword: edx
							 */

							Data.Index = AdjustRegs(OpNode, true);
							if (Op != Operator.Multiply || Size == 1)
							{
								if (Ch[1] is ConstExpressionNode)
								{
									var C = Ch[1] as ConstExpressionNode;
									Ch[1] = Container.GlobalScope.CreateConstRId(C, Root);
									if (Ch[1] == null) return PlugInRes.Failed;
								}

								var Ch0Data = Ch[0].ArchData as x86NodeData;
								var Ch1Data = Ch[1].ArchData as x86NodeData;
								Ch0Data.Input = new x86RegPosition(Arch, Size, 0);

								if (Op != Operator.Multiply)
								{
									if (Ch1Data.CantBe == null)
										Ch1Data.CantBe = new x86RegList(Arch.RegCount);

									if (Size == 1) Ch1Data.CantBe.SetUsed(0, 2);
									else Ch1Data.CantBe.SetUsed(2, Size);
								}

								Data.UsedRegs = new x86RegList(Arch.RegCount);
								Data.Index = -1;
								Data.NewScope = true;

								if (Size == 1)
								{
									Data.UsedRegs.SetUsed(0, 2);

									var Pos = new x86RegPosition(Arch, 1, 0, Op == Operator.Modolus);
									Data.Output = Pos;
								}
								else
								{
									Data.UsedRegs.SetUsed(0, Size);
									Data.UsedRegs.SetUsed(2, Size);

									var RegId = Op == Operator.Modolus ? 2 : 0;
									var Pos = new x86RegPosition(Arch, Size, RegId);
									Data.Output = Pos;
								}
							}
							else
							{
								Data.DataCalcPos = x86DataCalcPos.GeneralReg;
							}
						}
					}
					else
					{
						Data.Index = AdjustRegs(OpNode, true);
					}
				}
			}

			//--------------------------------------------------------------------------------------
			else if (Operators.IsRelEqualityOp(Op))
			{
				if (NeedSwap(Ch)) OpNode.Swap();
				Data.Index = AdjustRegs(OpNode, false);
			}

			//--------------------------------------------------------------------------------------
			else if (Op == Operator.Neg || Op == Operator.Complement)
			{
				if (Type.Size > Arch.RegSize && (Ch[0] is IdExpressionNode || Ch[0] is ConstExpressionNode))
				{
					var Null = Expressions.CreateConstNode(Node.Code,
						new ConstData(0), Ch[0].Type, Root);

					if (Null == null) return PlugInRes.Failed;
					var NCh = new List<ExpressionNode>() { Null, Ch[0] };
					Node = Root.NewNode(new OpExpressionNode(Operator.Subract, NCh, Node.Code));
					if (Node == null) return PlugInRes.Failed;
					else return PlugInRes.Ready;
				}
				else
				{
					var ChIndex = (Ch[0].ArchData as x86NodeData).Index;
					if (ChIndex == -1)
					{
						Ch[0] = CreateMoveNode(Ch[0], 0);
						if (Ch[0] == null) return PlugInRes.Failed;
						Data.Index = 0;
					}
					else
					{
						Data.Index = ChIndex;
					}
				}
			}

			//--------------------------------------------------------------------------------------
			else if (Op != Operator.Assignment)
			{
				throw new Exception("ERROR");
			}

			return PlugInRes.Succeeded;
		}

		public PlugInRes NewOpNode_Float(ref ExpressionNode Node)
		{
			var OpNode = Node as OpExpressionNode;
			var Ch = OpNode.Children;
			var Op = OpNode.Operator;
			var Data = Node.ArchData as x86NodeData;

			if (Op != Operator.Assignment && !AdjustConstFltNode(Ch))
				return PlugInRes.Failed;

			//--------------------------------------------------------------------------------------
			if (Operators.IsMathsOp(Op))
			{
				var Ch0Data = Ch[0].ArchData as x86NodeData;
				Data.Index = -1;
				Data.FPUItemsOnStack = Ch0Data.FPUItemsOnStack;

				if (Op == Operator.ACos)
				{
					Node = Expressions.CreateCallIndexExpr(Node.Code, Root,
						Operator.Call, new PString("Math_ArcCosine"), Ch);

					if (Node == null) return PlugInRes.Failed;
					else return PlugInRes.Ready;
				}
				else if (Op == Operator.ASin)
				{
					Node = Expressions.CreateCallIndexExpr(Node.Code, Root,
						Operator.Call, new PString("Math_ArcSine"), Ch);

					if (Node == null) return PlugInRes.Failed;
					else return PlugInRes.Ready;
				}
				else if (Op == Operator.ATan2)
				{
					if (!AdjustRegs_Float(OpNode, true))
						return PlugInRes.Failed;
				}
				else if (Op == Operator.Tan)
				{
					Data.UsedFPUStack = 1;
					if (Ch0Data.FPUItemsOnStack >= 8)
					{
						if ((Ch[0] = CreateMoveNode(Ch[0], 0, x86DataCalcPos.Memory)) == null)
							return PlugInRes.Failed;

						Ch[0].Type = Container.GetType(typeof(FloatType), 8);
					}
				}
			}

			//--------------------------------------------------------------------------------------
			else if (Op == Operator.Assignment)
			{
				var RId = Ch[0] as IdExpressionNode;
				var Var = RId != null ? RId.Id as LocalVariable : null;
				if (!AdjustRegs_Float(OpNode, false, false)) return PlugInRes.Failed;
			}

			//--------------------------------------------------------------------------------------
			else if (Operators.IsArithmeticalOp(Op))
			{
				if (NeedSwap(Ch)) OpNode.Swap();

				Data.Index = -1;
				if (!AdjustRegs_Float(OpNode, true)) return PlugInRes.Failed;
			}

			//--------------------------------------------------------------------------------------
			else if (Operators.IsRelEqualityOp(Op))
			{
				if (NeedSwap(Ch)) OpNode.Swap();

				Data.Index = -1;
				//Data.NewScope = true;
				if (!AdjustRegs_Float(OpNode, true)) return PlugInRes.Failed;
			}

			//--------------------------------------------------------------------------------------
			else if (Op == Operator.Neg)
			{
				Data.Index = -1;
			}

			//--------------------------------------------------------------------------------------
			else
			{
				throw new Exception("ERROR");
			}

			return PlugInRes.Succeeded;
		}

		public PlugInRes NewOpNode_Ptr(ref ExpressionNode Node)
		{
			var OpNode = Node as OpExpressionNode;
			var Ch = OpNode.Children;
			var Op = OpNode.Operator;
			var Data = Node.ArchData as x86NodeData;

			//--------------------------------------------------------------------------------------
			if (Operators.IsArithmeticalOp(Op))
			{
				if (Op == Operator.Add)
				{
					var PType = Ch[0].Type as PointerType;
					Ch[1] = MulBy(Ch[1], PType.Child.Size);
					if (Ch[1] == null) return PlugInRes.Failed;
				}

				Data.Index = AdjustRegs(OpNode, true);
			}

			//--------------------------------------------------------------------------------------
			else if (Op == Operator.Index)
			{
				var pType = Ch[0].Type as PointerType;
				var Size = pType.Child.Size;
				for (var i = 1; i < Ch.Count; i++)
				{
					if (Ch[i] is ConstExpressionNode) Ch[i] = MulBy(Ch[i], Size);
					else (Ch[i].ArchData as x86NodeData).MulBy = Size;
				}

				Data.Index = -1;
			}

			//--------------------------------------------------------------------------------------
			else if (Operators.IsRelEqualityOp(Op))
			{
				if (NeedSwap(Ch)) OpNode.Swap();
				Data.Index = AdjustRegs(OpNode, false);
			}

			//--------------------------------------------------------------------------------------
			else if (Op != Operator.Assignment)
			{
				throw new Exception("ERROR");
			}

			return PlugInRes.Succeeded;
		}

		public PlugInRes NewOpNode_Bool(ref ExpressionNode Node)
		{
			var OpNode = Node as OpExpressionNode;
			var Ch = OpNode.Children;
			var Op = OpNode.Operator;
			var Data = Node.ArchData as x86NodeData;
			
			//--------------------------------------------------------------------------------------
			if (Operators.IsBoolRetOp(Op))
			{
				var Log = !Operators.IsRelEqualityOp(Op);
				if (!Log && Ch[0] is ConstExpressionNode && !(Ch[1] is ConstExpressionNode))
					OpNode.Swap();

				if (Operators.IsRelEqualityOp(Op))
				{
					for (var i = 0; i < Ch.Count; i++)
					{
						var OpCh = Ch[i] as OpExpressionNode;
						if (OpCh != null && Operators.IsBoolRetOp(OpCh.Operator))
						{
							Ch[i] = CreateMoveNode(Ch[i], 0);
							if (Ch[i] == null) return PlugInRes.Failed;
						}
					}
				}

				Data.Index = AdjustRegs(OpNode, false);
			}

			//--------------------------------------------------------------------------------------
			else if (Op == Operator.Not)
			{
				var False = Root.NewNode(Expressions.GetBoolValue(Container, false, Node.Code));
				var nCh = new List<ExpressionNode>() { Ch[0], False };
				Node = Root.NewNode(new OpExpressionNode(Operator.Equal, nCh, Node.Code));
			}

			//--------------------------------------------------------------------------------------
			else if (Op != Operator.Assignment)
			{
				throw new Exception("ERROR");
			}

			return PlugInRes.Succeeded;
		}

		bool[] TupleAssignment_AlwaysLink = new bool[] { false, true };
		public PlugInRes NewOpNode_Structured(ref ExpressionNode Node)
		{
			var OpNode = Node as OpExpressionNode;
			var Ch = OpNode.Children;
			var Op = OpNode.Operator;
			var Data = Node.ArchData as x86NodeData;

			//--------------------------------------------------------------------------------------
			if (Op == Operator.Neg || Op == Operator.Complement || Operators.IsBitArithmOp(Op))
			{
				if (OpNode.Type is TupleType)
				{
					var Code = Node.Code;
					Node = Expressions.ExtractTupleOp(Node, Root, (i, Args) =>
                    {
                        return Root.NewNode(new OpExpressionNode(Op, Args, Code));
                    });

					if (Node == null) return PlugInRes.Failed;
					else return PlugInRes.Ready;
				}
				else
				{
					throw new Exception("ERROR");
				}
			}

			//--------------------------------------------------------------------------------------
			else if (Op == Operator.Member)
			{
				if (Ch[0] is OpExpressionNode)
				{
					var OpCh = Ch[0] as OpExpressionNode;
					var OpChOp = OpCh.Operator;

					if (OpChOp == Operator.New || OpChOp == Operator.Call)
					{
						Ch[0] = CreateMoveNode(Ch[0], 0, x86DataCalcPos.Memory);
						if (Ch[0] == null) return PlugInRes.Failed;
					}
				}

				Data.Index = -1;
			}

            //--------------------------------------------------------------------------------------
            else if (Op == Operator.Assignment)
            {
                var OpCh0 = Ch[0] as OpExpressionNode;
                if (OpCh0 != null && OpCh0.Operator == Operator.CreateTuple)
                {
					var Code = Node.Code;
					Node = Expressions.ExtractTupleOp(Node, Root, (i, Args) =>
                    {
                        return Root.NewNode(new OpExpressionNode(Operator.Assignment, Args, Code));
					}, TupleAssignment_AlwaysLink);

					if (Node == null) return PlugInRes.Failed;
					else return PlugInRes.Ready;
                }
            }

            //--------------------------------------------------------------------------------------
            else
            {
                throw new Exception("ERROR");
            }

			return PlugInRes.Succeeded;
		}

		public PlugInRes NewOpNode_Type(ref ExpressionNode Node)
		{
			var OpNode = Node as OpExpressionNode;
			var Op = OpNode.Operator;
			var Ch = OpNode.Children;
			var Type = Ch[0].Type.RealType;

			if (Type is NonFltNumType) return NewOpNode_NonFloat(ref Node);
			else if (Type is FloatType) return NewOpNode_Float(ref Node);
			else if (Type is BoolType) return NewOpNode_Bool(ref Node);
			else if (Type is PointerType) return NewOpNode_Ptr(ref Node);
			else if (Type is StructuredType) return NewOpNode_Structured(ref Node);
			else throw new Exception("ERROR");
		}

        public ExpressionNode NewCallOpNode(ExpressionNode Node)
        {
            var OpNode = Node as OpExpressionNode;
            var Ch = OpNode.Children;
            var Data = Node.ArchData as x86NodeData;

            var FuncType = Ch[0].Type as FunctionType;
            Data.Index = -1;
            Data.UsedRegs = new x86RegList(Arch.RegCount);
            Data.UsedFPUStack = int.MaxValue;

            //--------------------------------------------------------------------------------------
            for (var i = 1; i < Ch.Count; i++)
            {
                var ChData = Ch[i].ArchData as x86NodeData;
                ChData.NewScope = true;

                if (Ch[i] is ConstExpressionNode & Ch[i].Type is FloatType)
                {
                    Ch[i] = AdjustConstFltNode(Ch[i] as ConstExpressionNode);
                    if (Ch[i] == null) return null;
                }
            }

            for (var i = 0; i < Arch.RegCount; i++)
                if (x86Architecture.IsVolatileReg(i, FuncType.Conv))
                    Data.UsedRegs.SetUsed(i, Arch.RegSize);

            //--------------------------------------------------------------------------------------
            var RetType = FuncType.RetType;
            if (!(RetType is RefType)) RetType = RetType.RealType;
            var S = RetType.Size;

            var NeedMoveRetType = false;
            if (RetType is FloatType)
            {
                Data.FPUItemsOnStack = 1;
            }
            else if (RetType is PointerType || RetType is BoolType || RetType is FunctionType ||
                RetType is RefType || RetType is ClassType)
            {
                var Pos = new x86RegPosition(Arch, S, 0);
				Data.Output = Pos;
            }
            else if (RetType is NonFltNumType)
            {
                x86DataPosition Pos = null;
                if (S == Arch.RegSize) Pos = new x86RegPosition(Arch, S, 0);
				else if (S == Arch.RegSize * 2) Pos = Arch.MultiRegPos(0, 2);
				Data.Output = Pos;
            }
            else if (!(RetType is VoidType))
            {
                NeedMoveRetType = true;
            }

            //--------------------------------------------------------------------------------------
            if (FuncType.Conv == CallConv.AsCall)
            {
                var Index = NeedMoveRetType ? 1 : 0;
                var OpCh0 = Ch[0] as OpExpressionNode;
                if (OpCh0 != null && OpCh0.Operator == Operator.Member)
                    Index++;

				if (Index > 0)
				{
					Data.PreAllocate = new x86RegList(Arch.RegCount);
					for (var i = 0; i < Index; i++)
					{
						var Reg = x86DataAllocator.RegAllocSequence[i];
						Data.PreAllocate.SetUsed(Reg, Arch.RegSize);
					}
				}

                var Types = new Type[Ch.Count - 1];
                for (var i = 1; i < Ch.Count; i++)
                    Types[i - 1] = Ch[i].Type;

                foreach (var i in Arch.EnumFirstAsCallParams(Types, Index))
                {
                    var ChNode = Ch[i + 1];
                    if (ChNode is OpExpressionNode || ChNode is CastExpressionNode)
                    {
                        var P = Arch.GetArgP(ref Index, ChNode.Type.Size);
                        ChNode = CreateLinkingNode(ChNode, Node, P);
                        if (ChNode == null) return null;
                        Ch[i + 1] = ChNode;
                    }
                }
            }

            return Node;
        }

		public PlugInRes NewOpNode(ref ExpressionNode Node)
		{
			var OpNode = Node as OpExpressionNode;
			var Ch = OpNode.Children;
			var Op = OpNode.Operator;
			var Data = Node.ArchData as x86NodeData;

			if (Op == Operator.New)
			{
				Data.Index = -1;
			}

			//--------------------------------------------------------------------------------------
			else if (Op == Operator.Condition)
			{
				var ChData = Ch[1].ArchData as x86NodeData;
				var RegId = ChData.Index == -1 ? 0 : ChData.Index;

				for (var i = 1; i < 3; i++)
				{
					var n = Ch[i];
					ChData = n.ArchData as x86NodeData;

					if (ChData.Index != RegId)
					{
                        n = CreateMoveNode(n, RegId, x86Architecture.TypePos(Ch[i].Type));
						Ch[i] = n;
					}
				}

				var Ch0Data = Ch[0].ArchData as x86NodeData;
				Ch0Data.NewScope = true;
				Data.Index = RegId;
			}

			//--------------------------------------------------------------------------------------
			else if (Op == Operator.Call)
			{
                Node = NewCallOpNode(Node);
				if (Node == null) return PlugInRes.Failed;
			}

			//--------------------------------------------------------------------------------------
			else if (Op == Operator.Assignment)
			{
				Data.NewScope = true;
				Data.Index = -1;
				var Res = NewOpNode_Type(ref Node);
				if (Res == PlugInRes.Ready || Res == PlugInRes.Failed)
					return Res;
			}

			//--------------------------------------------------------------------------------------
            else if (Op == Operator.Address)
			{
				Data.Index = 0;
            }

            //--------------------------------------------------------------------------------------
            else if (Op == Operator.CreateTuple)
            {
                Data.Index = 0;
                Data.DataCalcPos = x86DataCalcPos.Memory;
            }

            //--------------------------------------------------------------------------------------
            else
			{
				var Res = NewOpNode_Type(ref Node);
				if (Res == PlugInRes.Ready || Res == PlugInRes.Failed)
					return Res;
            }

			return PlugInRes.Succeeded;
		}

		public PlugInRes NewCastNode_NonFloat(ref ExpressionNode Node)
		{
			var CastNode = Node as CastExpressionNode;
			var Ch = CastNode.Child;
			var Data = Node.ArchData as x86NodeData;

			var ChData = Ch.ArchData as x86NodeData;
			Data.Index = ChData.Index == -1 ? 0 : ChData.Index;

            var From = Ch.Type.RealType;
            var To = Node.Type.RealType;
            var ToSize = To.Size;

			//--------------------------------------------------------------------------------------
			if (From is FloatType)
			{
                if (ToSize > Arch.RegSize && To is UnsignedType)
				{
                    if (ToSize != 8) throw new NotImplementedException();
					var Func = Ch.Type.Size == 4 ? "FloatToULong" : "DoubleToULong";

					Node = Expressions.CreateCallIndexExpr(Node.Code, Root, Operator.Call,
						new PString(Func), Ch);

					if (Node == null) return PlugInRes.Failed;
					else return PlugInRes.Ready;
				}
                else if (ToSize == 1 || To is UnsignedType)
				{
					CastNode.ArchData = Data;
                    CastNode.Type = Container.GetType(To.GetType(), ToSize * 2);
                    Node = CreateSizeChangerNode(CastNode, ToSize, x86DataCalcPos.Memory);
				}
			}

			//--------------------------------------------------------------------------------------
			else if (From is NonFltNumType)
			{
                if (From.Size == ToSize)
				{
					Node = Ch;
					Node.Type = CastNode.Type;
				}
                else if (From is SignedType && ToSize > Arch.RegSize && Ch.Type.Size < ToSize)
				{
					Data.Output = Arch.MultiRegPos(0, 2);
					Data.UsedRegs = new x86RegList(Arch.RegCount);
					Data.UsedRegs.SetUsed(0, Arch.RegSize);
					Data.UsedRegs.SetUsed(2, Arch.RegSize);
					Data.Index = -1;
					Data.NewScope = true;
				}
			}

			//--------------------------------------------------------------------------------------
			else
			{
				throw new Exception("ERROR");
			}

			return PlugInRes.Succeeded;
		}

		public PlugInRes NewCastNode_Float(ref ExpressionNode Node)
		{
			var CastNode = Node as CastExpressionNode;
			var Ch = CastNode.Child;
			var Data = Node.ArchData as x86NodeData;
			Data.Index = -1;

            var From = Ch.Type.RealType;
            var To = Node.Type.RealType;

			//--------------------------------------------------------------------------------------
            if (From is FloatType)
			{
				Node = Ch;
				Node.Type = CastNode.Type;
			}

			//--------------------------------------------------------------------------------------
            else if (From is NonFltNumType)
			{
                var Size = From.Size;

                if (From is UnsignedType && Size > Arch.RegSize)
				{
					if (Size != 8) throw new Exception("ERROR");
					Node = Expressions.CreateCallIndexExpr(Node.Code, Root, Operator.Call,
						new PString("ULongToFloat"), Ch);

					if (Node == null) return PlugInRes.Failed;
					else return PlugInRes.Ready;
				}
				else
				{
					var Ok = true;
                    if (From is UnsignedType) Ok = false;
					else if (Size == 1) Ok = false;

					if (!Ok)
					{
						Ch = CreateSizeChangerNode(Ch, Size * 2);
						(Ch.ArchData as x86NodeData).DataCalcPos = x86DataCalcPos.Memory;
					}
					/*else
					{
						if (Ch is IdExpressionNode)
						{
							var IdCh = Ch as IdExpressionNode;
							IdCh.Id.CanBeInReg = false;
						}
						else
						{
							var ChData = Ch.Data as x86NodeData;
							if (ChData.Index != -1) ChData.DataCalcPos = x86DataCalcPos.Memory;
						}
					}*/

					Data.FPUItemsOnStack = 1;
					CastNode.Child = Ch;
				}
			}

			//--------------------------------------------------------------------------------------
			else
			{
				throw new Exception("ERROR");
			}

			return PlugInRes.Succeeded;
		}

		public PlugInRes NewCastNode_Ptr(ref ExpressionNode Node)
		{
			var CastNode = Node as CastExpressionNode;
			var Ch = CastNode.Child;
			var Data = Node.ArchData as x86NodeData;

			var ChData = Ch.ArchData as x86NodeData;
			Data.Index = ChData.Index == -1 ? 0 : ChData.Index;

            var From = Ch.Type.RealType;
            var To = Node.Type.RealType;

			//--------------------------------------------------------------------------------------
			if (From is PointerType)
			{
				if (Ch.Type.Size != Node.Type.Size)
					throw new Exception("ERROR");
			}

			//--------------------------------------------------------------------------------------
			else
			{
				throw new Exception("ERROR");
			}

			return PlugInRes.Succeeded;
		}

		public PlugInRes NewCastNode_Structured(ref ExpressionNode Node)
		{
			var CastNode = Node as CastExpressionNode;
			var Ch = CastNode.Child;
			var Data = Node.ArchData as x86NodeData;

            var ChData = Ch.ArchData as x86NodeData;
            Data.Index = ChData.Index == -1 ? 0 : ChData.Index;
            Data.DataCalcPos = x86DataCalcPos.Memory;

            var From = Ch.Type.RealType;
            var To = Node.Type.RealType;
			if (From.IsEqual(To)) return PlugInRes.Succeeded;

            if (To is TupleType && From is TupleType)
			{
                var DstType = To as TupleType;
				var Code = Node.Code;

                Node = Expressions.ExtractTupleOp(Node, Root, (i, Nodes) =>
                {
                    var MemVar = DstType.Members[i] as MemberVariable;
                    var Ret = Root.NewNode(new CastExpressionNode(MemVar.Type, Nodes[0], Code));
					if (Ret == null) return null;

					Ret.IncRegs(i + 1);
					return Ret;
                });

				if (Node == null) return PlugInRes.Failed;
				else return PlugInRes.Ready;
			}
			else
			{
				throw new Exception("ERROR");
			}
		}

		public PlugInRes NewCastNode(ref ExpressionNode Node)
		{
			var CastNode = Node as CastExpressionNode;
			var Ch = CastNode.Child;
			var Data = Node.ArchData as x86NodeData;
            var RealType = Node.Type.RealType;

			if (Ch.Type.RealType is AutomaticType)
			{
				Ch.Type = CastNode.Type;
				Node = Ch;
				return PlugInRes.Succeeded;
			}
            else if (RealType is NonFltNumType) return NewCastNode_NonFloat(ref Node);
            else if (RealType is FloatType) return NewCastNode_Float(ref Node);
            else if (RealType is PointerType) return NewCastNode_Ptr(ref Node);
            else if (RealType is StructuredType) return NewCastNode_Structured(ref Node);
			else throw new Exception("ERROR");
		}

		public override PlugInRes NewNode(ref ExpressionNode Node)
		{
			var Data = Node.ArchData as x86NodeData;
			if (Data != null) throw new Exception("ERROR");
			Data = new x86NodeData();
			Node.ArchData = Data;

			if (Node.LinkedNodes != null)
			{
				foreach (var e in Node.LinkedNodes)
					e.ArchData = new x86LinkedNodeData(null);
			}

			// ------------------------------------------------------------------------------------
			if (Node is LinkingNode)
			{
				Data.Index = -1;
			}

			else if (Node is MacroExpressionNode)
			{
				return PlugInRes.Succeeded;
			}

			else if (Node is StrExpressionNode)
			{
				return PlugInRes.Succeeded;
			}

			else if (Node is IdExpressionNode)
			{
				var RIdNode = Node as IdExpressionNode;
				var Id = RIdNode.Id;
				Data.Index = -1;

				if (Id is Variable)
				{
					var T = RIdNode.Type;
					if (T is FloatType || T is ValueType)
						Id.CanBeInReg = false;
				}
			}

			else if (Node is OpExpressionNode)
			{
				var Res = NewOpNode(ref Node);
				if (Res == PlugInRes.Ready || Res == PlugInRes.Failed)
					return Res;
			}

			else if (Node is CastExpressionNode)
			{
				var Res = NewCastNode(ref Node);
				if (Res == PlugInRes.Ready || Res == PlugInRes.Failed)
					return Res;
			}

			else if (Node is ConstExpressionNode)
			{
				var ConstNode = Node as ConstExpressionNode;
				Data.Index = -1;
			}

			// ------------------------------------------------------------------------------------
			Data = Node.ArchData as x86NodeData;
			if (Node == null || Node.Type == null || Data == null || Data.Index == int.MaxValue)
				throw new Exception("ERROR");

			if (!PostProcNode(Node)) return PlugInRes.Failed;
			else return PlugInRes.Succeeded;
		}

		public bool PostProcNode(ExpressionNode Node)
		{
            if (!CalcLinkedNodes(Node)) return false;
            if (!CalcNodeCantBe(Node)) return false;
			return true;
		}

        public bool CalcLinkedNodes(ExpressionNode Node)
        {
            if (Node.LinkedNodes != null)
                foreach (var e in Node.LinkedNodes)
                {
                    var ChData = e.Node.ArchData as x86NodeData;
                    ChData.NewScope = true;
                }

            return true;
		}

        bool CalcNodeCantBe(ExpressionNode Node)
		{
			var Data = Node.ArchData as x86NodeData;
            if (Data.UsedFPUStack < Data.FPUItemsOnStack)
                Data.UsedFPUStack = Data.FPUItemsOnStack;

            foreach (var Ch in Node.EnumChildren)
            {
                var ChData = Ch.ArchData as x86NodeData;
                if (ChData.UsedFPUStack > Data.UsedFPUStack)
                    Data.UsedFPUStack = ChData.UsedFPUStack;
            }

            // ----------------------------------------------------------------
			var UsedRegs = (x86RegList)null;
			foreach (var Ch in Node.EnumChWithoutLinkedNodes)
			{
				var ChUsed = (Ch.ArchData as x86NodeData).UsedRegs;
				if (ChUsed == null) continue;

				if (UsedRegs == null) UsedRegs = ChUsed.Copy();
				else UsedRegs.SetUsed(ChUsed);
			}

			// ----------------------------------------------------------------
			if (Node.LinkedNodes != null)
			{
				for (var i = Node.LinkedNodes.Count - 1; i >= 0; i--)
				{
					var e = Node.LinkedNodes[i];
					var LNode = e.Node;
					var LData = LNode.ArchData as x86NodeData;

					if (UsedRegs != null)
					{
						if (LData.CantBe != null) LData.CantBe.SetUsed(UsedRegs);
						else LData.CantBe = UsedRegs.Copy();

						if (LData.UsedRegs != null) UsedRegs.SetUsed(LData.UsedRegs);
					}
					else
					{
						if (LData.UsedRegs != null) UsedRegs = LData.UsedRegs.Copy();
					}
				}
			}

            // ----------------------------------------------------------------
            if (UsedRegs != null)
            {
                if (Data.UsedRegs == null) Data.UsedRegs = UsedRegs;
                else Data.UsedRegs.SetUsed(UsedRegs);
            }

			// ----------------------------------------------------------------
			if (Node is OpExpressionNode)
			{
				var OpNode = Node as OpExpressionNode;
				var Op = OpNode.Operator;
				var Ch = OpNode.Children;

				if (Operators.IsBoolRetBitArithmOp(Op))
				{
					var Dst = Ch[0];
					var Src = Ch[1];

					var DstData = Dst.ArchData as x86NodeData;
					var SrArchData = Src.ArchData as x86NodeData;

					if (!OpNode.Reverse)
					{
						if (SrArchData.UsedRegs != null)
						{
							var Regs = SrArchData.UsedRegs;

							if (DstData.CantBe == null)
								DstData.CantBe = Regs.Copy();
							else DstData.CantBe.SetUsed(Regs);
						}
					}
					else
					{
						if (DstData.Output != null)
						{
							var Regs = DstData.Output.GetRegs();

							if (SrArchData.CantBe == null)
								SrArchData.CantBe = Regs.Copy();
							else SrArchData.CantBe.SetUsed(Regs);
						}
					}
				}
			}

            return true;
		}

		private CastExpressionNode CreateSizeChangerNode(ExpressionNode Ch, int NewSize,
			x86DataCalcPos DataCalcPos = x86DataCalcPos.GRegMem)
		{
			var NewType = Container.GetType(Ch.Type.GetType(), NewSize);
			var nNode = new CastExpressionNode(NewType, Ch, Ch.Code);
			var Data = new x86NodeData();
			nNode.ArchData = Data;
			Data.DataCalcPos = DataCalcPos;

			var ChData = Ch.ArchData as x86NodeData;
			Data.Index = ChData.Index == -1 ? 0 : ChData.Index;
            if (!PostProcNode(nNode)) return null;
			return nNode;
		}

		private ExpressionNode CreateMoveNode(ExpressionNode n, int RegId,
			x86DataCalcPos DataCalcPos = x86DataCalcPos.GRegMem, bool ModCastNode = true)
		{
			if (n is CastExpressionNode && ModCastNode)
			{
				var Data = n.ArchData as x86NodeData;
				Data.Index = RegId;
				Data.DataCalcPos &= DataCalcPos;
			}
			else
			{
				n = new CastExpressionNode(n.Type, n, n.Code);
				var Data = new x86NodeData();
				n.ArchData = Data;
				Data.Index = RegId;
				Data.DataCalcPos = DataCalcPos;
                if (!PostProcNode(n)) return null;
			}

			return n;
		}

		bool NeedLoadRId(ExpressionNode Node)
		{
			var RId = Node as IdExpressionNode;
			if (RId == null) return false;

			var Type = RId.Type;
			if (!(Type is FloatType))
				throw new Exception("ERROR");

			var S = Type.Size;
			return S != 4 && S != 8;
		}

		ExpressionNode AdjustConstFltNode(ConstExpressionNode Node)
		{
			if (Node is ConstExpressionNode && Node.Type is FloatType)
			{
				var Val = Node.Double;
				if (Val != 0.0 && Val != 1.0 && Val != Math.PI)
					return Container.GlobalScope.CreateConstRId(Node, Root);
				else return CreateMoveNode(Node, -1);
			}

			return Node;
		}

		bool AdjustConstFltNode(List<ExpressionNode> Ch)
		{
			for (var i = 0; i < Ch.Count; i++)
			{
				var N = Ch[i].RealNode;
				if (N is ConstExpressionNode && N.Type is FloatType)
				{
					N = AdjustConstFltNode(N as ConstExpressionNode);
					if (N == null) return false;
					Ch[i] = N;
				}
			}

			return true;
		}

		bool AdjustRegs_Float(OpExpressionNode Node, bool Mod, bool RemoveIntCasts = true)
		{
			var Ch = Node.Children;
			var Data = Node.ArchData as x86NodeData;

			var RCh0 = Ch[0].RealNode;
			var RCh1 = Ch[1].RealNode;

			var Ch0Data = Ch[0].ArchData as x86NodeData;
			var Ch1Data = Ch[1].ArchData as x86NodeData;

			// -----------------------------------------------------------------------
            if (x86Architecture.NeedLoadFloatDst(Ch[0], Mod))
			{
				RCh0 = CreateMoveNode(Ch[0], -1);
				Ch0Data = RCh0.ArchData as x86NodeData;
				Ch0Data.FPUItemsOnStack = 1;
				Ch[0] = RCh0;
			}

			if (NeedLoadRId(RCh1))
			{
				RCh1 = CreateMoveNode(Ch[1], -1);
				Ch1Data = RCh1.ArchData as x86NodeData;
				Ch1Data.FPUItemsOnStack = 1;
				Ch[1] = RCh1;
			}

			if (RemoveIntCasts)
			{
				RCh1 = FloatOpIntSrc(Ch[1]);
				if (RCh1 == null) return false;
				Ch[1] = RCh1;
			}

			// -----------------------------------------------------------------------
			if (Ch1Data.UsedFPUStack >= 8 && Mod)
			{
				if ((Ch[0] = CreateMoveNode(Ch[0], 0, x86DataCalcPos.Memory)) == null)
					return false;

				Ch[0].Type = Container.GetType(typeof(FloatType), 8);
				Ch0Data = Ch[0].ArchData as x86NodeData;
				Ch[1].IncRegs();
			}

			Data.FPUItemsOnStack = Ch0Data.FPUItemsOnStack + Ch1Data.FPUItemsOnStack;
			return true;
		}
		
		int AdjustRegs(OpExpressionNode Node, bool Mod)
		{
			var Ch = Node.Children;
			var DstIndex = Node.Reverse ? 1 : 0;

			var Dst = Ch[DstIndex];
			var Src = Ch[1 - DstIndex];

			var DstData = Dst.ArchData as x86NodeData;
			var SrArchData = Src.ArchData as x86NodeData;

			var NeedMove = (DstData.Index != 0 && Mod) || Dst is ConstExpressionNode;
			if (!NeedMove && Dst.SamePosition(Src, false)) NeedMove = true;

			if (NeedMove)
			{
				Ch[DstIndex] = Dst = CreateMoveNode(Ch[DstIndex], 0);
				DstData = Dst.ArchData as x86NodeData;
			}

			if (SrArchData != null && SrArchData.Index != -1 && SrArchData.Index == DstData.Index)
				Src.IncRegs();

			return Mod ? 0 : -1;
		}
		
		private static bool NeedSwap(List<ExpressionNode> Ch)
		{
			if (Ch[0].Type is FloatType)
				return Ch[1] is OpExpressionNode && !(Ch[0] is OpExpressionNode);

			var A = Ch[0].RealNode;
			var B = Ch[1].RealNode;

			var AIndex = (A.ArchData as x86NodeData).Index;
			var BIndex = (B.ArchData as x86NodeData).Index;

			return AIndex == -1 && BIndex != -1;
		}

		private ExpressionNode FloatOpIntSrc(ExpressionNode Node)
		{
			var CastNode = Node as CastExpressionNode;
			if (CastNode == null) return Node;

			var Size = CastNode.Child.Type.Size;
			if (Size != 2 && Size != 4) return Node;
			return CastNode.Child;
		}

		private ExpressionNode MulBy(ExpressionNode N, long Num)
		{
			var Four = Root.NewNode(new ConstExpressionNode(N.Type, Num, N.Code));
			var NCh = new List<ExpressionNode>() { N, Four };
			return Root.NewNode(new OpExpressionNode(Operator.Multiply, NCh, N.Code));
		}
	}
}

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)

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
Web03 | 2.8.140721.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