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

namespace Anonymus
{
	public enum ExprRecognizerRes
	{
		UnknownOp,
		DontCallNewNode,
		Succeeded,
		Failed,
	}

	public abstract class ExprRecognizer
	{
		public string[] Operators;
		public string[] Skip;

		public string[] NewLineLeft;
		public string[] NewLineRight;
		public string[] OnlyLeft;
		public string[] OnlyRight;

		static string[] GetStrings(string[] Array, string[] Skip)
		{
			var RetList = new List<string>();
			foreach (var e in Array)
			{
				var Ok = true;
				if (Skip != null)
				{
					foreach (var f in Skip)
						if (f.Contains(e))
						{
							Ok = false;
							break;
						}
				}

				if (Ok) RetList.Add(e);
			}

			if (RetList.Count == 0) return null;
			else return RetList.ToArray();
		}

		public virtual void Init()
		{
			if (NewLineLeft != null)
				OnlyLeft = GetStrings(NewLineLeft, NewLineRight);

			if (NewLineRight != null)
				OnlyRight = GetStrings(NewLineRight, NewLineLeft);
		}

		public virtual ExprRecognizerRes Recognize(PString Code, ExprPlugIn PlugIn, ref ExpressionNode Ret)
		{
			return ExprRecognizerRes.UnknownOp;
		}

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

	public abstract class ArgRecognizer : ExprRecognizer
	{
		public abstract bool SplitArgs(CompilerState State, PString Self, List<PString> Ret, bool EnableMessages = true);
	}

    public delegate ExpressionNode BEFunc();
    public delegate ExpressionNode ExtractTupleOpFunc(int Index, List<ExpressionNode> Ch);

    public static class Expressions
    {
        public static ExpressionNode ExtractTupleOp(ExpressionNode Node, ExprPlugIn PlugIn, ExtractTupleOpFunc Func, bool[] AlwaysLink = null)
        {
            var DstType = Node.Type.RealType as TupleType;
			var NewCh = new List<ExpressionNode>();
			var LinkedNodes = new List<LinkedExprNode>();

			var Index = 0;
			foreach (var Ch in Node.EnumChildren)
			{
				var OpCh = Ch as OpExpressionNode;
				if (OpCh == null || OpCh.Operator != Operator.CreateTuple || (AlwaysLink != null && AlwaysLink[Index]))
				{
					LinkedNodes.Add(new LinkedExprNode(Ch));
					continue;
				}

				LinkedNodes.Add(null);
				Index++;
			}

            Index = 0;
            foreach (MemberVariable Member in DstType.Members)
            {
                var Args = new List<ExpressionNode>();
				var ArgIndex = 0;

                foreach (var Ch in Node.EnumChildren)
                {
					if (LinkedNodes[ArgIndex] != null)
                    {
                        var SrcType = Ch.Type.RealType as TupleType;
						var Linking = PlugIn.NewNode(new LinkingNode(LinkedNodes[ArgIndex], Node.Code));
                        var MNode = PlugIn.NewNode(new IdExpressionNode(SrcType.Members[Index], Node.Code));
                        if (MNode == null || Linking == null) return null;

                        var MemberCh = new List<ExpressionNode>() { Linking, MNode };
                        var MemberOp = PlugIn.NewNode(new OpExpressionNode(Operator.Member, MemberCh, Node.Code));
                        if (MemberOp == null) return null;

                        Args.Add(MemberOp);
                    }
                    else
					{
						var OpCh = Ch as OpExpressionNode;
                        Args.Add(OpCh.Children[Index]);
                    }

					ArgIndex++;
                }

                var Ret = Func(Index, Args);
                if (Ret == null) return null;

                NewCh.Add(Ret);
                Index++;
            }

            Node = new OpExpressionNode(Operator.CreateTuple, NewCh, Node.Code);
			if (LinkedNodes != null)
			{
				LinkedNodes.RemoveAll(x => x == null);
				Node.LinkedNodes = LinkedNodes;
			}

            Node.Type = DstType;
            Node = PlugIn.NewNode(Node);
            return Node;
        }

		public static ExpressionNode CreateConstNode(PString Code, 
			ConstData Data, Type Type, ExprPlugIn PlugIn = null)
		{
			var Ret = new ConstExpressionNode(Type, Data, Code);
			if (PlugIn == null) return Ret;
			else return PlugIn.NewNode(Ret);
		}

		public static ExpressionNode CreateCallIndexExpr(PString Code, ExprPlugIn PlugIn,
			Operator Op, PString FuncName, ExpressionNode Ch)
		{
			return CreateCallIndexExpr(Code, PlugIn, Op, FuncName, Helper.ObjToEnumable(Ch));
		}

