Click here to Skip to main content
15,886,760 members
Articles / High Performance Computing / Vectorization

Bird Programming Language: Part 1

Rate me:
Please Sign up or sign in to vote.
4.92/5 (129 votes)
1 Jan 2013GPL312 min read 377.6K   2.7K   153  
A new general purpose language that aims to be fast, high level and simple to use.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Anonymus
{
	public delegate void CodeCondBranchFunc(Compiler Compiler);

	public abstract class CondBranch
	{
	}

	public class JumpCodeBranch : CondBranch
	{
		public int Label;

		public JumpCodeBranch(int Label)
		{
			this.Label = Label;
		}
	}

	public class CodeCondBranch : CondBranch
	{
		public CodeCondBranchFunc GetCode;

		public CodeCondBranch(CodeCondBranchFunc GetCode)
		{
			this.GetCode = GetCode;
		}
	}

	public abstract class Instruction
	{
		public bool Skip = false;
		public abstract string GetCode(Compiler Comp);
	}

	public class LabelInstruction : Instruction
	{
		public int Label;

        public LabelInstruction(int Label)
		{
			this.Label = Label;
		}

		public override string GetCode(Compiler Comp)
		{
			return Comp.LabelStr("_" + Label);
		}
	}

	public abstract class JumpInstruction : Instruction
	{
		public int Label;

		public JumpInstruction(int Label)
		{
			this.Label = Label;
		}

		public override string GetCode(Compiler Comp)
		{
			return Comp.JumpStr("_" + Label);
		}
	}

    public class ReplaceableJumpInstruction : JumpInstruction
    {
        public ReplaceableJumpInstruction(int Label)
            : base(Label)
        {
        }
    }

	public class StrInstruction : Instruction
	{
		public string Instruction;

		public StrInstruction(string Instruction)
		{
			this.Instruction = Instruction;
		}

		public override string GetCode(Compiler Comp)
		{
			return Instruction;
		}
	}

    public delegate void ReplaceJumpsFunc(Compiler Compiler);

	public abstract class Compiler
	{
		public CompilerState State;
        public IdContainer Container;

		public List<Instruction> Instructions = new List<Instruction>();
		public Dictionary<int, int> LabelPositions;
        public Dictionary<int, ReplaceJumpsFunc> ReplaceJumps;

		public abstract string JumpStr(string Label);
		public abstract string LabelStr(string Label);
		public abstract void GetExprCode(ExpressionNode Node);

		public abstract void GetConditionCode(ExpressionNode Condition, CondBranch Then,
			CondBranch Else, bool ThenAllPathJumpAway = false, bool LinkedNodesCalced = false,
			int NextLabel = -1);

		public abstract void CalcCondAsmCode(ExpressionNode Node, int Then, int Else,
			Operator PrewOp, bool Last, bool LinkedNodesCalced = false);

		public abstract void DeclareLabelPtr(string Label);
		public abstract void DeclareLabelPtr(int Label);
		public abstract void Declare(Type Type, ConstData Data);
		public abstract void DeclareUnknownBytes(int Count);
		public abstract bool Compile(CompilerState State, PString[] Lines);

		public Compiler(CompilerState State)
		{
			this.State = State;
		}

		public void Jump(int Label)
		{
			Instructions.Add(new ReplaceableJumpInstruction(Label));
		}

		public void Label(int Label, bool Chk = true)
		{
            if (LabelPositions == null) LabelPositions = new Dictionary<int, int>();
			LabelPositions.Add(Label, Instructions.Count);

			var Ins = new LabelInstruction(Label);
			if (!Chk) Ins.Skip = false;
			Instructions.Add(Ins);
		}

        public void SetJumpReplacing(int Label, ReplaceJumpsFunc Compiler)
        {
            if (ReplaceJumps == null) ReplaceJumps = new Dictionary<int, ReplaceJumpsFunc>();
            ReplaceJumps.Add(Label, Compiler);
        }

		public void Jump(string Label)
		{
			Instructions.Add(new StrInstruction(JumpStr(Label)));
		}

		public void Label(string Label)
		{
			Instructions.Add(new StrInstruction(LabelStr(Label)));
		}

        public virtual void InitJumpOptimization()
        {
            foreach (var e in Instructions)
                e.Skip = e is LabelInstruction;
        }

		public virtual void OptimizeJumps()
		{
            InitJumpOptimization();
            for (var i = 0; i < Instructions.Count; i++)
            {
                var JumpIns = Instructions[i] as JumpInstruction;
                if (JumpIns != null && !JumpIns.Skip)
                {
                    JumpIns.Label = JumpsTo(JumpIns.Label);

                    var SkipPos = i + 1;
                    for (; SkipPos < Instructions.Count; SkipPos++)
                    {
                        var SIns = Instructions[SkipPos];
                        var SLabelIns = SIns as LabelInstruction;
                        if (SLabelIns != null && SLabelIns.Label != JumpIns.Label)
                            continue;

                        var SJumpIns = SIns as JumpInstruction;
                        if (SJumpIns == null || JumpIns.Label != SJumpIns.Label) break;
                        else SIns.Skip = true;
                    }

                    var LblIndex = LabelPositions[JumpIns.Label];
                    if (SkipPos == LblIndex) JumpIns.Skip = true;
                    else Instructions[LblIndex].Skip = false;
                }
            }
		}

        public virtual void Optimize()
        {
            OptimizeJumps();

            if (ReplaceJumps != null)
            {
                var New = State.Arch.CreateCompiler(State, Container);
                var Count = 0;

                for (var i = 0; i < Instructions.Count; i++)
                {
                    var Ins = Instructions[i];
                    var JumpIns = Ins as ReplaceableJumpInstruction;
                    if (!Ins.Skip && JumpIns != null && ReplaceJumps.ContainsKey(JumpIns.Label))
                    {
                        ReplaceJumps[JumpIns.Label](New);
                        Count++;
                        continue;
                    }

                    New.Append(Ins);
                }

                if (Count > 0)
                {
                    Set(New);
                    Optimize();
                }
            }
        }

        void Set(Compiler Compiler)
        {
            Instructions = Compiler.Instructions;
            LabelPositions = Compiler.LabelPositions;
        }

        public void Insert(int Index, Compiler Comp)
        {
            var P = Comp != null ? Comp.Instructions.Count - 1 : 0;
            if (LabelPositions != null)
            {
                foreach (var e in LabelPositions.Keys.ToArray())
                    if (LabelPositions[e] >= Index) LabelPositions[e] += P;
            }

            if (P > 0)
            {
                Instructions.InsertRange(Index, Comp.Instructions);
                if (Comp.LabelPositions != null)
                {
                    foreach (var e in Comp.LabelPositions)
                        LabelPositions.Add(e.Key, e.Value + Index);
                }
            }
        }

		public int JumpsTo(int Label)
		{
			var InsIndex = LabelPositions[Label];
			for (var i = InsIndex; i < Instructions.Count; i++)
			{
				var Ins = Instructions[i];
				if (Ins is JumpInstruction)
				{
					var JumpIns = Ins as JumpInstruction;
					return JumpsTo(JumpIns.Label);
				}
				else if (Ins is LabelInstruction)
					continue;
				else break;
			}

			return Label;
		}

		public string GetAssembly()
		{
			var Ret = new StringBuilder();
			foreach (var Ins in Instructions)
				if (!Ins.Skip) Ret.Append(Ins.GetCode(this));

			return Ret.ToString();
		}

		public void Append(Compiler Comp)
		{
			var Count = Instructions.Count;
			Instructions.AddRange(Comp.Instructions);

            if (Comp.LabelPositions != null)
            {
                foreach (var e in Comp.LabelPositions)
                    LabelPositions.Add(e.Key, e.Value + Count);
            }
		}

		public void Append(Instruction Ins)
		{
			if (Ins is LabelInstruction)
			{
				var LblIns = Ins as LabelInstruction;
                if (LabelPositions == null) LabelPositions = new Dictionary<int, int>();
				LabelPositions.Add(LblIns.Label, Instructions.Count);
			}

			Instructions.Add(Ins);
		}

		public void Append(string Str)
		{
			Instructions.Add(new StrInstruction(Str));
		}

		public void Append(StringBuilder Str)
		{
			Instructions.Add(new StrInstruction(Str.ToString()));
		}
	}

	public abstract class Architecture
	{
		public abstract ExprPlugIn CreatePlugIn(IdContainer Container);
		public abstract Compiler CreateCompiler(CompilerState State);
		public abstract FuncScopeNode CreateFuncScope(IdContainer Parent, PString Name, FunctionType Type, bool IsStatic, PString[] Source);
		public abstract void OnNewContainer(IdContainer Container);
		public abstract void OnNewIdentifier(Identifier Id);
		public abstract void CalcExprDataPos(CompilerState State, IdContainer Container, ExpressionNode Node);
		public abstract int GetAlign(Type Type);
		public abstract CondBranch[] GetBraches(Compiler Compiler, GlobalScopeNode Global,
			Command Then, Command Else, ref ExpressionNode Condition);

		public abstract int RegSize { get; }
		public abstract int RegCount { get; }
		public abstract int MaxStructPow2Size { get; }

		public Compiler CreateCompiler(CompilerState State, IdContainer Container)
		{
			var Ret = CreateCompiler(State);
            Ret.Container = Container;
			return Ret;
		}
	}
}

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)


Written By
Software Developer
Hungary Hungary
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions