Beispiel #1
0
        /// <summary>
        /// コード生成
        /// </summary>
        /// <param name="mergedLSFile">マージ済みのレイヤ構造ファイル</param>
        private void GenerateCode(LayerStructureFile mergedLSFile)
        {
            // ソースコードディレクトリのルートパスを取得
            string includeFilePath = OutputFile;

            if (SourceRootPath != "/")
            {
                string generateCodePath = Path.GetFullPath(OutputFile);
                string sourceRootPath   = Path.GetFullPath(SourceRootPath);
                if (generateCodePath.StartsWith(sourceRootPath))
                {
                    includeFilePath = generateCodePath.Substring(sourceRootPath.Length);
                    includeFilePath = includeFilePath.Replace('\\', '/');
                    includeFilePath = "./" + includeFilePath;
                }
            }
            // コードジェネレート
            var result = _RTCOPCodeGenerator.GenerateCode(mergedLSFile, includeFilePath);

            foreach (string filename in result.CodeDictionary.Keys)
            {
                string filepath = OutputFile + filename;
                string dirpath  = Path.GetDirectoryName(filepath);
                if (!Directory.Exists(dirpath))
                {
                    Directory.CreateDirectory(dirpath);
                }
                using (StreamWriter sw = new StreamWriter(filepath, false, Encoding))
                {
                    sw.Write(result.CodeDictionary[filename]);
                }
            }
        }
Beispiel #2
0
 /// <summary>
 /// コンフィグファイルの反映
 /// </summary>
 /// <param name="lsFile">レイヤ構造ファイル</param>
 /// <returns>反映後のレイヤ構造ファイル</returns>
 private LayerStructureFile ReflectConfigFile(LayerStructureFile lsFile)
 {
     if (_RTCOPConfigFile != null)
     {
         // 実行優先度に基づいたソート
         List <LayerStructure> newLayerStructureList = new List <LayerStructure>();
         foreach (var lconfig in _RTCOPConfigFile.LayerConfigs)
         {
             var ls = lsFile.LayerStructures.Find((obj) => obj.LayerName == lconfig.LayerName);
             if (ls != null)
             {
                 newLayerStructureList.Add(ls);
                 lsFile.LayerStructures.Remove(ls);
             }
         }
         // コンフィグファイルに載ってなかったものを突っ込む
         if (lsFile.LayerStructures.Count > 0)
         {
             newLayerStructureList.AddRange(lsFile.LayerStructures);
             lsFile.LayerStructures.Clear();
         }
         // ソート済みのものを入れなおす
         lsFile.LayerStructures.AddRange(newLayerStructureList);
     }
     return(lsFile);
 }
Beispiel #3
0
        /// <summary>
        /// コンパイル実行。
        /// </summary>
        public void Compile()
        {
            // ソースファイルが無い場合
            if (SourceFiles.Count <= 0)
            {
                // エラー
                throw new Exception("ソースファイルが1つも無いです。");
            }

            // ソースファイルの読み込み
            List <LayerStructureFile> lstrs = new List <LayerStructureFile>();

            foreach (string fileName in SourceFiles)
            {
                if (Path.GetExtension(fileName) == ".lcpp")
                {
                    // .lcppをコンパイル
                    LayerStructureFile result = CompileLCppToObjectFile(fileName);
                    lstrs.Add(result);
                }
                else
                {
                    // レイヤ構造ファイルを読み込み
                    LayerStructureFile result = LayerStructureFile.LoadFile(fileName);
                    lstrs.Add(result);
                }
            }
            // レイヤ構造ファイルのマージ
            LayerStructureFile mergedLSFile = _RTCOPCompiler.MergeObjectFiles(lstrs);
            // 出力ファイルがC++のソースコードか、レイヤ構造ファイルかを確認
            bool outputIsCpp = OutputFile.EndsWith("/") || OutputFile.EndsWith("\\");

            if (!outputIsCpp && (Path.GetExtension(OutputFile) == ""))
            {
                // 拡張子無しの場合フォルダと判断
                outputIsCpp = true;
                OutputFile += "/";
            }
            // ソースコード出力
            if (outputIsCpp)
            {
                GenerateCode(mergedLSFile);
            }
            // レイヤ構造出力
            else
            {
                LayerStructureFile.SaveFile(OutputFile, mergedLSFile);
            }
        }
