Esempio n. 1
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;
            }
        }