Click here to Skip to main content
15,896,111 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 384.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.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;

namespace Anonymus
{
	public class CodeFile
	{
		public string FilePath;
		public string[] Lines;

        public CodeFile(string FilePath)
		{
            FilePath = Path.GetFullPath(FilePath);

            this.FilePath = FilePath;
            Lines = File.ReadAllLines(FilePath);
		}
	}
	
	public class Settings
	{
        public string Architecture;
        public string Debug;
        public string Format;
        public string Entry;

		public Settings(BinaryReader br)
		{
            Architecture = br.ReadString();
            Debug = br.ReadString();
		}

        public Settings()
        {
            Architecture = "x86";
            Debug = "false";
            Format = "console";
            Entry = "Main";
        }

		public void Save(BinaryWriter bw)
		{
            bw.Write(Architecture);
			bw.Write(Debug);
		}
	}

	public class Project
	{
		public static Encoding Encoding = new UnicodeEncoding();

		public string FileName;
		public List<CodeFile> CodeFiles;
		public Settings Settings;

		public string ProjDir
		{
			get { return Path.GetDirectoryName(FileName); }
		}

        public string OutName
        {
            get
            {
                var Ret = Path.GetFileNameWithoutExtension(FileName);
                if (Settings.Debug == "true") Ret += ".debug";
                else if (Settings.Debug == "false") Ret += ".release";
                Ret += "." + Settings.Architecture;
                return Ret;
            }
        }

		public Project()
		{
			FileName = "";
			CodeFiles = new List<CodeFile>();
            Settings = new Settings();
		}

		public Project(string FileName)
		{
			this.FileName = FileName;

			using (var br = new BinaryReader(File.OpenRead(FileName), Encoding))
			{
				var Count = br.ReadInt32();
				CodeFiles = new List<CodeFile>();

				for (int i = 0; i < Count; i++)
					CodeFiles.Add(new CodeFile(br.ReadString()));

				Settings = new Settings(br);
			}
		}

		public void Save(string Path = null)
		{
            if (Path != null) FileName = Path;

            if (File.Exists(FileName))
                File.Delete(FileName);

            using (var bw = new BinaryWriter(File.OpenWrite(FileName), Encoding))
			{
				bw.Write(CodeFiles.Count);
				foreach (var e in CodeFiles)
                    bw.Write(e.FilePath);

				Settings.Save(bw);
			}
		}

		public void SetSetting(string Name, string Value)
		{
            Name = Name.ToLower();
			var Type = typeof(Settings);
			var Ret = Type.GetField(Name);

            if (Ret == null)
            {
                Console.WriteLine("Unknown settings");
            }
            else
            {
                if (Name != "entry") Value = Value.ToLower();
                Ret.SetValue(Settings, Value);
            }
		}

		public PString[] GetLines()
		{
			if (CodeFiles.Count == 0)
				return null;

			var Ret = (IEnumerable<PString>)null;
			foreach (var e in CodeFiles)
			{
                var Ps = Helper.StrToPStrArr(e.FilePath, e.Lines);
				if (Ret == null) Ret = Ps;
				else Ret = Ret.Union(Ps);
			}

			return Ret != null ? Ret.ToArray() : null;
		}

        public void Assemble(CompilerState State, string AsmCode)
        {
            var OutDir = ProjDir;
            var s = Path.DirectorySeparatorChar;

            if (!(OutDir.Length > 0 && OutDir[OutDir.Length - 1] == s))
                OutDir += Path.DirectorySeparatorChar;

            OutDir += ".as";
            if (!Directory.Exists(OutDir))
                Directory.CreateDirectory(OutDir);

            var oName = OutDir + Path.DirectorySeparatorChar + OutName;
            var AsmFile = oName + ".s";
            File.WriteAllText(AsmFile, AsmCode);
            
            var StartInfo = new ProcessStartInfo("fasm.exe", AsmFile);
            StartInfo.UseShellExecute = false;
            var Proc = Process.Start(StartInfo);

            /*
            StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            StartInfo.RedirectStandardError = true;
            StartInfo.RedirectStandardOutput = true;

            var Proc = Process.Start(StartInfo);

            while (!Proc.HasExited)
            {
                Thread.Sleep(10);
                Console.WriteLine(Proc.StandardOutput.ReadToEnd());
                Console.WriteLine(Proc.StandardError.ReadToEnd());
            }
            */
        }