Beispiel #4
0
        public static void Test()
        {
            string src =
                @"
baselayer
{
	// ベースクラス
	base class Sample
	{
	public:
		Sample();
		virtual ~Sample();
	};

}
";
            var text = RTCOPParser.BaseLayerDefinition.TokenWithSkipComment().Many().Parse(src);
            //var text = PreprocessParser.DirectiveOrLine.TokenWithSkipCommentForPreprocessParser().Many().Parse(src2);
            //var text = RTCOPParser.BaseLayerDefinition.TokenWithSkipComment().Many().Parse(src);
            //var text = TokenParser.Token.TokenWithSkipComment().Many().Parse(src);
            //var text = PreprocessParser.Directive.TokenWithSkipCommentForPreprocessParser().Many().Parse(src);

            //foreach (var t in text) Console.WriteLine(t);
            //Console.WriteLine(text);

            RTCOPSourceFile   f = new RTCOPSourceFile("a.lcpp", src);
            RTCOPPreprocessor p = new RTCOPPreprocessor(new string[0], new List <string>(), Encoding.UTF8);
            var f2 = p.Run(f);

            Console.WriteLine(f2.Text);

            RTCOPCompiler c  = new RTCOPCompiler(null);
            var           of = c.Compile(f2);

            LayerStructureFile.SaveFile(@"C:\Users\Ikuta\Desktop\aaa.lobj", of);
            var of2 = LayerStructureFile.LoadFile(@"C:\Users\Ikuta\Desktop\aaa.lobj");
        }
