private void LoadHllFiles(string libraryPath)
        {
            string[] hllFiles = Directory.GetFiles(libraryPath, "*.hll", SearchOption.AllDirectories);
            List <TokenExpression> tokens2 = new List <TokenExpression>();

            foreach (string hllFile in hllFiles)
            {
                IncludeFile(hllFile, tokens2);
                var    firstPass   = new FirstPass();
                var    tokens3     = firstPass.CompileFirstPass(tokens2);
                string libraryName = Path.GetFileNameWithoutExtension(hllFile);
                CreateHllSymbols(tokens3, libraryName, libraryName);
                tokens2.Clear();
            }
        }
        private bool IncludeHll(string hllFile, string alias)
        {
            if (!File.Exists(hllFile))
            {
                return(false);
            }
            List <TokenExpression> tokens2 = new List <TokenExpression>();

            IncludeFile(hllFile, tokens2);
            var firstPass = new FirstPass();
            var tokens3   = firstPass.CompileFirstPass(tokens2);

            if (firstPass.Errors.Count > 0)
            {
                return(false);
            }
            CreateHllSymbols(tokens3, Path.GetFileNameWithoutExtension(hllFile), alias);
            return(true);
        }
Example #3
0
        public void Compile(string projectFilename)
        {
            this.stopwatch.Start();

            var lastDefaultAinFile = Expression.defaultAinFile;

            try
            {
                Expression.defaultAinFile = this.ainFile;

                if (worker != null)
                {
                    worker.ReportProgress(0, "Loading files...");
                }

                List <TokenExpression> tokens = new List <TokenExpression>();
                PreprocessInclude(projectFilename, tokens);
                if (this.TargetVMVersion >= 430)
                {
                    this.UseSimplifiedCode = true;
                }

                ainFile.Version           = this.AinVersion;
                ainFile.TargetVMVersion   = this.TargetVMVersion;
                ainFile.KeyCode           = this.KeyCode;
                ainFile.IsAi2File         = this.IsAi2File;
                ainFile.UsesMsg1          = this.UsesMsg1;
                ainFile.GameVersion       = this.gameVersion;
                ainFile.UseSimplifiedCode = this.UseSimplifiedCode;
                if (ainFile.Version >= 6)
                {
                    this.Messages.DoNotCombine = true;
                }

                if (worker != null)
                {
                    worker.ReportProgress(20, "First pass, finding functions and classes and other symbols...");
                }

                var firstPass = new FirstPass();
                if (this.Error != null)
                {
                    firstPass.Error += this.Error;
                }

                var result = firstPass.CompileFirstPass(tokens);
                if (firstPass.Errors.Count > 0)
                {
                    return;
                }
                var functionsToOutput = CreateSymbols(result);

                GetInitialValues(result);

                DefineZeroFunction();

                if (worker != null)
                {
                    worker.ReportProgress(40, "Second pass, parsing the code...");
                }

                if (!CompileSecondPass())
                {
                    return;
                }

                if (worker != null)
                {
                    worker.ReportProgress(60, "Compiling the code...");
                }

                GenerateExpressions();

                if (worker != null)
                {
                    worker.ReportProgress(80, "Generating binary code...");
                }


                //List<object> FunctionsToOutput = GetFunctionsToOutput(tokens);

                string prefixLowercase = Path.GetFullPath(mainSourcePrefix).ToLowerInvariant();
                if (!prefixLowercase.EndsWith(Path.DirectorySeparatorChar.ToString()))
                {
                    prefixLowercase += Path.DirectorySeparatorChar;
                }

                var codeGenerator = new CodeGenerator(ainFile);
                foreach (var node in functionsToOutput)
                {
                    var function = node as Function;
                    if (function != null)
                    {
                        var expression = this.FunctionDefinitions.GetOrNull(function);
                        function.Address = codeGenerator.Address + 6;
                        codeGenerator.GenerateCodeForFunction(expression);
                    }
                    string filename = node as string;
                    if (filename != null)
                    {
                        filename = Path.GetFullPath(filename);
                        if (filename.StartsWith(prefixLowercase, StringComparison.OrdinalIgnoreCase))
                        {
                            filename = filename.Substring(prefixLowercase.Length);
                        }
                        else
                        {
                        }
                        int fileNameNumber = ainFile.Filenames.Count;
                        ainFile.Filenames.Add(filename);
                        codeGenerator.WriteInstruction(Instruction.EOF, fileNameNumber);
                    }
                }

                ainFile.Code = codeGenerator.Code.ToArray();
                string outputFileName = Path.Combine(Path.GetDirectoryName(projectFilename), this.codeName);
                ainFile.MAIN = Functions.Contains("main") ? (Functions.Get("main").Index) : -1;
                ainFile.MSGF = Functions.Contains("message") ? (Functions.Get("message").Index) : -1;
                ainFile.OJMP = Functions.Contains("onjump") ? (Functions.Get("onjump").Index) : -1;
                RemoveFunctypes(ainFile);
                FixStructs(ainFile);
                ainFile.ComputeFunctionHashes();
                SortGlobalInitialValues(ainFile);
                SortSwitchCases(ainFile);

                if (worker != null)
                {
                    worker.ReportProgress(100, "Saving AIN file...");
                }
                ainFile.WriteAndEncryptAinFile(outputFileName);
                ainFile.OriginalFilename = outputFileName;
            }
            finally
            {
                Expression.defaultAinFile = lastDefaultAinFile;
            }
        }