        public bool ApplySettings(CompilerState State)
        {
			var RetValue = true;
            var SErrs = new List<string>();

			if (Settings.Architecture == "x86") State.Arch = new x86.x86Architecture(false);
			else if (Settings.Architecture == "x64") State.Arch = new x86.x86Architecture(true);
			else SErrs.Add("Architecture = " + Settings.Architecture);

			if (Settings.Format == "gui") State.Format = ImageFormat.GUI;
			else if (Settings.Format == "console") State.Format = ImageFormat.Console;
            else if (Settings.Format == "dll") State.Format = ImageFormat.DLL;
            else if (Settings.Format == "asdll") State.Format = ImageFormat.AsDLL;
            else SErrs.Add("Format = " + Settings.Format);

			if (Settings.Entry == "" && (State.Format == ImageFormat.GUI ||
				State.Format == ImageFormat.Console))
			{
				State.Messages.Add(MessageId.EntryNotSpecified, (PString)null);
				RetValue = false;
			}
			else
			{
				State.Entry = Settings.Entry;
			}

            if (SErrs.Count > 0)
            {
                foreach (var e in SErrs)
                    State.Messages.Add(MessageId.WrongSettings, (PString)null, e);

                return false;
            }

            return RetValue;
        }

		public void Compile(CompilerState State = null, bool Asm = true)
		{
			if (State == null) State = new CompilerState(null, null);
			else State.Messages.Messages = new List<Message>();

            if (ApplySettings(State))
            {
                var Lines = GetLines();
                if (Lines != null)
                {
					var Compiler = State.Arch.CreateCompiler(State);
                    Compiler.Compile(State, Lines);
					var AsmCode = Compiler.GetAssembly().Replace("\n", "\r\n");
                    if (AsmCode != null && Asm) Assemble(State, AsmCode.ToString());
                }
                else
                {
                    Console.WriteLine("Nothing to compile");
                    return;
                }
            }

			State.Messages.WriteToConsole();
		}
	}

	public class Program
	{
        public static void MakeFTest()
        {
            if (File.Exists("Txt\\FTest.txt"))
                File.Delete("Txt\\FTest.txt");

            var sw = new StreamWriter("Txt\\FTest.txt");
            sw.WriteLine("#define Func(x, y, z) (x + y) * z");
            sw.WriteLine();

            var LineCount = 2;
            var i = 0;

            while (LineCount < 10000)
            {
				var c = i > 0 ? i.ToString() : "";
                sw.WriteLine("void Main" + c + "()");
                sw.WriteLine("\tint x = Func(1, 2, 3),");
                sw.WriteLine("\t    y = Func(2, 3, 4),");
                sw.WriteLine("\t    z = Func(5, 6, 7)");
                sw.WriteLine();
                sw.WriteLine("\tint w = x + y + z");
                sw.WriteLine();
                sw.WriteLine("\tfor int i = 0 until x");
				sw.WriteLine("\t\tfor int j = 0 until y");
				sw.WriteLine("\t\t\tfor int k = 0 until z");
                sw.WriteLine("\t\t\t\tif i > j and i > k and j > k");
				sw.WriteLine("\t\t\t\t\ti = 0");
                sw.WriteLine();

                LineCount += 13;
                i++;
            }

            sw.Close();
        }