Beispiel #5
0
        /// <summary>
        /// コード生成
        /// </summary>
        /// <param name="mergedLSFile">マージ済みのレイヤ構造ファイル</param>
        /// <param name="includeFilePath">インクルードファイルパス</param>
        /// <returns>生成後のソースコード</returns>
        public GeneratedCodes GenerateCode(LayerStructureFile mergedLSFile, string includeFilePath)
        {
            GeneratedCodes result = new GeneratedCodes();

            // ライブラリのヘッダファイルを追加
            result.CodeDictionary[@"Layer_Private.h"]        = Properties.Resources.Layer_Private_Header;
            result.CodeDictionary[@"LayerdObject_Private.h"] = Properties.Resources.LayerdObject_Private_Header;
            // ベースクラスを調べる
            LayerStructure baselayerStructure = mergedLSFile.BaseLayerStructure;

            if (baselayerStructure == null)
            {
                // ベースレイヤは定義されていなくても、自動的に生成される
                baselayerStructure = new LayerStructure("baselayer");
                mergedLSFile.BaseLayerStructure = baselayerStructure;
            }
            List <string> baseClassNameList = new List <string>();
            List <List <LayerdMethodDefinition> > baseMethodLists  = new List <List <LayerdMethodDefinition> >();
            List <List <ConstructorDefinition> >  constructorLists = new List <List <ConstructorDefinition> >();
            List <int> superClassIDs = new List <int>();
            Action <IEnumerable <object>, string, int> createBaseClassAndMethodList = null;

            createBaseClassAndMethodList = (items, nspace, classId) =>
            {
                foreach (object item in items)
                {
                    if (item is LayerDefinition)
                    {
                        var    ld      = (LayerDefinition)item;
                        string nspace2 = "baselayer";
                        createBaseClassAndMethodList(ld.Contents, nspace2, -1);
                    }
                    else if (item is NamespaceDefinition)
                    {
                        var    nd      = (NamespaceDefinition)item;
                        string nspace2 = nd.Name;
                        if (nspace != "")
                        {
                            nspace2 = nspace + "::" + nspace2;
                        }
                        createBaseClassAndMethodList(nd.Contents, nspace2, -1);
                    }
                    else if (item is LayerdClassDefinition)
                    {
                        var    lcd       = (LayerdClassDefinition)item;
                        string classname = lcd.Name;
                        if (nspace != "")
                        {
                            classname = nspace + "::" + classname;
                        }
                        if (!baseClassNameList.Contains(classname))
                        {
                            baseClassNameList.Add(classname);
                            baseMethodLists.Add(new List <LayerdMethodDefinition>());
                            constructorLists.Add(new List <ConstructorDefinition>());
                            int id = baseClassNameList.IndexOf(classname);
                            if (lcd.SuperClasses.Count >= 1)
                            {
                                string superclassFullname = lcd.SuperClasses[0].ClassName;
                                if (nspace != "")
                                {
                                    superclassFullname = nspace + "::" + superclassFullname;
                                }
                                string[] superclassNspaces = superclassFullname.Split(new string[] { "::" }, StringSplitOptions.None);
                                string   sname             = superclassFullname;
                                int      superId           = -1;
                                for (int i = 0; i < superclassNspaces.Length; ++i)
                                {
                                    int id2 = baseClassNameList.IndexOf(sname);
                                    if (id2 != -1)
                                    {
                                        baseMethodLists[id].AddRange(baseMethodLists[id2]);
                                        superId = id2;
                                        break;
                                    }
                                    sname = sname.Remove(0, (superclassNspaces[i].Length + 2));
                                }
                                superClassIDs.Add(superId);
                            }
                            else
                            {
                                superClassIDs.Add(-1);
                            }
                            createBaseClassAndMethodList(lcd.Contents, classname, id);
                            // デストラクタ無ければ追加
                            var baseMethodList = baseMethodLists[id];
                            if (!baseMethodList.Exists((obj) => obj == null))
                            {
                                baseMethodList.Add(null);
                            }
                        }
                        else
                        {
                            throw new Exception("クラス" + classname + "の定義が重複しています");
                        }
                    }
                    else if (item is ConstructorDefinition)
                    {
                        var cd   = (ConstructorDefinition)item;
                        var list = constructorLists[classId];
                        list.Add(cd);
                    }
                    else if (item is DestructorDefinition)
                    {
                        var dd = (DestructorDefinition)item;
                        if (dd.IsVirtual || dd.IsPureVirtual)
                        {
                            var methodList = baseMethodLists[classId];
                            if (!methodList.Exists((obj) => obj == null))
                            {
                                methodList.Add(null);
                            }
                        }
                    }
                    else if (item is LayerdMethodDefinition)
                    {
                        if (classId == -1)
                        {
                            continue;
                        }
                        var lmd = (LayerdMethodDefinition)item;
                        if (((lmd.IsBase != null) && lmd.IsBase.Value) || lmd.IsVirtual || lmd.IsPureVirtual)
                        {
                            var methodList = baseMethodLists[classId];
                            if (!methodList.Exists((obj) => (obj != null) && (obj.CompareMethod(lmd))))
                            {
                                methodList.Add(lmd);
                            }
                        }
                    }
                }
            };
            createBaseClassAndMethodList(baselayerStructure.HeaderFileItems, "", -1);
            createBaseClassAndMethodList(baselayerStructure.SourceFileItems, "", -1);
            createBaseClassAndMethodList(mergedLSFile.BaseClassHeaderItems, "", -1);
            // レイヤ、クラス、メソッドの数を調べる
            int numOfLayers  = mergedLSFile.LayerStructures.Count + 1;
            int numOfClasses = baseClassNameList.Count;

            int[] numOfMethods = new int[numOfClasses];
            for (int i = 0; i < numOfClasses; ++i)
            {
                numOfMethods[i] = baseMethodLists[i].Count;
            }

            //=======================================
            // ↓これらは別ファイルで定義
            //=======================================
            // RTCOPAppInitializerの生成
            GenerateRTCOPAppInitializer(result, numOfLayers, numOfClasses, numOfMethods, mergedLSFile.LayerStructures, includeFilePath);
            // API.h、COPNewForApp.h、ActivationForApp.hの生成
            GenerateAPIHeaders(result, mergedLSFile.LayerStructures, baseClassNameList, includeFilePath);
            // ベースレイヤの生成
            GenerateBaseLayer(result, baselayerStructure, mergedLSFile.LayerStructures, baseClassNameList, baseMethodLists, superClassIDs, includeFilePath);
            // 各レイヤの生成
            GenerateLayers(result, baselayerStructure, mergedLSFile.LayerStructures, baseClassNameList, baseMethodLists, constructorLists, superClassIDs, includeFilePath);
            // 環境依存コードの生成
            GenerateDependentCode(result, baselayerStructure, mergedLSFile.LayerStructures, baseClassNameList, baseMethodLists, includeFilePath);

            // 結果を返す
            return(result);
        }