		public static ExpressionNode CreateCallIndexExpr(PString Code, ExprPlugIn PlugIn,
			Operator Op, List<ExpressionNode> Ch)
		{
			var OpNode = new OpExpressionNode(Op, Ch, Code);
			return PlugIn.NewNode(OpNode);
		}

		public static ExpressionNode CreateCallIndexExpr(PString Code, ExprPlugIn PlugIn,
			Operator Op, PString FuncName, PString Params)
		{
			var Ch = CreateParamNodes(PlugIn, Code, FuncName, Params);
			if (Ch == null) return null;
			return CreateCallIndexExpr(Code, PlugIn, Op, Ch);
		}

		public static ExpressionNode CreateCallIndexExpr(PString Code, ExprPlugIn PlugIn, Operator Op, List<PString> Params)
		{
			var Ch = CreateParamNodes(PlugIn, Code, Params);
			if (Ch == null) return null;
			return CreateCallIndexExpr(Code, PlugIn, Op, Ch);
		}

		public static ExpressionNode CreateCallIndexExpr(PString Code, ExprPlugIn PlugIn,
			Operator Op, PString FuncName, IEnumerable<ExpressionNode> Ch)
		{
			var Func = Recognize(FuncName, PlugIn, false);
			if (Func == null) return null;

			var NewCh = new List<ExpressionNode>() { Func };
			NewCh.AddRange(Ch);
			return CreateCallIndexExpr(Code, PlugIn, Op, NewCh);
		}

		public static ExpressionNode GetId(ExprPlugIn PlugIn, PString Code, IdContainer Container = null)
		{
            if (Container == null) Container = PlugIn.Container;
            var Node = Container.GetExprRec(Code, PlugIn: PlugIn);
			if (Node == null)
			{
				var Var = Container.GetId<Identifier>(Code, EnableMessages: false);
				if (Var == null) return PlugIn.NewNode(new StrExpressionNode(Code));
				Node = PlugIn.NewNode(new IdExpressionNode(Var, Code));
			}

			if (Node is IdExpressionNode)
			{
                var RIdNode = Node as IdExpressionNode;
                if (RIdNode.Id is MemberVariable || RIdNode.Id is MemberFunction)
                {
                    var Var = RIdNode.Id as MemberVariable;
					var Self = PlugIn.Container.FuncScope.Self;

					if (Self != null)
					{
						var RIdSelf = PlugIn.NewNode(new IdExpressionNode(Self, Code));
						if (RIdSelf == null) return null;

						var Ch = new List<ExpressionNode>() { RIdSelf, RIdNode };
						return PlugIn.NewNode(new OpExpressionNode(Operator.Member, Ch, Code));
					}

					return PlugIn.NewNode(new StrExpressionNode(Code));
				}
                else if (RIdNode.Id is ConstructorFunction)
                {
                    if (Container.Parent == null) throw new Exception("ERROR");
                    return GetId(PlugIn, Code, Container.Parent);
                }
			}

			return Node;
		}

		public static int AsFindParamPosition(CompilerState State, string Line)
		{
			var ZHlp = new BracketHelper();
			var Ok = false;

			for (var i = 0; i < Line.Length; i++)
			{
				var Chr = Line[i];
				if (!ZHlp.OnChar(Chr)) continue;

				if (!StringHelper.IsIdChar(Chr))
				{
					if (!Ok) continue;
					else if (Chr == '(') return -1;

					var C = StringHelper.LWhiteSpaceCount(Line, i + 1);
					var Pos = i + C + 1;
					if (Pos >= 0 && char.IsWhiteSpace(Chr) && StringHelper.IsIdChar(Line[Pos]))
						return i;

					var Rec = State.Language.ExprRecognizer;
					if (Line.SubstringEquals(i, Rec.OnlyRight).Position != -1)
						return i;
				}
				else
				{
					Ok = true;
				}
			}

			return -1;
		}

		public static ExpressionNode CreateFuncCallNode(PString Line, ExprPlugIn PlugIn)
		{
			var State = PlugIn.State;
			var Pos = AsFindParamPosition(PlugIn.State, Line.String);

			if (Pos != -1)
			{
				var str_Func = Line.TrimmedSubstring(0, Pos);
				var str_Params = BracketHelper.TrimOneBracket(Line.TrimmedSubstring(Pos));

				BEFunc Func = () =>
				{
					return CreateCallIndexExpr(Line, PlugIn, Operator.Call, str_Func, str_Params);
				};

				return BeginEnd(PlugIn, Func);
			}
			else
			{
				var Node = NewExpressionTree(Line, PlugIn, false);
				if (Node == null) return null;

				var OpNode = Node as OpExpressionNode;
				if (OpNode == null || OpNode.Operator != Operator.Call)
				{
					var Ch = new List<ExpressionNode>() { Node };
					Node = PlugIn.NewNode(new OpExpressionNode(Operator.Call, Ch, Line));
					if (Node == null) return null;
				}

				return PlugIn.End(Node);
			}
		}

