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); }
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; } }
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(); } } }
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; } }