public void Compile(Project proj) { ProjectFile = proj; //Make sure the build directory exists and create it if needed if (!Directory.Exists(proj.Buildfolder)) Directory.CreateDirectory(proj.Buildfolder); if (!Directory.Exists(proj.OutputFolder)) Directory.CreateDirectory(proj.OutputFolder); //Prepare some stuff needed for preprocessing Dictionary<string, PPDefine> defines = new Dictionary<string, PPDefine>(); foreach (var it in flagDefines) defines.Add(it.Name, it); List<preprocessFile_IfDefModes> ifdefs = new List<preprocessFile_IfDefModes>(); List<PostProcessFile> ppFiles = new List<PostProcessFile>(); //do the preprocessing preprocessFile(ifdefs, defines, proj, proj.Mainfile, proj.Mainfile.Substring(proj.Mainfile.LastIndexOf('\\') + 1), ppFiles); var ppMainFile = ppFiles[0]; if (outputFolderCleanup) { Logger.Instance.log(Logger.LogLevel.VERBOSE, "Cleaning up output dir"); cleanupRecursive(proj.OutputFolder); } int errCount = 0; //Check the syntax of all files in ppFiles foreach(var it in ppFiles) { //if (!noPrintOut) //{ // var stream = File.Create(proj.Buildfolder + it.Name + ".obj"); // it.resetPosition(); // it.FileStream.WriteTo(stream); // stream.Flush(); // stream.Close(); //} Scanner scanner = new Scanner(it.FileStream); Base baseObject = new Base(); Parser p = new Parser(scanner); Parser.UsedFiles = new List<string>(); p.BaseObject = baseObject; p.Parse(); if (p.errors.count > 0) { errCount += p.errors.count; Logger.Instance.log(Logger.LogLevel.ERROR, "In file '" + it.Name + "'"); } if (printOutMode > 0) { if (printOutMode == 1 && it == ppMainFile) { var stream = File.Create(proj.Buildfolder + it.Name + ".objF"); it.resetPosition(); it.FullFileStream.WriteTo(stream); stream.Flush(); stream.Close(); } if (printOutMode >= 2) { var stream = File.Create(proj.Buildfolder + it.Name + ".obj"); it.resetPosition(); it.FileStream.WriteTo(stream); stream.Flush(); stream.Close(); if (printOutMode >= 3) { var stream2 = File.Create(proj.Buildfolder + it.Name + ".objF"); it.resetPosition(); it.FullFileStream.WriteTo(stream2); stream2.Flush(); stream2.Close(); } else if(it == ppMainFile) { var stream2 = File.Create(proj.Buildfolder + it.Name + ".objF"); it.resetPosition(); it.FullFileStream.WriteTo(stream2); stream2.Flush(); stream2.Close(); } } } it.resetPosition(); } if(errCount > 0) { Logger.Instance.log(Logger.LogLevel.ERROR, "Errors found (" + errCount + "), cannot continue with Translating!"); return; } //process the actual file Base oosTreeBase = new Base(); NamespaceResolver.BaseClass = oosTreeBase; Parser parser = new Parser(new Scanner(ppMainFile.FullFileStream)); Parser.UsedFiles = new List<string>(); parser.BaseObject = oosTreeBase; parser.Parse(); errCount = parser.errors.count + parser.BaseObject.finalize(); if (errCount > 0) { Logger.Instance.log(Logger.LogLevel.ERROR, "Errors found (" + errCount + "), cannot continue with Comnpiling!"); return; } SqfConfigFile configFile = new SqfConfigFile(configFileName); oosTreeBase.writeOut(null, configFile); configFile.writeOut(proj.OutputFolder); }
public override void writeOut(System.IO.StreamWriter sw, SqfConfigObjects.SqfConfigFile cfg) { if (this.IsExternal) { return; } if (this.IsInline) { if (cfg == null) { cfg = new SqfConfigObjects.SqfConfigFile("inline"); } else { return; } } int index; string tab = new string('\t', this.getAllParentsOf <Interfaces.iCodeBlock>().Count); if (this.IsVirtual || this.IsInline) { tab += '\t'; } if (!this.IsVirtual) { var fqn = this.Name.FullyQualifiedName; var filePath = Wrapper.Compiler.ProjectFile.OutputFolder + fqn.Replace("::", "\\") + this.SqfSuffix; var fileFolderPath = filePath.Substring(0, filePath.LastIndexOf('\\')); if (!Directory.Exists(fileFolderPath) && !this.IsInline) { Directory.CreateDirectory(fileFolderPath); } if (sw == null) { sw = new System.IO.StreamWriter(filePath + ".sqf"); } int lIndex = fqn.LastIndexOf("::") - fqn.Count(c => c == ':') / 2 + 1; fqn = fqn.Replace("::", "_") + this.SqfSuffix; string lPath; string rPath; if (lIndex <= 0) { lPath = "UNCATEGORIZED"; rPath = fqn; Logger.Instance.log(Logger.LogLevel.WARNING, "Function '" + this.Name.FullyQualifiedName + "' at line " + this.Name.Line + " has no namespace"); } else { lPath = fqn.Substring(0, lIndex); rPath = fqn.Substring(lIndex + 1); } cfg.setValue(lPath + '/' + "All" + '/' + rPath + '/' + "file", '"' + filePath.Substring(Wrapper.Compiler.ProjectFile.OutputFolder.Length) + ".sqf" + '"'); cfg.setValue(lPath + '/' + "All" + '/' + rPath + '/' + "preInit", this.Name.OriginalValue == "preInit" ? "1" : "0"); cfg.setValue(lPath + '/' + "All" + '/' + rPath + '/' + "postInit", this.Name.OriginalValue == "postInit" ? "1" : "0"); cfg.setValue(lPath + '/' + "All" + '/' + rPath + '/' + "preStart", this.Name.OriginalValue == "preStart" ? "1" : "0"); cfg.setValue(lPath + '/' + "All" + '/' + rPath + '/' + "recompile", "0"); cfg.setValue(lPath + '/' + "All" + '/' + rPath + '/' + "ext", '"' + ".sqf" + '"'); cfg.setValue(lPath + '/' + "All" + '/' + rPath + '/' + "headerType", "-1"); } #region Print Class/Interface global registers if (this.Name.OriginalValue == "preInit") { Base b = this.getFirstOf <Base>(); var classes = b.getAllChildrenOf <oosClass>(true, null, -1, -1, new Type[] { typeof(Namespace) }); classes.Sort(Comparer <oosClass> .Create((obj, obj2) => obj.ID - obj2.ID)); var interfaces = b.getAllChildrenOf <oosInterface>(true, null, -1, -1, new Type[] { typeof(Namespace) }); interfaces.Sort(Comparer <oosInterface> .Create((obj, obj2) => obj.ID - obj2.ID)); //Classes Global Register sw.Write(tab + oosClass.GlobalClassRegisterVariable.SqfVariableName); sw.Write(" = ["); int index2 = 0; foreach (var cl in classes) { if (index2 > 0) { sw.Write(','); } index2++; sw.Write('['); var classIdents = cl.ParentClassesIdents; classIdents.Add(cl.Name); var objects = cl.AllObjects; index = 0; sw.Write('['); foreach (var it in classIdents) { if (index > 0) { sw.Write(", "); } if (it is Ident) { index++; sw.Write('"' + ((Interfaces.iClass)((Ident)it).ReferencedObject).Name.FullyQualifiedName + '"'); } else { throw new Exception("please report to developer, unknown exception happened in function object creation"); } } sw.Write("], ["); index = 0; foreach (var child in objects) { if (child is Interfaces.iFunction && !((Interfaces.iFunction)child).IsVirtual) { continue; } if (child is Variable) { var variable = (Variable)child; if (variable.IsClassVariable) { if (index > 0) { sw.Write(", "); } sw.Write('"' + ((Variable)child).Name.OriginalValue + '"'); index++; } } else if (child is Interfaces.iFunction) { if (index > 0) { sw.Write(", "); } var fnc = (Interfaces.iFunction)child; sw.Write('"' + ((Interfaces.iFunction)child).Name.OriginalValue + '"'); index++; } else { throw new Exception(); } } sw.Write("]"); foreach (var child in objects) { if (child is Interfaces.iFunction && ((Interfaces.iFunction)child).IsVirtual) { sw.Write(", {"); child.writeOut(sw, cfg); sw.WriteLine("}"); } } sw.Write("]"); } sw.WriteLine("];"); //Interfaces Global Register sw.Write(tab + oosInterface.GlobalInterfaceRegisterVariable.SqfVariableName); sw.Write(" = ["); index = 0; foreach (var it in interfaces) { if (index > 0) { sw.Write(", "); } sw.Write("[]"); index++; } sw.WriteLine("];"); foreach (var cl in classes) { List <oosInterface> infcList = new List <oosInterface>(); foreach (var ext in cl.ExtendedClasses) { if (ext.ReferencedObject is oosInterface) { infcList.Add((oosInterface)ext.ReferencedObject); } } foreach (var infc in infcList) { var infcFncList = infc.getAllChildrenOf <VirtualFunction>(); List <string> fncNameList = new List <string>(); foreach (var it in infcFncList) { fncNameList.Add(it.Name.OriginalValue); } sw.Write(tab); sw.Write('('); sw.Write(oosInterface.GlobalInterfaceRegisterVariable.SqfVariableName); sw.Write(" select "); sw.Write(infc.ID); sw.Write(')'); sw.Write(" set ["); sw.Write(cl.ID); sw.Write(", ["); var fncList = cl.getAllChildrenOf <Function>(false, null, -1, -1, null, (obj) => fncNameList.Contains(obj.Name.OriginalValue)); index = 0; foreach (var it in fncList) { if (index > 0) { sw.Write(", "); } sw.Write('{'); it.writeOut(sw, cfg); sw.Write('}'); index++; } sw.WriteLine("]];"); } } } #endregion sw.WriteLine(tab + "scopeName \"" + Wrapper.Compiler.ScopeNames.function + "\";"); var argList = this.ArgListObjects; if (argList.Count > 0 || this.encapsulation != Encapsulation.Static) { sw.Write(tab + "params ["); bool printComma = false; if (this.encapsulation != Encapsulation.Static && !this.IsConstructor) { sw.Write('"' + Wrapper.Compiler.thisVariableName + '"'); printComma = true; } foreach (var it in argList) { if (printComma) { sw.Write(", "); } if (it is Variable) { sw.Write('"' + ((Variable)it).SqfVariableName + '"'); printComma = true; } else { throw new Exception(); } } sw.WriteLine("];"); } #region constructor printing if (this.IsConstructor) { ///////////////////////////////// // OBJECT CONSTRUCTOR PRINTING // ///////////////////////////////// var classObject = this.getFirstOf <oosClass>(); var objects = classObject.AllObjects; if (objects.Count > 0) { sw.Write(tab + "private ["); index = 0; foreach (var it in objects) { if (it is Interfaces.iFunction) { continue; } if (!(it is Variable) || ((Variable)it).Value != null) { if (index > 0) { sw.Write(", "); } sw.Write("\"" + Wrapper.Compiler.thisVariableName + (it is Function ? "fnc" : "var") + ((Interfaces.iName)it).Name.OriginalValue.Replace("::", "_") + (it is Function ? this.SqfSuffix : "") + "\""); index++; } } sw.WriteLine("];"); } foreach (var it in objects) { if (it == this) { continue; } if (it is Interfaces.iFunction) { continue; } var val = ((Variable)it).Value; if (val != null) { sw.Write(tab + Wrapper.Compiler.thisVariableName + (it is Function ? "fnc" : "var") + ((Interfaces.iName)it).Name.OriginalValue.Replace("::", "_") + (it is Function ? this.SqfSuffix + " = {\r\n" : " = ")); val.writeOut(sw, cfg); sw.WriteLine(";"); } } sw.Write(tab + Wrapper.Compiler.thisVariableName + " = ["); //Representing classes (InstanceOf reference) sw.Write(classObject.ID); foreach (var child in objects) { if (child is Variable) { var variable = (Variable)child; if (variable.IsClassVariable) { sw.Write(", "); if (variable.Value == null) { sw.Write("nil"); } else { sw.Write(Wrapper.Compiler.thisVariableName + "var" + ((Variable)child).Name.OriginalValue.Replace("::", "_")); } } } else if (child is Function) { continue; } else { throw new Exception(); } } sw.WriteLine("];"); //ToDo: add baseconstructor calls } #endregion Logger.Instance.log(Logger.LogLevel.DEBUG, "Printing out function '" + this.Name.FullyQualifiedName + this.SqfSuffix + "'s body"); HelperClasses.PrintCodeHelpers.printPrivateArray(this, tab, sw, cfg); HelperClasses.PrintCodeHelpers.printCodeLines(this.CodeInstructions, tab, sw, cfg); if (this.IsConstructor) { sw.Write(tab + Wrapper.Compiler.thisVariableName); } if (!this.IsVirtual) { sw.Flush(); if (!this.IsInline) { sw.Close(); } } }