		public static FindRes Find2(CompilerState State, string String, string[] Find, string[] Skip = null)
        {
			var Start = String.Length - 1;
            FindRes Result;

            while (true)
            {
                if (Start >= 0)
                {
					Result = String.Find(Find, InZ: true, Start: Start, Skip: Skip, Back: true);
                    if (Result.Position != -1)
                    {
						var Str = String.Substring(0, Result.Position).Trim();
						Start = Result.Position - Result.String.Length;

						var FindS = State.Language.ExprRecognizer.Operators;
						if (Str == "" || Str.EndsWith(FindS, NotIdChar: true).Position != -1)
							continue;
						else break;
                    }
                }

                Result = new FindRes(-1, -1, null);
                break;
            }

            return Result;
        }

		public static bool IsCastString(CompilerState State, string String)
		{
			if (String[0] == '(')
			{
				var ZPos = BracketHelper.ZPos(String);
				if (ZPos == -1) return false;

				String = String.Substring(ZPos + 1).Trim();
				var FindS = State.Language.ExprRecognizer.NewLineLeft;
				if (String.StartsWith(FindS, NotIdChar: true).Position != -1)
					return false;

				return true;
			}

			return false;
		}

		public static List<ExpressionNode> TwoParamOpNode(PString String, FindRes Result, ExprPlugIn PlugIn)
		{
			var NStr = String.TrimmedSubstring(0, Result.Position);
			var MStr = String.TrimmedSubstring(Result.Position + Result.String.Length);

			if (NStr.String == "" || MStr.String == "")
			{
				PlugIn.State.Messages.Add(MessageId.DeficientExpr, String);
				return null;
			}

			var N = Recognize(NStr, PlugIn, true);
			var M = Recognize(MStr, PlugIn, true);

			if (N == null || M == null) return null;
			else return new List<ExpressionNode>() { N, M };
		}

		static PString ChkTrmSubStr(CompilerState State, PString String, int StrSize = 1, bool Back = false)
        {
            PString Ret;
            if (!Back) Ret = String.TrimmedSubstring(StrSize);
            else Ret = String.TrimmedSubstring(0, String.StrLen - StrSize);

            if (Ret.String == "")
            {
                State.Messages.Add(MessageId.DeficientExpr, String);
                return null;
            }

            return Ret;
        }

		public static ExpressionNode OneParamOpNode(PString String, ExprPlugIn Settings,
			Operator Op, int StrSize = 1)
        {
            var ps = ChkTrmSubStr(Settings.State, String, StrSize);
			var Node = Recognize(ps, Settings, true);
            if (Node != null) return new OpExpressionNode(Op, new List<ExpressionNode>() { Node }, String);
            else return null;
        }

		public static ExpressionNode NewExpressionTree(PString String, ExprPlugIn PlugIn, bool End = true)
        {
			BEFunc Func = () => { return Recognize(String, PlugIn, false); };
			return BeginEnd(PlugIn, Func, End);
        }

		public static ExpressionNode BeginEnd(ExprPlugIn PlugIn, BEFunc Func, bool End = true)
		{
			if (!PlugIn.Begin()) return null;
			var Ret = Func();
			if (End && Ret != null) Ret = PlugIn.End(Ret);
			return Ret;
		}

		public static ConstExpressionNode GetIntValue(IdContainer Container, int Val, PString Code)
		{
			var IntType = Container.GetType(typeof(SignedType), 4);
			return new ConstExpressionNode(IntType, Val, Code);
		}

		public static ConstExpressionNode GetFloatValue(IdContainer Container, double Val, PString Code)
		{
			var FloatType = Container.GetType(typeof(FloatType), 8);
			return new ConstExpressionNode(FloatType, Val, Code);
		}

		public static ExpressionNode IncDecNode(PString String,
            ExprPlugIn PlugIn, Operator Op, int StrSize)
        {
            var Str = ChkTrmSubStr(PlugIn.State, String, StrSize, Back: true);
            if (Str != null)
            {
				var RId = Recognize(Str, PlugIn, true);
				var One = PlugIn.NewNode(GetIntValue(PlugIn.Container, 1, String));

				if (RId != null && One != null)
				{
					var Addition = PlugIn.NewNode(new OpExpressionNode(Op, new List<ExpressionNode>() { RId, One }, String));
					if (Addition != null)
					{
						var Ch = new List<ExpressionNode>() { RId, Addition };
						return PlugIn.NewNode(new OpExpressionNode(Operator.Assignment, Ch, String));
					}
				}
            }

            return null;
        }