Beispiel #6
0
        /// <summary>
        /// コンパイル
        /// </summary>
        /// <param name="sourceFile">ソースファイル</param>
        /// <returns>レイヤ構造ファイル</returns>
        public LayerStructureFile Compile(RTCOPSourceFile sourceFile)
        {
            // 結果を格納するためのレイヤ構造ファイル
            LayerStructureFile result = new LayerStructureFile();
            // パーサに通す
            string sourceCode = sourceFile.Text;
            var    items      = RTCOPParser.RTCOPSourceFile.Parse(sourceCode);
            // 各レイヤ共通のアイテム
            List <object> commonItemsS = new List <object>();
            List <object> commonItemsH = new List <object>();

            // 要素の解釈
            foreach (object item in items)
            {
                // レイヤ定義の場合
                if (item is LayerDefinition)
                {
                    var layerDefinition = (LayerDefinition)item;
                    if (layerDefinition.Name == "baselayer")
                    {
                        if (result.BaseLayerStructure == null)
                        {
                            result.BaseLayerStructure = new LayerStructure("baselayer");
                        }
                        result.BaseLayerStructure.SourceFileItems.Add(layerDefinition);
                    }
                    else
                    {
                        var layerStructure = result.LayerStructures.Find((obj) => obj.LayerName == layerDefinition.Name);
                        if (layerStructure == null)
                        {
                            layerStructure = new LayerStructure(layerDefinition.Name);
                            result.LayerStructures.Add(layerStructure);
                        }
                        layerStructure.SourceFileItems.Add(layerDefinition);
                    }
                }
                // それ以外
                else
                {
                    commonItemsS.Add(item);
                }
            }
            // 各レイヤ共通のアイテムの反映
            if (result.BaseLayerStructure != null)
            {
                result.BaseLayerStructure.SourceFileItems.InsertRange(0, commonItemsS);
            }
            foreach (var layerStructure in result.LayerStructures)
            {
                layerStructure.SourceFileItems.InsertRange(0, commonItemsS);
            }

            // ヘッダファイルの解釈
            Action <RTCOPSourceFile> InterpretImportedFiles = null;

            InterpretImportedFiles = (src) =>
            {
                foreach (RTCOPSourceFile impFile in src.ImportedFiles)
                {
                    // .lh内でさらに読み込まれているファイルをチェック
                    InterpretImportedFiles(impFile);

                    // パーサに通す
                    string impFileCode  = impFile.Text;
                    var    impFileItems = RTCOPParser.RTCOPSourceFile.Parse(impFileCode);
                    // ファイルの種類によって処理方法を変える
                    if (Path.GetExtension(impFile.FilePath) == ".lh")
                    {
                        List <string> layerNames = new List <string>();
                        // 要素の解釈
                        foreach (object item in impFileItems)
                        {
                            // レイヤ定義の場合
                            if (item is LayerDefinition)
                            {
                                var layerDefinition = (LayerDefinition)item;
                                layerNames.Add(layerDefinition.Name);
                                // ヘッダ要素の追加
                                if (layerDefinition.Name == "baselayer")
                                {
                                    // ベースレイヤ
                                    if (result.BaseLayerStructure == null)
                                    {
                                        result.BaseLayerStructure = new LayerStructure("baselayer");
                                    }
                                    ImportedFileInfomation ifi = result.BaseLayerStructure.ImportedLhInfomation.Find((obj) => obj.FilePath == impFile.FilePath);
                                    if (ifi == null)
                                    {
                                        ifi            = new ImportedFileInfomation(impFile.FilePath);
                                        ifi.StartIndex = result.BaseLayerStructure.HeaderFileItems.Count;
                                        ifi.NumOfItems = 0;
                                        result.BaseLayerStructure.ImportedLhInfomation.Add(ifi);
                                    }
                                    ++ifi.NumOfItems;
                                    result.BaseLayerStructure.HeaderFileItems.Add(layerDefinition);
                                }
                                else
                                {
                                    // ベースレイヤ以外
                                    var layerStructure = result.LayerStructures.Find((obj) => obj.LayerName == layerDefinition.Name);
                                    if (layerStructure == null)
                                    {
                                        layerStructure = new LayerStructure(layerDefinition.Name);
                                        result.LayerStructures.Add(layerStructure);
                                    }
                                    ImportedFileInfomation ifi = layerStructure.ImportedLhInfomation.Find((obj) => obj.FilePath == impFile.FilePath);
                                    if (ifi == null)
                                    {
                                        ifi            = new ImportedFileInfomation(impFile.FilePath);
                                        ifi.StartIndex = layerStructure.HeaderFileItems.Count;
                                        ifi.NumOfItems = 0;
                                        layerStructure.ImportedLhInfomation.Add(ifi);
                                    }
                                    ++ifi.NumOfItems;
                                    layerStructure.HeaderFileItems.Add(layerDefinition);
                                }
                            }
                            // それ以外
                            else
                            {
                                commonItemsH.Add(item);
                            }
                        }
                        // 各レイヤ共通のアイテムの反映
                        if (layerNames.Contains("baselayer"))
                        {
                            ImportedFileInfomation ifi = result.BaseLayerStructure.ImportedLhInfomation.Find((obj) => obj.FilePath == impFile.FilePath);
                            ifi.NumOfItems += commonItemsH.Count;
                            result.BaseLayerStructure.HeaderFileItems.InsertRange(ifi.StartIndex, commonItemsH);
                        }
                        foreach (var layerStructure in result.LayerStructures)
                        {
                            if (layerNames.Contains(layerStructure.LayerName))
                            {
                                ImportedFileInfomation ifi = layerStructure.ImportedLhInfomation.Find((obj) => obj.FilePath == impFile.FilePath);
                                ifi.NumOfItems += commonItemsH.Count;
                                layerStructure.HeaderFileItems.InsertRange(ifi.StartIndex, commonItemsH);
                            }
                        }
                    }
                    // .lhファイル以外
                    else
                    {
                        ImportedFileInfomation ifi = new ImportedFileInfomation(impFile.FilePath);
                        ifi.StartIndex = result.BaseClassHeaderItems.Count;
                        ifi.NumOfItems = impFileItems.Count();
                        result.ImportedBaseClassHeaderInfomation.Add(ifi);
                        result.BaseClassHeaderItems.AddRange(impFileItems);
                    }
                }
            };
            InterpretImportedFiles(sourceFile);
            // 結果を返す
            return(result);
        }