Example #4
0
        public void CompileCode(string codeText, out byte[] codeBytes, out string disassembledCode, bool topLevel, Dictionary <string, string> codePatches)
        {
            int oldStructCount   = ainFile.Structs.Count;
            int oldFunctionCount = ainFile.Functions.Count;
            int oldSwitchCount   = ainFile.Switches.Count;
            int oldFunctypeCount = ainFile.FunctionTypes.Count;
            int oldDelegateCount = ainFile.Delegates.Count;
            int oldGlobalCount   = ainFile.Globals.Count;
            int oldLibraryCount  = ainFile.Libraries.Count;

            codeBytes        = null;
            disassembledCode = null;

            var lastDefaultAinFile = Expression.defaultAinFile;

            try
            {
                if (!topLevel)
                {
                    string dummyFunctionName = "DUMMY" + dummyFunctionNumber.ToString("0000");
                    codeText = "void " + dummyFunctionName + "()" + Environment.NewLine + "{" + Environment.NewLine + codeText + Environment.NewLine + "}" + Environment.NewLine;
                    dummyFunctionNumber++;
                }
                List <TokenExpression> tokens = new List <TokenExpression>();
                IncludeString(codeText, tokens);

                ainFile.Version           = this.AinVersion;
                ainFile.TargetVMVersion   = this.TargetVMVersion;
                ainFile.IsAi2File         = this.IsAi2File;
                ainFile.UsesMsg1          = this.UsesMsg1;
                ainFile.KeyCode           = this.KeyCode;
                ainFile.GameVersion       = this.gameVersion;
                ainFile.UseSimplifiedCode = this.UseSimplifiedCode;
                if (ainFile.Version >= 6)
                {
                    this.Messages.DoNotCombine = true;
                }

                var firstPass = new FirstPass();
                if (this.Error != null)
                {
                    firstPass.Error += this.Error;
                }

                var result = firstPass.CompileFirstPass(tokens);
                if (firstPass.Errors.Count > 0)
                {
                    this.Errors.AddRange(firstPass.Errors);
                    return;
                }

                bool createAdditionalFunctions = topLevel;
                var  symbolsCreated            = CreateSymbols(result, createAdditionalFunctions);
                var  functionsToOutput         = symbolsCreated.OfType <Function>().ToArray();
                var  structsCreated            = symbolsCreated.OfType <Struct>().ToArray();
                var  librariesToOutput         = symbolsCreated.OfType <HllLibrary>().ToArray();
                if (ainFile.Libraries.Count > oldLibraryCount + librariesToOutput.Length)
                {
                    //fix missing libraries
                    librariesToOutput = librariesToOutput.Concat(ainFile.Libraries.Skip(oldLibraryCount)).ToArray();
                }

                GetInitialValues(result);
                if (!CompileSecondPass())
                {
                    return;
                }
                GenerateExpressions();

                var codeGenerator = new CodeGenerator(ainFile);
                foreach (var function in functionsToOutput)
                {
                    var expression = this.FunctionDefinitions.GetOrNull(function);
                    function.Crc     = 0;
                    function.Address = codeGenerator.Address + 6;
                    codeGenerator.GenerateCodeForFunction(expression);
                }

                var writer = new AssemblerProjectWriter(ainFile);
                codeBytes = codeGenerator.Code.ToArray();

                StringWriter    sw = new StringWriter();
                List <Function> functionsToOutput2 = new List <Function>();

                foreach (var function in functionsToOutput)
                {
                    bool handled = false;
                    if (codePatches != null)
                    {
                        if (function.Index < oldFunctionCount)
                        {
                            disassembledCode           = writer.GetDisassembledCode(function, codeBytes);
                            codePatches[function.Name] = disassembledCode;
                            //writer.GetDisassembledCode(codeBytes, new Function[] { function }, ainFile.Structs.Count, ainFile.Delegates.Count, ainFile.FunctionTypes.Count, ainFile.Globals.Count);
                            handled = true;
                        }
                    }

                    if (!handled)
                    {
                        functionsToOutput2.Add(function);
                    }
                }

                writer.GetDisassembledCode(sw, codeBytes, functionsToOutput, functionsToOutput2.ToArray(), structsCreated, librariesToOutput, oldDelegateCount, oldFunctypeCount, oldGlobalCount);
                disassembledCode = sw.ToString();

                ainFile.MAIN = Functions.Contains("main") ? (Functions.Get("main").Index) : -1;
                ainFile.MSGF = Functions.Contains("message") ? (Functions.Get("message").Index) : -1;
                ainFile.OJMP = Functions.Contains("onjump") ? (Functions.Get("onjump").Index) : -1;
                RemoveFunctypes(ainFile);
                FixStructs(ainFile);
                ainFile.ComputeFunctionHashes();
                SortGlobalInitialValues(ainFile);
                SortSwitchCases(ainFile);

                if (!topLevel && Errors.Count > 0)
                {
                    disassembledCode = null;
                    codeBytes        = null;
                }
            }
            finally
            {
                Expression.defaultAinFile = lastDefaultAinFile;

                if (!topLevel)
                {
                    this.FunctionDeclarationTokens.Clear();
                    this.FunctionDefinitionTokens.Clear();
                    this.FunctionDefinitions.Clear();
                }
            }
        }
