Пример #1
0
        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);
        }
Пример #2
0
        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();
                }
            }
        }