123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- using System;
- using System.Collections.Concurrent;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using NTERA.Interpreter;
- using NTERA.Interpreter.Compiler;
- namespace NTERA.Compiler
- {
- public class Compiler
- {
- public string InputDirectory { get; }
- public List<Tuple<ParserError, string>> Errors { get; } = new List<Tuple<ParserError, string>>();
- public Dictionary<FunctionDefinition, string> DeclaredFunctions = new Dictionary<FunctionDefinition, string>();
- public Compiler(string inputDirectory)
- {
- InputDirectory = inputDirectory;
- }
- public void Compile(string outputDirectory)
- {
- var globals = new VariableDictionary
- {
- ["LOCAL"] = 0,
- ["LOCALS"] = "",
- ["ARG"] = "",
- ["ARGS"] = "",
- ["GLOBAL"] = "",
- ["GLOBALS"] = "",
- ["NICKNAME"] = "",
- ["MASTERNAME"] = "",
- ["CSTR"] = "",
- ["CUP"] = "",
- ["CDOWN"] = "",
- ["DOWNBASE"] = "",
- ["TCVAR"] = "",
- ["CDFLAG"] = "",
- ["ITEMPRICE"] = "",
- ["TRAINNAME"] = "",
- ["BASENAME"] = "",
- ["EQUIPNAME"] = "",
- ["TEQUIPNAME"] = "",
- ["STAINNAME"] = "",
- ["EXNAME"] = "",
- ["SOURCENAME"] = "",
- ["FLAGNAME"] = "",
- ["TFLAGNAME"] = "",
- ["CFLAGNAME"] = "",
- ["TCVARNAME"] = "",
- ["STRNAME"] = "",
- ["TSTRNAME"] = "",
- ["CSTRNAME"] = "",
- ["SAVESTRNAME"] = "",
- ["CDFLAGNAME"] = "",
- ["CDFLAGNAME"] = "",
- ["GLOBALNAME"] = "",
- ["GLOBALSNAME"] = "",
- ["GAMEBASE_AUTHOR"] = "",
- ["GAMEBASE_INFO"] = "",
- ["GAMEBASE_YEAR"] = "",
- ["GAMEBASE_TITLE"] = "",
- ["GAMEBASE_GAMECODE"] = "",
- ["GAMEBASE_VERSION"] = "",
- ["GAMEBASE_ALLOWVERSION"] = "",
- ["GAMEBASE_DEFAULTCHARA"] = "",
- ["GAMEBASE_NOITEM"] = "",
- ["WINDOW_TITLE"] = "",
- ["MONEYLABEL"] = "",
- ["DRAWLINESTR"] = "",
- ["LASTLOAD_VERSION"] = "",
- ["LASTLOAD_NO"] = "",
- ["LASTLOAD_TEXT"] = "",
- ["SAVEDATA_TEXT"] = "",
- ["TSTR"] = "",
- ["RANDDATA"] = "",
- ["LINECOUNT"] = "",
- ["ISTIMEOUT"] = "",
- ["__INT_MAX__"] = "",
- ["__INT_MIN__"] = "",
- ["NAME"] = "",
- ["CALLNAME"] = "",
- ["RAND"] = "",
- ["CHARANUM"] = "",
- ["TALENT"] = "",
- ["FLAG"] = "",
- ["TFLAG"] = "",
- ["CFLAG"] = "",
- ["MASTER"] = "",
- ["BASE"] = "",
- ["MAXBASE"] = "",
- ["SOURCE"] = "",
- ["ABL"] = "",
- ["PALAM"] = "",
- ["TEQUIP"] = "",
- ["EQUIP"] = "",
- ["DAY"] = "",
- ["MARK"] = "",
- ["PALAMLV"] = "",
- ["TARGET"] = "",
- ["PLAYER"] = "",
- ["NOWEX"] = "",
- ["EX"] = "",
- ["EXNAME"] = "",
- ["STAIN"] = "",
- ["EXP"] = "",
- ["ASSIPLAY"] = "",
- ["ASSI"] = "",
- ["ITEM"] = "",
- ["EXPLV"] = "",
- ["TIME"] = "",
- ["MONEY"] = "",
- ["SELECTCOM"] = "",
- ["JUEL"] = "",
- ["STR"] = "",
- ["PREVCOM"] = "",
- ["SAVESTR"] = "",
- ["ABLNAME"] = "",
- ["MARKNAME"] = "",
- ["TALENTNAME"] = "",
- ["ITEMNAME"] = "",
- ["PALAMNAME"] = "",
- ["EXPNAME"] = "",
- ["DITEMTYPE"] = "",
- ["NO"] = "",
- ["RELATION"] = "",
- ["IS"] = ""
- };
- foreach (char c in "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
- globals[c.ToString()] = "";
- var funcs = new List<FunctionDefinition>
- {
- new FunctionDefinition("RAND", new[] { new FunctionParameter("a", new string[0]), new FunctionParameter("b", new string[0]) }, new FunctionVariable[0], true, "_GLOBAL", new Marker()),
- new FunctionDefinition("TOSTR", new[] { new FunctionParameter("a", new string[0]), new FunctionParameter("b", new string[0], "") }, new FunctionVariable[0], true, "_GLOBAL", new Marker()),
- new FunctionDefinition("STRCOUNT", new[] { new FunctionParameter("input", new string[0]), new FunctionParameter("match", new string[0]) }, new FunctionVariable[0], true, "_GLOBAL", new Marker()),
- new FunctionDefinition("MIN", new[] { new FunctionParameter("a", new string[0], isArrayParameter: true), }, new FunctionVariable[0], true, "_GLOBAL", new Marker()),
- new FunctionDefinition("MAX", new[] { new FunctionParameter("a", new string[0], isArrayParameter: true), }, new FunctionVariable[0], true, "_GLOBAL", new Marker()),
- new FunctionDefinition("POWER", new[] { new FunctionParameter("a", new string[0]), new FunctionParameter("b", new string[0]) }, new FunctionVariable[0], true, "_GLOBAL", new Marker()),
- new FunctionDefinition("GETPALAMLV", new[] { new FunctionParameter("a", new string[0]), new FunctionParameter("b", new string[0]) }, new FunctionVariable[0], true, "_GLOBAL", new Marker()),
- new FunctionDefinition("GETBIT", new[] { new FunctionParameter("a", new string[0]), new FunctionParameter("b", new string[0]) }, new FunctionVariable[0], true, "_GLOBAL", new Marker()),
- new FunctionDefinition("UNICODE", new[] { new FunctionParameter("a", new string[0]) }, new FunctionVariable[0], true, "_GLOBAL", new Marker()),
- new FunctionDefinition("MATCH", new[] { new FunctionParameter("a", new string[0]), new FunctionParameter("b", new string[0]), new FunctionParameter("c", new string[0], "a"), new FunctionParameter("d", new string[0], "f"), }, new FunctionVariable[0], true, "_GLOBAL", new Marker()),
- new FunctionDefinition("INRANGE", new[] { new FunctionParameter("a", new string[0]), new FunctionParameter("b", new string[0]), new FunctionParameter("c", new string[0]), }, new FunctionVariable[0], true, "_GLOBAL", new Marker()),
- new FunctionDefinition("HE_SHE", new[] { new FunctionParameter("a", new string[0]), }, new FunctionVariable[0], true, "_GLOBAL", new Marker()),
- new FunctionDefinition("SUBSTRING", new[] { new FunctionParameter("a", new string[0]), new FunctionParameter("a", new string[0]), new FunctionParameter("a", new string[0]), }, new FunctionVariable[0], true, "_GLOBAL", new Marker()),
- new FunctionDefinition("STRLENS", new[] { new FunctionParameter("a", new string[0]), }, new FunctionVariable[0], true, "_GLOBAL", new Marker()),
- new FunctionDefinition("CSVNAME", new[] { new FunctionParameter("a", new string[0]), }, new FunctionVariable[0], true, "_GLOBAL", new Marker()),
- new FunctionDefinition("CSVNAME", new[] { new FunctionParameter("a", new string[0]), new FunctionParameter("a", new string[0]), }, new FunctionVariable[0], true, "_GLOBAL", new Marker()),
- new FunctionDefinition("CSVTALENT", new[] { new FunctionParameter("a", new string[0]), new FunctionParameter("a", new string[0]), }, new FunctionVariable[0], true, "_GLOBAL", new Marker()),
- new FunctionDefinition("CSVCSTR", new[] { new FunctionParameter("a", new string[0]), new FunctionParameter("a", new string[0]), }, new FunctionVariable[0], true, "_GLOBAL", new Marker()),
- new FunctionDefinition("GETNUM", new[] { new FunctionParameter("a", new string[0]), new FunctionParameter("a", new string[0]), }, new FunctionVariable[0], true, "_GLOBAL", new Marker()),
- new FunctionDefinition("FINDCHARA", new[] { new FunctionParameter("a", new string[0]), new FunctionParameter("a", new string[0]), new FunctionParameter("a", new string[0]), new FunctionParameter("a", new string[0]), }, new FunctionVariable[0], true, "_GLOBAL", new Marker()),
- new FunctionDefinition("LIMIT", new[] { new FunctionParameter("a", new string[0]), new FunctionParameter("a", new string[0]), new FunctionParameter("a", new string[0]), }, new FunctionVariable[0], true, "_GLOBAL", new Marker()),
- new FunctionDefinition("GETTIME", new FunctionParameter[0], new FunctionVariable[0], true, "_GLOBAL", new Marker()),
- new FunctionDefinition("SAVENOS", new FunctionParameter[0], new FunctionVariable[0], true, "_GLOBAL", new Marker()),
- new FunctionDefinition("GETCOLOR", new FunctionParameter[0], new FunctionVariable[0], true, "_GLOBAL", new Marker()),
- new FunctionDefinition("CURRENTREDRAW", new FunctionParameter[0], new FunctionVariable[0], true, "_GLOBAL", new Marker()),
- };
- var stringStatements = new List<string>
- {
- "DRAWLINEFORM",
- "PRINTFORML",
- "PRINT",
- "PRINTW",
- "PRINTV",
- "PRINTL",
- "PRINTLC",
- "PRINTC",
- "ALIGNMENT",
- "CALL",
- "CUSTOMDRAWLINE",
- "DATAFORM",
- "GOTO",
- "PRINTFORMDL",
- "PRINTFORMW",
- "PRINTFORMDW",
- "PRINTFORMC",
- "PRINTFORMLC",
- "PRINTFORM",
- "PRINTPLAINFORM",
- "DEBUGPRINTL",
- "DEBUGPRINTFORML",
- "REUSELASTLINE",
- "PRINTPLAIN",
- "PRINT_TRAIN_NAME",
- "PRINT_STR",
- };
- string csvPath = Path.Combine(InputDirectory, "CSV");
- string erbPath = Path.Combine(InputDirectory, "ERB");
- var csvDefinition = new CSVDefinition();
- foreach (var file in Directory.EnumerateFiles(csvPath, "*.csv", SearchOption.AllDirectories))
- {
- string path = Path.GetFileNameWithoutExtension(file);
- if (path.EndsWith("_TR"))
- continue;
- Preprocessor.ProcessCSV(csvDefinition, path, File.ReadLines(file, Encoding.UTF8));
- }
- ConcurrentDictionary<FunctionDefinition, string> preprocessedFunctions = new ConcurrentDictionary<FunctionDefinition, string>();
- #if DEBUG
- foreach (var file in Directory.EnumerateFiles(erbPath, "*.erb", SearchOption.AllDirectories))
- #else
- Parallel.ForEach(Directory.EnumerateFiles(erbPath, "*.erb", SearchOption.AllDirectories), new ParallelOptions
- {
- MaxDegreeOfParallelism = 4
- }, file =>
- #endif
- {
- try
- {
- foreach (var kv in Preprocessor.PreprocessFile(File.ReadAllText(file), Path.GetFileName(file)))
- preprocessedFunctions[kv.Key] = kv.Value;
- }
- catch (Exception ex)
- {
- lock (Errors)
- Errors.Add(new Tuple<ParserError, string>(new ParserError($"Internal pre-process lexer error [{ex}]", new Marker()), Path.GetFileName(file)));
- }
- #if DEBUG
- }
- #else
- });
- #endif
- DeclaredFunctions = preprocessedFunctions.ToDictionary(kv => kv.Key, kv => kv.Value);
- funcs.AddRange(DeclaredFunctions.Keys.Where(x => x.IsReturnFunction));
- var procedures = DeclaredFunctions.Keys.Where(x => !x.IsReturnFunction).ToList();
- #if DEBUG
- foreach (var kv in DeclaredFunctions)
- #else
- Parallel.ForEach(DeclaredFunctions, new ParallelOptions
- {
- MaxDegreeOfParallelism = 4
- }, kv =>
- #endif
- {
- try
- {
- var locals = new VariableDictionary();
- foreach (var param in kv.Key.Variables)
- locals[param.Name] = param.DefaultValue ?? param.ValueType == Interpreter.ValueType.String ? new Value("") : new Value(0d);
- Parser parser = new Parser(kv.Value, kv.Key, funcs, procedures, globals, locals, stringStatements, csvDefinition);
- var nodes = parser.Parse(out var localErrors);
- lock (Errors)
- Errors.AddRange(localErrors.Select(x => new Tuple<ParserError, string>(x, $"{kv.Key.Filename} - {kv.Key.Name}")));
- }
- catch (Exception ex)
- {
- lock (Errors)
- Errors.Add(new Tuple<ParserError, string>(new ParserError($"Internal post-process lexer error [{ex}]", new Marker()), $"{kv.Key.Filename} - {kv.Key.Name}"));
- }
- #if DEBUG
- }
- #else
- });
- #endif
- long fileSize = 0;
- int fileCount = 0;
- foreach (var file in Directory.EnumerateFiles(InputDirectory, "*.erb", SearchOption.AllDirectories))
- {
- var info = new FileInfo(file);
- fileSize += info.Length;
- fileCount++;
- }
- var htmlWriter = new HTMLWriter
- {
- Errors = Errors.OrderBy(x => x.Item2).ToList(),
- FunctionCount = DeclaredFunctions.Count,
- TotalFileSize = fileSize,
- TotalFileCount = fileCount
- };
- using (var stream = File.Create(Path.Combine(outputDirectory, "report.html")))
- htmlWriter.WriteReportToFile(stream);
- }
- }
- }
|