Beispiel #7
0
        /// <summary>
        /// レイヤ構造ファイルのマージ
        /// </summary>
        /// <param name="structureFiles">マージしたいレイヤ構造ファイル</param>
        /// <returns>マージされたレイヤ構造ファイル</returns>
        public LayerStructureFile MergeObjectFiles(IEnumerable <LayerStructureFile> structureFiles)
        {
            // 結果を格納するためのオブジェクトファイル
            LayerStructureFile result = new LayerStructureFile();

            // マージ
            foreach (var structureFile in structureFiles)
            {
                // ベースクラスヘッダを重複を防いでマージ
                foreach (var ifi in structureFile.ImportedBaseClassHeaderInfomation)
                {
                    var ifi2 = result.ImportedBaseClassHeaderInfomation.Find((obj) => obj.FilePath == ifi.FilePath);
                    if (ifi2 == null)
                    {
                        ifi2            = new ImportedFileInfomation(ifi.FilePath);
                        ifi2.StartIndex = result.BaseClassHeaderItems.Count;
                        ifi2.NumOfItems = ifi.NumOfItems;
                        result.ImportedBaseClassHeaderInfomation.Add(ifi2);
                        var range = structureFile.BaseClassHeaderItems.GetRange(ifi.StartIndex, ifi.NumOfItems);
                        result.BaseClassHeaderItems.AddRange(range);
                    }
                }
                // ベースレイヤ
                if (structureFile.BaseLayerStructure != null)
                {
                    if (result.BaseLayerStructure == null)
                    {
                        result.BaseLayerStructure = new LayerStructure("baselayer");
                    }
                    result.BaseLayerStructure.SourceFileItems.AddRange(structureFile.BaseLayerStructure.SourceFileItems);
                    // ヘッダ重複を防いでマージ
                    foreach (var ifi in structureFile.BaseLayerStructure.ImportedLhInfomation)
                    {
                        var ifi2 = result.BaseLayerStructure.ImportedLhInfomation.Find((obj) => obj.FilePath == ifi.FilePath);
                        if (ifi2 == null)
                        {
                            ifi2            = new ImportedFileInfomation(ifi.FilePath);
                            ifi2.StartIndex = result.BaseLayerStructure.HeaderFileItems.Count;
                            ifi2.NumOfItems = ifi.NumOfItems;
                            result.BaseLayerStructure.ImportedLhInfomation.Add(ifi2);
                            var range = structureFile.BaseLayerStructure.HeaderFileItems.GetRange(ifi.StartIndex, ifi.NumOfItems);
                            result.BaseLayerStructure.HeaderFileItems.AddRange(range);
                        }
                    }
                }
                // ベースレイヤ以外
                foreach (var layerStructure in structureFile.LayerStructures)
                {
                    var rld = result.LayerStructures.Find((obj) => obj.LayerName == layerStructure.LayerName);
                    if (rld == null)
                    {
                        rld = new LayerStructure(layerStructure.LayerName);
                        result.LayerStructures.Add(rld);
                    }
                    rld.SourceFileItems.AddRange(layerStructure.SourceFileItems);
                    // ヘッダ重複を防いでマージ
                    foreach (var ifi in layerStructure.ImportedLhInfomation)
                    {
                        var ifi2 = rld.ImportedLhInfomation.Find((obj) => obj.FilePath == ifi.FilePath);
                        if (ifi2 == null)
                        {
                            ifi2            = new ImportedFileInfomation(ifi.FilePath);
                            ifi2.StartIndex = rld.HeaderFileItems.Count;
                            ifi2.NumOfItems = ifi.NumOfItems;
                            rld.ImportedLhInfomation.Add(ifi2);
                            var range = layerStructure.HeaderFileItems.GetRange(ifi.StartIndex, ifi.NumOfItems);
                            rld.HeaderFileItems.AddRange(range);
                        }
                    }
                }
            }
            // レイヤコンフィグの反映
            //result = ReflectConfigFile(result);
            // 結果を返す
            return(result);
        }