コード例 #1
0
ファイル: Compiler.cs プロジェクト: HyodaKazuaki/GMC-4
        /// <summary>
        /// ソースコードをコンパイルします。
        /// </summary>
        public void Compile()
        {
            // コンパイル前の初期化処理
            Memory.reset();
            Memory.resetLabel();
            Address.reset();
            OperationCode.resetDataMemoryAddress();
            Error.isError = false;

            // スタートラインを探し、ラベルを処理した上で機械語に変換する
            try
            {
                getStartLine();
                addLabel();
                compileOperation();
            }
            catch (StartLineNotFoundException e)
            {
                Error error = new Error("E11", "スタートラインが見つかりません。");
                return;
            }
            catch (EndLineNotFoundException e)
            {
                Error error = new Error("E12", "エンドラインが見つかりません。");
                return;
            }

            // エラーが発生していればメモリをリセットする
            if (Error.isError) Memory.reset();
        }
コード例 #2
0
ファイル: Compiler.cs プロジェクト: HyodaKazuaki/GMC-4
        /// <summary>
        /// ラベルを追加します。
        /// </summary>
        private void addLabel()
        {
            string operationCode = "";
            bool notFoundEndLine = true;
            for (int i = startLine + 1; i < sourceCode.Length; i++)
            {
                try
                {
                    var value = sourceCode[i];
                    string[] term = value.Split(del, StringSplitOptions.RemoveEmptyEntries);

                    if (value.IndexOf(term[0]) == 0)
                    {
                        // ラベル名重複チェック
                        if (Memory.labelList.Count(x => x.Name() == term[0]) != 0)
                            throw new LabelDuplicationException();
                        // ラベル追加
                        Memory.labelList.Add(new Label(term[0], labelAddress));
                        // オペコードは第二引数部
                        operationCode = term[1];
                    }
                    else if (term[0] == "END" && value.IndexOf(term[0]) != 0)
                    {
                        // 終了
                        notFoundEndLine = false;
                        break;
                    }
                    else
                    {
                        // ラベルなし、オペコードは第一引数部
                        operationCode = term[0];
                    }

                    // ラベルアドレスをオペコード分ずらす
                    labelAddress += OperationCode.addOperationCode(operationCode);
                }
                catch (KeyNotFoundException e)
                {
                    Error error = new Error("E01", "命令 " + operationCode + " は存在しません。", i + 1);
                    return;
                }
                catch (LabelDuplicationException e)
                {
                    Error error = new Error("E22", "命令 " + operationCode + " のラベルはすでに使用されています。", i + 1);
                    return;
                }
            }

            if (notFoundEndLine) throw new EndLineNotFoundException();
        }
コード例 #3
0
ファイル: Compiler.cs プロジェクト: HyodaKazuaki/GMC-4
        /// <summary>
        /// オペレーションコードからコンパイルを行いメモリに書き込みます。
        /// </summary>
        private void compileOperation()
        {
            string operationCode = "";
            string operand = "";

            for(int i = startLine + 1; i < sourceCode.Length; i++)
            {
                // オペコードとオペランドを初期化
                operationCode = "";
                operand = "";

                // 1行分取得
                string line = sourceCode[i];
                string[] term = line.Split(del, StringSplitOptions.RemoveEmptyEntries);
                
                if (line.IndexOf(term[0]) == 0)
                {
                    // ラベル付き(term[0]はラベル)
                    operationCode = term[1];
                    if (term.Length >= 3)
                        // オペランド付き
                        operand = term[2];
                }
                else if (term[0] == "END" && line.IndexOf(term[0]) != 0)
                {
                    // コンパイル終了
                    break;
                }
                else
                {
                    // ラベルなし
                    operationCode = term[0];
                    if (term.Length >= 2)
                        // オペランド付き
                        operand = term[1];
                }

                // 機械語へ変換
                try
                {
                    OperationCode.compileOperationCode(operationCode, operand);
                }
                catch (ArgumentLackException e)
                {
                    Error error = new Error("E02", "命令 " + operationCode + " のオペランドがありません。", i + 1);
                    return;
                }
                catch (ArgumentExcessException e)
                {
                    Error error = new Error("E03", "命令 " + operationCode + " のオペランドが過剰です。", i + 1);
                    return;
                }
                catch (ArgumentOutOfRangeException e)
                {
                    Error error = new Error("E04", "命令 " + operationCode + " のオペランドが不正です。", i + 1);
                    return;
                }
                catch (InvalidOperationException e)
                {
                    Error error = new Error("E21", "命令 " + operationCode + " の指定するラベルは存在しません。", i + 1);
                    return;
                }
                catch (KeyNotFoundException e)
                {
                    Error error = new Error("E01", "命令 " + operationCode + " " + operand + " は存在しません", i + 1);
                    return;
                }
            }

        }