Example #5
0
        public void CompileCodeInPlace(string codeText)
        {
            this.stopwatch.Start();

            var lastDefaultAinFile = Expression.defaultAinFile;

            try
            {
                Expression.defaultAinFile = this.ainFile;

                if (worker != null)
                {
                    worker.ReportProgress(0, "Loading files...");
                }

                List <TokenExpression> tokens = new List <TokenExpression>();
                IncludeString(codeText, tokens);

                ainFile.Version           = this.AinVersion;
                ainFile.TargetVMVersion   = this.TargetVMVersion;
                ainFile.KeyCode           = this.KeyCode;
                ainFile.IsAi2File         = this.IsAi2File;
                ainFile.UsesMsg1          = this.UsesMsg1;
                ainFile.GameVersion       = this.gameVersion;
                ainFile.UseSimplifiedCode = this.UseSimplifiedCode;
                if (ainFile.Version >= 6)
                {
                    this.Messages.DoNotCombine = true;
                }

                if (worker != null)
                {
                    worker.ReportProgress(20, "First pass, finding functions and classes and other symbols...");
                }

                var firstPass = new FirstPass();
                if (this.Error != null)
                {
                    firstPass.Error += this.Error;
                }

                var result = firstPass.CompileFirstPass(tokens);
                if (firstPass.Errors.Count > 0)
                {
                    this.Errors.AddRange(firstPass.Errors);
                    return;
                }
                var symbolsCreated = CreateSymbols(result, false);

                GetInitialValues(result);

                //DefineZeroFunction();

                if (worker != null)
                {
                    worker.ReportProgress(40, "Second pass, parsing the code...");
                }

                if (!CompileSecondPass())
                {
                    return;
                }

                if (worker != null)
                {
                    worker.ReportProgress(60, "Compiling the code...");
                }

                GenerateExpressions();

                if (worker != null)
                {
                    worker.ReportProgress(80, "Generating binary code...");
                }

                var codeGenerator = new CodeGenerator(ainFile);
                codeGenerator.Code.Write(ainFile.Code, 0, ainFile.Code.Length);
                codeGenerator.Address = ainFile.Code.Length;
                var functionsToOutput = symbolsCreated.OfType <Function>().ToArray();

                foreach (var function in functionsToOutput)
                {
                    var expression = this.FunctionDefinitions.GetOrNull(function);
                    function.Address = codeGenerator.Address + 6;
                    function.Crc     = 0;
                    codeGenerator.GenerateCodeForFunction(expression);
                }

                ainFile.Code = codeGenerator.Code.ToArray();
                ainFile.MAIN = Functions.Contains("main") ? (Functions.Get("main").Index) : -1;
                ainFile.MSGF = Functions.Contains("message") ? (Functions.Get("message").Index) : -1;
                ainFile.OJMP = Functions.Contains("onjump") ? (Functions.Get("onjump").Index) : -1;
                RemoveFunctypes(ainFile);
                FixStructs(ainFile);
                ainFile.ComputeFunctionHashes();
                SortGlobalInitialValues(ainFile);
                SortSwitchCases(ainFile);

                if (worker != null)
                {
                    worker.ReportProgress(100, "Saving AIN file...");
                }
            }
            finally
            {
                Expression.defaultAinFile = lastDefaultAinFile;
            }
        }