		public static ExpressionNode Recognize(PString Code, ExprPlugIn PlugIn, bool Trimmed)
		{
			if (!Trimmed)
			{
				Code.TrimThis();
			}
#if DEBUG
			else if (Code.String.LWhiteSpaceCount() != 0 ||
					 Code.String.RWhiteSpaceCount() != 0)
			{
				throw new Exception("Not Trimmed");
			}

			if (Code == null || Code.String == "")
				throw new Exception("Deficient");
#endif

			var Recognizer = PlugIn.Recognizer;
			var State = PlugIn.State;
			var RetValue = (ExpressionNode)null;

			var NewCode = BracketHelper.TrimFZ(Code);
			if (NewCode.StrLen == 0)
			{
				State.Messages.Add(MessageId.DeficientExpr, Code);
				return null;
			}

			var Res = Recognizer.Recognize(NewCode, PlugIn, ref RetValue);
			if (Res == ExprRecognizerRes.Succeeded)
			{
				RetValue = PlugIn.NewNode(RetValue);
				if (RetValue == null) return null;
			}
			else if (Res == ExprRecognizerRes.UnknownOp)
			{
				State.Messages.Add(MessageId.UnknownOp, NewCode);
				return null;
			}
			else if (Res == ExprRecognizerRes.Failed)
			{
				return null;
			}

			return RetValue;
		}

		public static List<PString> ConstructCallIndexParams(CompilerState State, PString Func, PString Params)
		{
			var Ret = new List<PString>();
			if (Func != null) Ret.Add(Func);

			Params = Params.Trim();
			if (Params.StrLen == 0) return Ret;

			var Recognizer = State.Language.ArgRecognizer;
			if (!Recognizer.SplitArgs(State, Params, Ret))
				return null;

			return Ret;
		}

		public static List<ExpressionNode> CreateParamNodes(ExprPlugIn PlugIn, PString Code,
			PString Func, PString Params, int ParamCount = -1)
		{
			var Lst = ConstructCallIndexParams(PlugIn.State, Func, Params);
			if (Lst == null) return null;

			return CreateParamNodes(PlugIn, Code, Lst, ParamCount);
		}

		public static List<ExpressionNode> CreateParamNodes(ExprPlugIn PlugIn, PString Code,
			IEnumerable<PString> Params, int ParamCount = -1)
		{
			var Nodes = new List<ExpressionNode>();
			foreach (var Obj in Params)
			{
				var Node = Recognize(Obj, PlugIn, true);
				if (Node == null) return null;
				Nodes.Add(Node);
			}

			if (ParamCount != -1 && Nodes.Count != ParamCount)
			{
				PlugIn.State.Messages.Add(MessageId.ParamCount, Code);
				return null;
			}

			return Nodes;
		}

        public static ConstExpressionNode GetBoolValue(BoolType Type, bool Value, PString Code)
        {
            var Val = Value ? Type.TrueVal : Type.FalseVal;
            return new ConstExpressionNode(Type, Val, Code);
        }

		public static ConstExpressionNode GetBoolValue(IdContainer Container, bool Value, PString Code)
        {
			var Tp = Container.GlobalScope.BoolType as BoolType;
            return GetBoolValue(Tp, Value, Code);
        }

		public static bool IsLiteral(string Code)
		{
			var f = Code[0];
			if (Code == "true" || Code == "false" || Code == "pi" || Code == "null")
				return true;

			if (char.IsDigit(f) || f == '$' || f == '%' || f == '-')
			{
				if (f == '-') Code = Code.Substring(1).Trim();
				f = Code[0];
				Code = f == '$' || f == '%' ? Code.Substring(1) : Code;

				var Old = Code;
				Code = StringHelper.CutEndStr(Code, LetterCase.Lower);
				if (Code.Length == 0) Code = Old;

				var P = Code.IndexOf(".");
				if (P == -1) return Code.IsNum();

				return Code.Substring(0, P).IsNum() &&
					   Code.Substring(P + 1).IsNum();
			}

			if (f == '\"' && Code.Length > 1 && Code[Code.Length - 1] == '\"')
				if (Code.Substring(1, Code.Length - 2).IndexOf('\"') == -1)
					return true;

			return false;
		}

