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

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 Anonymus
{
	public enum CommRecognizerRes
	{
		UnknownOp,
		Succeeded,
		Failed,
	}

	public abstract class CommRecognizer
	{
		public virtual CommRecognizerRes Recognize(PString Code, PString Word, PString Line, int Index, CodeScopeNode Scope)
		{
			return CommRecognizerRes.UnknownOp;
		}

		public virtual T GetRecognizer<T>() where T : ExprRecognizer
		{
			if (this is T) return this as T;
			else return null;
		}
	}

	public enum ScopeRelation
	{
		Or,
		And,
		Other,
	}

	public delegate bool CommFunc(CodeScopeNode Scope);

	public abstract class Command : IdContainer
    {
		public PString Code;
        public bool ChkUnreachable = true;
		public bool Unreachable = true;
		public int CommIndex;

		public abstract IEnumerable<ExpressionNode> EnumExpressions { get; }

		public override Variable CreateVariable(PString Name, Type Type, ModifierList Mods = null)
		{
			var Ret = new LocalVariable(this, Name, Type);
			if (Mods != null && !Mods.Apply(this, Ret)) return null;
			return Ret;
		}

		public override void InitCodeChk(bool Unreachable = true)
		{
			base.InitCodeChk();
			this.Unreachable = Unreachable;
		}

		public Command(IdContainer Parent)
			: base(Parent)
		{
		}

		public override MultiPlugIn GetPlugIn()
		{
			return new LocalPlugIn(this);
		}

		public virtual IEnumerable<CodeScopeNode> EnumScopes
		{
			get
			{
				foreach (var e in EnumChildren)
				{
					var Scope = e as CodeScopeNode;
					if (Scope != null) yield return Scope;
				}
			}
		}

		public virtual void GetAsmCode(Compiler Compiler)
        {
        }

		public virtual IEnumerable<CodeScopeNode> GetRunScopes(bool RunScopes = true)
		{
			if (RunScopes)
			{
				foreach (var e in EnumScopes)
					yield return e;
			}
			
			yield break;
		}

		public override void CalcExprRegs()
		{
			foreach (var Expr in EnumExpressions)
				State.Arch.CalcExprDataPos(State, this, Expr);

			base.CalcExprRegs();
		}

		public override bool ChkCodeRec(CodeChkData Data, ref bool Succeeded)
		{
			base.ChkCodeRec(Data, ref Succeeded);

			foreach (var Expr in EnumExpressions)
			{
				var D = Expr.Vars;
				foreach (var Node in D.AssignedIds)
					Data.OnAssign(State, Node.Id, null);

				foreach (var Node in D.UsedBeforeAssignIds)
				{
					var Id = Data.GetId(Node.Id);
					if (Id != null) continue;

					var Local = Node.Id as LocalVariable;
					if (Local != null && !Local.PreAssigned)
					{
						State.Messages.Add(MessageId.UnassignedVar, Node.Code);
						Succeeded = false;
					}
				}
			}

			Unreachable = false;
			foreach (var Ch in EnumScopes)
				if (Ch.ChkCodeRec(Data, ref Succeeded)) return true;

			return false;
		}
    }

    public class EmptyCommand : Command
    {
        public EmptyCommand(IdContainer Parent)
			: base(Parent)
        {
        }

		public override IEnumerable<ExpressionNode> EnumExpressions
		{ get { yield break; } }
    }

    public class LabelCommand : Command
    {
		public int Label;

		public LabelCommand(IdContainer Parent, int Label)
			: base(Parent)
        {
            this.Label = Label;
        }

		public override void GetAsmCode(Compiler Compiler)
        {
			Compiler.Label(Label);
        }

		public override IEnumerable<ExpressionNode> EnumExpressions
		{ get { yield break; } }
    }

    public abstract class JumpCommand : Command
    {
		public int Label;
		public bool CodeChk = false;

		public JumpCommand(IdContainer Parent, int Label)
			: base(Parent)
        {
            this.Label = Label;
        }

		public override void GetAsmCode(Compiler Compiler)
        {
			Compiler.Jump(Label);
        }

		public override IEnumerable<ExpressionNode> EnumExpressions
		{ get { yield break; } }

    }

	public class GotoCommand : JumpCommand
	{
		public LabelCommand JumpTo;
		public PString LabelName;

		public GotoCommand(IdContainer Parent, PString LabelName)
			: base(Parent, -1)
        {
			this.LabelName = LabelName;
        }

		public override bool ChkCodeRec(CodeChkData Data, ref bool Succeeded)
		{
			base.ChkCodeRec(Data, ref Succeeded);

			if (!CodeChk)
			{
				Unreachable = false;
				CodeChk = true;

				var SParent = JumpTo.Parent as CodeScopeNode;
				SParent.ChkCodeRec(Data, JumpTo.CommIndex, ref Succeeded);
				CodeChk = false;
			}

			return true;
		}
	}

	public class BreakCommand : JumpCommand
	{
		public BreakCommand(IdContainer Parent, int Label)
			: base(Parent, Label)
        {
        }

		public override bool ChkCodeRec(CodeChkData Data, ref bool Succeeded)
		{
			if (!CodeChk)
			{
				Unreachable = false;
				CodeChk = true;

				var Breakable = GetScope<BreakableCommand>();
				var SParent = Breakable.Parent as CodeScopeNode;
				SParent.ChkCodeRec(Data, Breakable.CommIndex + 1, ref Succeeded);
				CodeChk = false;
			}

			return true;
		}
	}

	public class ContinueCommand : JumpCommand
	{
		public ContinueCommand(IdContainer Parent, int Label)
			: base(Parent, Label)
		{
		}

		public override bool ChkCodeRec(CodeChkData Data, ref bool Succeeded)
		{
			Unreachable = false;
			CodeChk = true;
			return true;
		}
	}

    public class RetCommand : JumpCommand
    {
		public bool Chk;

		public RetCommand(IdContainer Parent, int Label, bool Chk)
            : base(Parent, Label)
        {
			this.Chk = Chk;
        }

		public override bool ChkCodeRec(CodeChkData Data, ref bool Succeeded)
		{
			base.ChkCodeRec(Data, ref Succeeded);

			if (Chk)
			{
				var FS = FuncScope;
				if (FS.RetMembers != null && !FS.ChkRetMembers(Data, Code))
					Succeeded = false;
			}

			return true;
		}
    }

	public enum ConditionRes
	{
		True,
		Unknown,
		False,
	}

	public class SwitchCommand : ConditionCommand
	{
		public ExpressionNode Node;

		public SwitchCommand(IdContainer Parent)
			: base(Parent)
		{
		}
	}

	public class CondPart : IdContainer
	{
		public ExpressionNode Condition;
		public CodeScopeNode Then, Else;

		public CondPart(ConditionCommand Parent)
			: base(Parent)
		{
		}

		public override IEnumerable<IdContainer> EnumChildren
		{
			get
			{
				yield return Then;
				if (Else != null) yield return Else;
			}
		}

		public override MultiPlugIn GetPlugIn()
		{
			return new LocalPlugIn(this);
		}

		public override Variable CreateVariable(PString Name, Type Type, ModifierList Mods = null)
		{
			var Ret = new LocalVariable(this, Name, Type);
			if (Mods != null && !Mods.Apply(this, Ret)) return null;
			return Ret;
		}
	}

	public class ConditionCommand : Command
	{
		public List<CondPart> Conditions = new List<CondPart>();

		public ConditionCommand(IdContainer Parent)
			: base(Parent)
		{
		}

		public CondPart LastCondition
		{
			get
			{
				if (Conditions.Count > 0)
					return Conditions[Conditions.Count - 1];

				return null;
			}
		}

		static bool ChkCodeRec(CodeScopeNode Scope, CodeChkData Data, List<CodeChkData> Datas, ref bool Failed)
		{
			var Ret = true;
			var NewData = Data.Copy();
			if (!Scope.ChkCodeRec(NewData, ref Failed)) Ret = false;
			Datas.Add(NewData);
			return Ret;
		}

		public override bool ChkCodeRec(CodeChkData Data, ref bool Succeeded)
		{
			Unreachable = false;
			var Datas = new List<CodeChkData>();
			var Ret = true;

			foreach (var e in Conditions)
			{
				if (!ChkCodeRec(e.Then, Data, Datas, ref Succeeded)) Ret = false;

				if (e.Else != null)
				{
					if (!ChkCodeRec(e.Else, Data, Datas, ref Succeeded)) Ret = false;
					Data.Vars.AddRange(Datas.Intersect().Vars);
					return Ret;
				}
			}

			return false;
		}

		public CondPart CreateCondition()
		{
			var Ret = new CondPart(this);
			State.Arch.OnNewContainer(Ret);
			var L = LastCondition;

			if (L != null && L.Condition == null)
				Conditions.Insert(Conditions.Count - 1, L);
			else Conditions.Add(Ret);

			return Ret;
		}

		public bool HasElseNIf()
		{
			var L = LastCondition;
			return L == null || L.Condition == null || L.Else != null;
		}

		public override IEnumerable<ExpressionNode> EnumExpressions
		{
			get
			{
				foreach (var e in Conditions)
				{
					if (e.Condition != null)
						yield return e.Condition;
				}
			}
		}

		public override IEnumerable<IdContainer> EnumChildren
		{
			get
			{
				return Conditions;
			}
		}

		object GetElse(CondPart Part, int Index)
		{
			if (Part.Else != null) return Part.Else;
			else if (Index < Conditions.Count - 1) return Index + 1;
			else return null;
		}

		void CalcElse(Compiler Comp, CondPart Part, int Index)
		{
			if (Part.Else != null) Part.Else.GetAsmCode(Comp);
			else if (Index < Conditions.Count - 1) CalcAsmCode(Comp, Index + 1);
		}

		CondBranch GetDefCondBranch(object Obj)
		{
			CodeCondBranchFunc Func = null;
			if (Obj is CodeScopeNode)
			{
				var Scope = Obj as CodeScopeNode;
				Func = (Comp) => { Scope.GetAsmCode(Comp); };
			}
			else if (Obj is int)
			{
				Func = (Comp) => { CalcAsmCode(Comp, (int)Obj); };
			}
			else
			{
				throw new Exception("ERROR");
			}

			return new CodeCondBranch(Func);
		}

		Command GetCommand(object Obj)
		{
			var Scope = Obj as CodeScopeNode;
			if (Scope == null || Scope.Commands.Count != 1)
				return null;

			return Scope.Commands[0];
		}

		int NextLabel;
		void CalcAsmCode(Compiler Compiler, int Index)
		{
			var Part = Conditions[Index];

			var Res = ConditionRes.True;
			if (Part.Condition != null)
				Res = Part.Condition.ConditionResult;

			switch (Res)
			{
				case ConditionRes.Unknown:
					var Else = GetElse(Part, Index);
					var Cond = Part.Condition;
					var ThenCmd = GetCommand(Part.Then);
					var ElseCmd = GetCommand(Else);

					var Branches = State.Arch.GetBraches(Compiler, GlobalScope, ThenCmd, ElseCmd, ref Cond);
					if (Branches[0] == null) Branches[0] = GetDefCondBranch(Part.Then);
					if (Branches[1] == null && Else != null) Branches[1] = GetDefCondBranch(Else);

					Compiler.GetConditionCode(Cond, Branches[0], Branches[1], NextLabel: NextLabel,
						ThenAllPathJumpAway: Part.Then.AllPathJumpAway);

					break;

				case ConditionRes.True:
					Part.Then.GetAsmCode(Compiler);
					break;

				case ConditionRes.False:
					CalcElse(Compiler, Part, Index);
					break;
			}
		}

		public override void GetAsmCode(Compiler Compiler)
		{
			NextLabel = State.NextLabelIndex;
			CalcAsmCode(Compiler, 0);
			Compiler.Label(NextLabel);
		}

		public override IEnumerable<CodeScopeNode> GetRunScopes(bool RunScopes = true)
		{
			bool Run = true;
			foreach (var e in Conditions)
			{
				var Res = ConditionRes.False;
				if (Run)
				{
					if (e.Condition == null) Res = ConditionRes.True;
					else Res = e.Condition.ConditionResult;
				}

				if (Res == ConditionRes.True) Run = false;

				if ((Res != ConditionRes.False) == RunScopes) yield return e.Then;
				if ((Res != ConditionRes.True) == RunScopes && e.Else != null) yield return e.Else;
			}
		}

		public override IEnumerable<CodeScopeNode> EnumScopes
		{
			get
			{
				foreach (var e in Conditions)
				{
					yield return e.Then;
					if (e.Else != null) yield return e.Else;
				}
			}
		}
	}

	public abstract class BreakableCommand : Command
	{
		public int BreakLabel;
		public int ContinueLabel;

		public BreakableCommand(IdContainer Parent)
			: base(Parent)
		{
			BreakLabel = State.NextLabelIndex;
			ContinueLabel = State.NextLabelIndex;
		}
	}

	public class LoopCommand : BreakableCommand
	{
		public CodeScopeNode InnerScope;

		public LoopCommand(IdContainer Parent)
			: base(Parent)
		{
		}

		public override IEnumerable<IdContainer> EnumChildren
		{
			get
			{
				yield return InnerScope;

				foreach (var e in base.EnumChildren)
					yield return e;
			}
		}

		public override IEnumerable<ExpressionNode> EnumExpressions
		{ get { yield break; } }

		public override void GetAsmCode(Compiler Compiler)
        {
			Compiler.Label(ContinueLabel);
			if (InnerScope != null) InnerScope.GetAsmCode(Compiler);
			Compiler.Jump(ContinueLabel);
			Compiler.Label(BreakLabel);
        }
	}

	public class WhileCommand : LoopCommand
    {
        public ExpressionNode Condition;
        public bool DoWhile;

		ConditionRes _WillRun;
		bool _WillRun_Calced = false;
		public ConditionRes WillRun
		{
			get
			{
				if (!_WillRun_Calced) _WillRun = WillInnerScopeRun();
				return _WillRun;
			}
		}

		public WhileCommand(IdContainer Parent, ExpressionNode Condition, bool DoWhile = false)
            : base(Parent)
        {
            this.Condition = Condition;
            this.DoWhile = DoWhile;
        }

        private void GetConditionCode(bool JumpIfNot, int Then, Compiler Compiler)
        {
            var OpC = Condition as OpExpressionNode;
            var Last = OpC == null ? false : OpC.Operator == Operator.Or;
            if (!JumpIfNot) Last = !Last;
            Compiler.CalcCondAsmCode(Condition, Then, BreakLabel, Operator.Nothing, Last);
        }

		public void GetAsmCodeWExp(Compiler Compiler, ExpressionNode Loop = null, bool ChkFirst = true)
        {
            if (WillRun == ConditionRes.False) return;
            var Then = State.NextLabelIndex;
            var CondLbl = State.NextLabelIndex;

            //--------------------------------------------------------
            ReplaceJumpsFunc Func = C =>
            {
                GetConditionCode(!ChkFirst, Then, C);
                if (ChkFirst) C.Jump(BreakLabel);
                else C.Jump(Then);
            };

            Compiler.SetJumpReplacing(CondLbl, Func);

            //--------------------------------------------------------
			if (ChkFirst)
			{
				Compiler.Label(CondLbl);
                GetConditionCode(ChkFirst, Then, Compiler);
			}

			Compiler.Label(Then);
			if (InnerScope != null) InnerScope.GetAsmCode(Compiler);

			Compiler.Label(ContinueLabel);
			if (Loop != null) Compiler.GetExprCode(Loop);

			if (!ChkFirst)
			{
                Compiler.Label(CondLbl);
                GetConditionCode(ChkFirst, Then, Compiler);
			}
			else
			{
				Compiler.Jump(CondLbl);
			}

			Compiler.Label(BreakLabel);
        }

		public virtual ConditionRes WillInnerScopeRun()
		{
			return Condition.ConditionResult;
		}

		public override IEnumerable<CodeScopeNode> GetRunScopes(bool RunScopes = true)
		{
			if (RunScopes)
			{
				if (WillRun != ConditionRes.False)
					yield return InnerScope;
			}
			else
			{
				if (WillRun == ConditionRes.False)
					yield return InnerScope;
			}
		}

		public override void GetAsmCode(Compiler Compiler)
        {
			GetAsmCodeWExp(Compiler, null, !DoWhile);
        }

		public override IEnumerable<ExpressionNode> EnumExpressions
		{ get { yield return Condition; } }
    }

    public class ForCommand : WhileCommand
    {
        public ExpressionNode Loop, Init;
		public bool WillRunCalced = false;

		public ForCommand(IdContainer Parent, ExpressionNode Condition, ExpressionNode Loop, ExpressionNode Init)
            : base(Parent, Condition, false)
        {
            this.Loop = Loop;
			this.Init = Init;
        }

		public override void GetAsmCode(Compiler Compiler)
        {
			if (Init != null) Compiler.GetExprCode(Init);
			GetAsmCodeWExp(Compiler, Loop, WillInnerScopeRun() != ConditionRes.True);
        }

		public override ConditionRes WillInnerScopeRun()
		{
			var Res = base.WillInnerScopeRun();
			if (Res != ConditionRes.Unknown) return Res;

			ExpressionNode AssignTo = null;
			Variable AssignVar = null;

			if (Init is OpExpressionNode)
			{
				var OpNode = Init 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 ConditionRes.Unknown;

				var OpCondition = Condition as OpExpressionNode;
				if (OpCondition == null) return ConditionRes.Unknown;
				var Op = OpCondition.Operator;
				var Ch = OpCondition.Children;

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

				var NewCh = new List<ExpressionNode>() { ConstAssignTo, ConstCh1 };
				var NewNode = new OpExpressionNode(Op, NewCh, null);
				var Ret = ConstExpressionNode.DoOps(this, NewNode);
				return Ret.ConditionResult;
			}

			return ConditionRes.Unknown;
		}

		public override IEnumerable<ExpressionNode> EnumExpressions
		{
			get
			{
				yield return Loop;
				yield return Init;
				yield return Condition;
			}
		}
    }

    public class ExpressionCommand : Command
    {
        public ExpressionNode Expression;

		public ExpressionCommand(IdContainer Parent, ExpressionNode Expression)
			: base(Parent)
        {
            this.Expression = Expression;
        }

		public override IEnumerable<ExpressionNode> EnumExpressions
		{ get { yield return Expression; } }

        public override void GetAsmCode(Compiler Compiler)
        {
            // sb.Append("\n\t; " + Expression.CompData().Code.String + "\n");
            Compiler.GetExprCode(Expression);
        }
    }

    public class AsmCommand : Command
    {
        public List<object> List = new List<object>();

        public AsmCommand(IdContainer Parent)
			: base(Parent)
        {
        }

        public bool Process(CompilerState State, PString AsmCode)
        {
            var Ret = true;
            var Pos = AsmCode.IndexOf('$');
			var PlugIn = GetPlugIn();

            while (Pos != -1)
            {
                List.Add(AsmCode.String.Substring(0, Pos));
                AsmCode = AsmCode.Substring(Pos + 1);
                var VarName = AsmCode.Word();

				var Node = PlugIn.NewNode(new StrExpressionNode(VarName));
                if (!(Node is IdExpressionNode))
                {
                    State.Messages.Add(MessageId.AsmNotRId, VarName);
                    Node = null;
                }

                if (Node == null) Ret = false;
                else List.Add(Node);

                Pos = AsmCode.IndexOf('$');
            }

            if (AsmCode.String != "")
                List.Add(AsmCode.String);

            return Ret;
        }

        public override void GetAsmCode(Compiler Compiler)
        {
			Compiler.Append("\t");
            foreach (var e in List)
            {
				if (e is string) Compiler.Append(e as string);
#warning WARNING
				//else if (e is ExpressionNode) Compiler.Append(Compiler.GetPositionString((e as ExpressionNode), null));
                else throw new Exception("ERROR");
            }

			Compiler.Append("\n");
        }

		public override IEnumerable<ExpressionNode> EnumExpressions
		{ get { yield break; } }
    }

}

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
Web02 | 2.8.140926.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