        public static void Pipe()
        {
            var Projects = new List<Project>();
            var CurrProject = (Project)null;
            var NewProjCount = 0;

            var Str = (PString)null;
            var Exit = false;

            while (!Exit)
            {
                try
                {
                    Str = new PString(Console.ReadLine().ToLower());
                    var Word = Str.Word();
                    Str.TrimThis();

                    if (Word.String == "new")
                    {
                        if (!Directory.Exists("tmp"))
                            Directory.CreateDirectory("tmp");

                        var Proj = new Project();
                        var c = (++NewProjCount).ToString();
                        Proj.FileName = Path.GetFullPath("tmp\\untitled" + c + ".asproj");
                        CurrProject = Proj;
                    }

                    else if (Word.String == "load")
                    {
                        CurrProject = new Project(Str.String);
                    }

                    else if (Word.String == "setproj")
                    {
                        var ok = false;
                        foreach (var e in Projects)
                            if (e.FileName == Str.String)
                            {
                                CurrProject = e;
                                ok = true;
                                break;
                            }

                        if (!ok) Console.WriteLine("Unloaded project");
                    }

                    else if (Word.String == "setsetting")
                    {
                        if (CurrProject == null)
                        {
                            Console.WriteLine("Unknown project");
                        }
                        else
                        {
                            var Name = Str.Word().String.Trim();
                            var Value = Str.Word().String.Trim();
                            CurrProject.SetSetting(Name, Value);
                        }
                    }

                    else if (Word.String == "save")
                    {
                        if (CurrProject == null) Console.WriteLine("Unknown project");
                        else CurrProject.Save();
                    }

                    else if (Word.String == "saveas")
                    {
                        if (CurrProject == null) Console.WriteLine("Unknown project");
                        else CurrProject.Save(Str.String);
                    }

                    else if (Word.String == "compile")
                    {
                        if (CurrProject == null) Console.WriteLine("Unknown project");
                        else CurrProject.Compile();
                    }

                    else if (Word.String == "addfile")
                    {
                        if (CurrProject == null) Console.WriteLine("Unknown project");
                        else CurrProject.CodeFiles.Add(new CodeFile(Str.String));
                    }

                    else if (Word.String == "getcurrent")
                    {
                        if (CurrProject == null) Console.WriteLine("Unknown project");
                        else Console.WriteLine(CurrProject.FileName);
                    }

                    else if (Word.String == "getprojects")
                    {
                        foreach (var e in Projects)
                            Console.WriteLine(e.FileName);
                    }

                    else if (Word.String == "exit")
                    {
                        Exit = true;
                    }

                    else
                    {
                        Console.WriteLine("Unknown command");
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                    Console.WriteLine(e.StackTrace);
                }
            }
        }

        public static void Main(string[] Args)
		{
			if (Args.Length < 2)
			{
				Console.WriteLine("Command line error");
				return;
			}

			var LinesLst = new List<PString>(1024);
			for (var i = 0; i < Args.Length - 1; i++)
			{
				var fLines = File.ReadAllLines(Args[i]);
				for (var lIndex = 0; lIndex < fLines.Length; lIndex++)
					LinesLst.Add(new PString(Args[i], lIndex, 0, fLines[lIndex]));
			}

			var Lines = LinesLst.ToArray();
			LinesLst = null;

			var Arch = new x86.x86Architecture(false);
			var Lang = new AsLang.AsLanguage();
			var State = new CompilerState(Arch, Lang);
			State.Entry = "AsEntry";
			State.Format = ImageFormat.MSCoff;

			var Compiler = Arch.CreateCompiler(State);
			if (Compiler.Compile(State, Lines))
			{
				Console.WriteLine("A fordítás sikeres.");
				State.Messages.WriteToConsole();
				File.WriteAllText(Args[Args.Length - 1], Compiler.GetAssembly());
			}
			else
			{
				Console.WriteLine("A fordítás sikertelen.");
				State.Messages.WriteToConsole();
			}


			/*
            if (Args[0] == "-pipe")
            {
                if (Args.Length == 1) Pipe();
                else Console.WriteLine("Commandline error");
            }
            else
            {
                if (Args.Length == 1)
                {
                    try
                    {
                        var Proj = new Project(Args[1]);
                        Proj.Compile(null, true);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                    }
                }
                else
                {
                    Console.WriteLine("Commandline error");
                }
            }
			*/
		}
	}
}

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