		public static ConstExpressionNode GetLiteral(ExprPlugIn PlugIn, PString Code)
        {
			var Container = PlugIn.Container;
			var State = PlugIn.State;

            var FStr = Code.Copy();
			if (Code.String == "true") return GetBoolValue(Container, true, FStr);
			if (Code.String == "false") return GetBoolValue(Container, false, FStr);
			if (Code.String == "pi") return Expressions.GetFloatValue(Container, Math.PI, Code) as ConstExpressionNode;
			if (Code.String == "null") return new ConstExpressionNode(Container.GlobalScope.AutoType, 0, Code);

			var FirstChar = Code[0];
			if (FirstChar == '\"' && Code.StrLen > 1 && Code[Code.StrLen -1] == '\"')
			{
				var s = Code.Substring(1, Code.StrLen - 2).String;
				if (s.IndexOf('\"') == -1) return new ConstExpressionNode(Container.GlobalScope.CStrType, s, FStr);
			}

			if (char.IsDigit(FirstChar) || FirstChar == '$' || FirstChar == '%' || FirstChar == '-')
			{
				var Str = Code.String;
				var Type = (Type)null;
				var End = StringHelper.EndStr(Code.String, LetterCase.Lower);

				if (!string.IsNullOrEmpty(End))
				{
					foreach (var Id in Container.GlobalScope.BasicTypes)
					{
						var Tp = Id as NumberType;
						if (Tp != null && Tp.Code == End)
						{
							Str = Str.Substring(0, Str.Length - Tp.Code.Length);
							Type = Tp;
						}
					}

					if (Type == null)
					{
						State.Messages.Add(MessageId.UnknownType, Code);
						return null;
					}
				}

				var Neg = FirstChar == '-';
				if (Neg) Str = Str.Substring(1).Trim();
				FirstChar = Str[0];

				var S = 10;
				if (!char.IsDigit(FirstChar))
				{
					if (FirstChar == '$')
					{
						S = 16;
						Str = Str.Substring(1);
					}
					else if (FirstChar == '%')
					{
						S = 2;
						Str = Str.Substring(1);
					}
					else
					{
						State.Messages.Add(MessageId.ConstNumErr, Code);
						return null;
					}
				}

				return ConvStrToConst(State, Code, Str, Type, Container, S, Neg);
			}
			
			return null;
        }

		public static ConstExpressionNode ConvStrToConst(CompilerState State, PString Code, string Num, Type Type = null,
			IdContainer Container = null, int Radix = 10, bool Negative = false)
		{
			var P = Num.IndexOf(".");
			if (P == -1)
			{
				BigInteger Ret;
				if (!Num.ConvertToDec(Radix, LetterCase.Upper, out Ret))
				{
					State.Messages.Add(MessageId.ConstNumErr, Code);
					return null;
				}

				if (Negative) Ret = -Ret;
				if (Type == null) Type = Container.GetType(typeof(SignedType), 4);

				if (Type is FloatType)
				{
					return new ConstExpressionNode(Type, (double)Ret, Code);
				}
				else if (Type is NonFltNumType)
				{
					var NFltTp = Type as NonFltNumType;
					if (Ret <= NFltTp.MaxValue && Ret >= NFltTp.MinValue)
					{
						if (NFltTp is SignedType)
							return new ConstExpressionNode(Type, (long)Ret, Code);
						else if (NFltTp is UnsignedType)
							return new ConstExpressionNode(Type, (ulong)Ret, Code);
						else throw new Exception("ERROR");
					}
				}
			}
			else
			{
				var Str1 = Num.Substring(0, P);
				var Str2 = Num.Substring(P + 1);

				BigInteger N1, N2;
				if (!Str1.ConvertToDec(Radix, LetterCase.Upper, out N1) || 
					!Str2.ConvertToDec(Radix, LetterCase.Upper, out N2))
				{
					State.Messages.Add(MessageId.ConstNumErr, Code);
					return null;
				}

				var Dbl = (double)N1 + (double)N2 / (double)(Str2.Length * Radix);
				if (Negative) Dbl = -Dbl;

				if (Type == null) Type = Container.GetType(typeof(FloatType), 8);
				if (Type is FloatType) return new ConstExpressionNode(Type, Dbl, Code);
			}

			State.Messages.Add(MessageId.ConstOutOfRange, Code);
			return null;
		}

		public static ConstExpressionNode GetStringNode(PString Code, IdContainer Container)
		{
			var GlbScope = Container.GlobalScope;
			var PlugIn = new GlobalPlugIn(Container);
			PlugIn.GetPlugIn<TypeMgrPlugIn>().RetType = GlbScope.CStrType;
			return Expressions.NewExpressionTree(Code, PlugIn) as ConstExpressionNode;
		}
    }

}

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