예제 #1
0
        static void Main(string[] args)
        {
            // --------------------------------------------------
            // Compile
            NakoCompiler compiler = new NakoCompiler();
            compiler.DirectSource =
                "利用中プラグイン列挙して表示。"+
                "";
            cout = "----------";
            cout = "* TOKENS:";
            cout = compiler.Tokens.toTypeString();
            cout = "----------";
            cout = "* NODES:";
            cout = compiler.TopNode.Children.toTypeString();
            cout = "----------";
            cout = "* CODES:";
            cout = compiler.Codes.ToAddressString();

            // --------------------------------------------------
            // Run
            cout = "----------";
            cout = "* RUN";
            NakoInterpreter runner = new NakoInterpreter(compiler.Codes);
            runner.debugMode = true;
            runner.Run();
            Console.WriteLine("LOG=" + runner.PrintLog);
            cout = "----------";

            // Wait
            cout = "ok.";
            Console.ReadLine();
        }
예제 #2
0
        public void TestInterpreter1()
        {
            NakoCompiler ns = new NakoCompiler();
            NakoInterpreter runner = new NakoInterpreter();
            object o;

            // 1
            ns.source = "1+2*3";
            ns.Tokenize();
            ns.ParseOnlyValue();
            runner.Run(ns.WriteIL());
            o = runner.StackTop;
            Assert.IsNotNull(o);
            Assert.IsTrue(7 == NakoValueConveter.ToLong(o));

            // 2
            ns.source = "(1+2)*3";
            ns.Tokenize();
            ns.ParseOnlyValue();
            runner.Run(ns.WriteIL());
            o = runner.StackTop;
            Assert.IsNotNull(o);
            Assert.IsTrue(9 == NakoValueConveter.ToLong(o));

            // 3
            ns.source = "1+4/2";
            ns.Tokenize();
            ns.ParseOnlyValue();
            runner.Run(ns.WriteIL());
            o = runner.StackTop;
            Assert.IsNotNull(o);
            Assert.IsTrue(3 == NakoValueConveter.ToLong(o));
        }
예제 #3
0
        public void TestNest()
        {
            NakoCompiler ns = new NakoCompiler();
            NakoInterpreter runner = new NakoInterpreter();
            NakoILCodeList codes = null;

            // (1)
            codes = ns.WriteIL(
                "A=1\n" +
                "B=2\n" +
                "もし、A=1ならば\n" +
                "  もし、B=1ならば\n" +
                "    PRINT `11`\n" +
                "  違えば\n" +
                "    PRINT `12`\n" +
                "違えば\n" +
                "  もし、B=1ならば\n" +
                "    PRINT `21`\n" +
                "  違えば\n" +
                "    PRINT`22`\n"
            );
            runner.Run(codes);
            Assert.AreEqual(runner.PrintLog, "12");

            // (2)
            codes = ns.WriteIL(
                "A=1\n" +
                "B=1\n" +
                "もし、A=1ならば\n" +
                "  もし、B=1ならば\n" +
                "    PRINT `11`\n" +
                "  違えば\n" +
                "    PRINT `12`\n" +
                "違えば\n" +
                "  もし、B=1ならば\n" +
                "    PRINT `21`\n" +
                "  違えば\n" +
                "    PRINT`22`\n"
            );
            runner.Run(codes);
            Assert.AreEqual(runner.PrintLog, "11");

            // (3)
            codes = ns.WriteIL(
                "A=2\n" +
                "B=2\n" +
                "もし、A=1ならば\n" +
                "  もし、B=1ならば\n" +
                "    PRINT `11`\n" +
                "  違えば\n" +
                "    PRINT `12`\n" +
                "違えば\n" +
                "  もし、B=1ならば\n" +
                "    PRINT `21`\n" +
                "  違えば\n" +
                "    PRINT`22`\n"
            );
            runner.Run(codes);
            Assert.AreEqual(runner.PrintLog, "22");
        }
예제 #4
0
 public TestNakoPluginADO()
 {
     NakoCompilerLoaderInfo info = new NakoCompilerLoaderInfo();
     info.PreloadModules = new NakoPlugin.INakoPlugin[] {
         new NakoBaseSystem(),
         new NakoPluginADO.NakoPluginADO()
     };
     com = new NakoCompiler(info);
 }
예제 #5
0
 // Define Method
 public Object _eval(INakoFuncCallInfo info)
 {
     string s = info.StackPopAsString();
     NakoCompiler compiler = new NakoCompiler();
     compiler.DirectSource = s;
     NakoInterpreter runner = new NakoInterpreter(compiler.Codes);
     runner.Run();
     Console.WriteLine("EVALLOG=" + runner.PrintLog);
     return runner.globalVar.GetValue(0);
 }
 public NakoPluginOfficePowerPointTest()
 {
     NakoCompilerLoaderInfo info = new NakoCompilerLoaderInfo();
     info.PreloadModules = new NakoPlugin.INakoPlugin[] {
         new NakoBaseSystem(),
         new NakoPluginOfficePowerPoint.NakoPluginOfficePowerPoint()
     };
     com = new NakoCompiler(info);
     runner = new NakoInterpreter();
 }
예제 #7
0
 public void Test_array2()
 {
     NakoCompiler nc = new NakoCompiler();
     NakoInterpreter ni = new NakoInterpreter();
     nc.WriteIL(
         "A[`a`]=566\n" +
         "A[`a`]を継続表示\n" +
         "");
     ni.Run(nc.Codes);
     Assert.AreEqual("566", ni.PrintLog);
 }
예제 #8
0
 /// <summary>
 /// ソースコードをトークンに分ける
 /// </summary>
 /// <param name="src"></param>
 /// <param name="filename"></param>
 public void ParseEx(string src, string filename)
 {
     cur           = new NakoCompiler(LoaderInfo);
     cur.DebugMode = this.DebugMode;
     cur.source    = src;
     cur.fullpath  = filename;
     cur.name      = this.GetNamespaceFromPath(filename);
     cur.Tokenize();
     cur.Parse();
     cur.WriteIL();
     namespaceList.Add(cur);
 }
예제 #9
0
        static void Main(string[] args)
        {
            // --------------------------------------------------
            // Compile
            NakoCompiler compiler = new NakoCompiler();
            try
            {
                compiler.DirectSource =
                    "0でパワポ起動。パワポ終了。"+
                    /*
                    "TMP=テンポラリフォルダ。TMP=TMP&「test.xlsx」。\n" +
                    "0でエクセル起動。「A1」に「ABC」をエクセルセル設定。/エクセル終了。\n" +
                    "0でエクセル起動。TMPのエクセル開く。「A1」のエクセルセル取得。それを表示。\n"+
                    //"TMP=テンポラリフォルダ。TMP=TMP&「test.xlsx」。TMPを表示。" +
                     */
                    //"1でエクセル起動。S1=(デスクトップ)&「test.xlsx」。S2=(デスクトップ)&「abc.xlsx」。S1をエクセル開く。S2へエクセル保存。3秒待つ。" +
                    //"1でエクセル起動。「C2」に「いろは」をエクセルセル設定。「C2」のエクセルセル取得。それを表示。3秒待つ。" +
                    //"1でエクセル起動。エクセルブック追加。「わんわん」にエクセルタイトル変更。3秒待つ。" +
                    //"1でエクセル起動。エクセルブック追加。1秒待つ。" +
                    //"1でエクセル起動。エクセルバージョンを表示。2秒待つ。エクセル終了。" +
                    //"A=「」;A[`a`]=30;A[`b`]=31;Aの配列ハッシュキー列挙。それを「,」で配列結合して表示。" +
                    "";
                cout = "----------";
                cout = "* TOKENS:";
                cout = compiler.Tokens.toTypeString();
                cout = "----------";
                cout = "* NODES:";
                cout = compiler.TopNode.Children.toTypeString();
                cout = "----------";
                cout = "* CODES:";
                cout = compiler.Codes.ToAddressString();
            }
            catch(Exception e){
                cout = e.Message;
                Console.ReadLine();
                return;
            }

            // --------------------------------------------------
            // Run
            cout = "----------";
            cout = "* RUN";
            NakoInterpreter runner = new NakoInterpreter(compiler.Codes);
            runner.debugMode = true;
            runner.Run();
            Console.WriteLine("LOG=" + runner.PrintLog);
            cout = "----------";

            // Wait
            cout = "ok.";
            Console.ReadLine();
        }
예제 #10
0
 public TestNakoPluginFile()
 {
     NakoCompilerLoaderInfo info = new NakoCompilerLoaderInfo();
     info.PreloadModules = new NakoPlugin.INakoPlugin[] {
         new NakoBaseSystem(),
         new NakoPluginArray(),
         new NakoPluginString(),
         new NakoPluginFile.NakoPluginFile()
     };
     com = new NakoCompiler(info);
     string assemblyPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
     string assemblyDirectory = System.IO.Path.GetDirectoryName(System.IO.Path.GetDirectoryName(System.IO.Path.GetDirectoryName(assemblyPath)));
     this.sjisFilePath = System.IO.Path.Combine(assemblyDirectory, "SJISTEST.txt");
 }
예제 #11
0
 public void TestForeachLoopAccessToHash()
 {
     NakoCompiler nc = new NakoCompiler();
     NakoInterpreter ni = new NakoInterpreter();
     nc.WriteIL(
         "A[`a`]=566\n" +
         "A[`b`]=666\n" +
         "B[0]=「a」\n" +
         "B[1]=「b」\n" +
         "Bで反復\n" +
         "  A[対象]を継続表示\n" +
         "");
     ni.Run(nc.Codes);
     Assert.AreEqual("566666", ni.PrintLog);
 }
예제 #12
0
        public void TestNormal()
        {
            NakoCompiler ns = new NakoCompiler();
            NakoInterpreter runner = new NakoInterpreter();
            NakoILCodeList codes = null;

            // (1)
            codes = ns.WriteIL(
                "N=3;(N>=0)の間\n"+
                "  PRINT N\n" +
                "  N=N-1\n;"
                );
            runner.Run(codes);
            Assert.AreEqual(runner.PrintLog, "3210");

            // (2)
            codes = ns.WriteIL(
                "N=1;(N<5)の間\n" +
                "  PRINT N\n" +
                "  N=N+1\n;"
                );
            runner.Run(codes);
            Assert.AreEqual(runner.PrintLog, "1234");

            // (3)
            codes = ns.WriteIL(
                "A=1;B=3\n"+
                "(A <= B)の間\n" +
                "  PRINT A; PRINT B;\n" +
                "  A=A+1;B=B-1\n;"
                );
            runner.Run(codes);
            Assert.AreEqual(runner.PrintLog, "1322");

            codes = ns.WriteIL(
                "A=1\n" +
                "(A <= 2)の間\n" +
                "  PRINT `A`&A;\n" +
                "  A=A+1;\n" +
                "  B=1\n" +
                "  (B <= 3)の間\n" +
                "    PRINT `B`&B;\n"+
                "    B=B+1\n" +
                "\n"
                );
            runner.Run(codes);
            Assert.AreEqual(runner.PrintLog, "A1B1B2B3A2B1B2B3");
        }
예제 #13
0
        public void TestInterpreterCalcReal()
        {
            NakoCompiler ns = new NakoCompiler();
            NakoInterpreter runner = new NakoInterpreter();

            // 1
            ns.source = "PRINT 2 * 1.5";
            ns.Tokenize();
            ns.Parse();
            runner.Run(ns.WriteIL());
            Assert.AreEqual("3", runner.PrintLog);

            // 2
            runner.Reset();
            ns.source = "PRINT (1 / 2) * 4";
            ns.Tokenize();
            ns.Parse();
            runner.Run(ns.WriteIL());
            Assert.AreEqual("2", runner.PrintLog);

            // 3
            runner.Reset();
            ns.source = "PRINT 4 % 3";
            ns.Tokenize();
            ns.Parse();
            runner.Run(ns.WriteIL());
            Assert.AreEqual("1", runner.PrintLog);

            // 4
            runner.Reset();
            ns.source = "PRINT 2 ^ 3";
            ns.Tokenize();
            ns.Parse();
            runner.Run(ns.WriteIL());
            Assert.AreEqual("8", runner.PrintLog);

            // 5 : べき乗の優先順位
            runner.Reset();
            ns.source = "PRINT 2 * 3 ^ 3";
            ns.Tokenize();
            ns.Parse();
            runner.Run(ns.WriteIL());
            Assert.AreEqual("54", runner.PrintLog);
        }
예제 #14
0
        public void TestNestl()
        {
            NakoCompiler ns = new NakoCompiler();
            NakoInterpreter runner = new NakoInterpreter();
            NakoILCodeList codes = null;

            codes = ns.WriteIL(
                "A=1\n" +
                "(A <= 2)の間\n" +
                "  PRINT `A`&A;\n" +
                "  A=A+1;\n" +
                "  B=1\n" +
                "  (B <= 3)の間\n" +
                "    PRINT `B`&B;\n"+
                "    B=B+1\n" +
                "\n"
                );
            runner.Run(codes);
            Assert.AreEqual(runner.PrintLog, "A1B1B2B3A2B1B2B3");
        }
예제 #15
0
        public void TestInterpreter2()
        {
            NakoCompiler ns = new NakoCompiler();
            NakoInterpreter runner = new NakoInterpreter();

            // 1
            ns.source = "A=5; PRINT A";
            ns.Tokenize();
            ns.Parse();
            runner.Run(ns.WriteIL());
            Assert.AreEqual("5", runner.PrintLog);

            // 2
            runner.Reset();
            ns.source = "A=5; B=8; C=A+B; PRINT C";
            ns.Tokenize();
            ns.Parse();
            runner.Run(ns.WriteIL());
            Assert.AreEqual("13", runner.PrintLog);
        }
예제 #16
0
        public void TestNakoILWriter1()
        {
            NakoCompiler ns = new NakoCompiler();
            NakoILWriter writer = new NakoILWriter(null);
            bool r;

            // (1)
            ns.source = "1+2*3";
            ns.Tokenize();
            ns.ParseOnlyValue();
            writer.Write(ns.TopNode);
            r = writer.Result.CheckTypes(new NakoILType[] {
                NakoILType.NOP,
                NakoILType.LD_CONST_INT,
                NakoILType.LD_CONST_INT,
                NakoILType.LD_CONST_INT,
                NakoILType.MUL,
                NakoILType.ADD
            });
            Assert.IsTrue(r);
        }
예제 #17
0
        public static void Main(string[] args)
        {
            // --------------------------------------------------
            // Compile
            NakoCompiler compiler = new NakoCompiler();
            compiler.DirectSource =
            @"
            A[`a`]=`aaa`
            A[`b`]=`bbb`
            A[`c`]=`ccc`
            (Aの配列ハッシュキー列挙)で反復
              「***:{対象}」を継続表示

            ";
            //                "デスクトップ。\nそれのファイル列挙。\nそれを「/」で配列結合。\nそれを表示。" +
            //                "";
            cout = "----------";
            cout = "* TOKENS:";
            cout = compiler.Tokens.toTypeString();
            cout = "----------";
            cout = "* NODES:";
            cout = compiler.TopNode.Children.toTypeString();
            cout = "----------";
            cout = "* CODES:";
            cout = compiler.Codes.ToAddressString();

            // --------------------------------------------------
            // Run
            cout = "----------";
            cout = "* RUN";
            NakoInterpreter runner = new NakoInterpreter(compiler.Codes);
            runner.debugMode = true;
            runner.Run();
            Console.WriteLine("LOG=" + runner.PrintLog);
            cout = "----------";
            //
            //            // Wait
            //            cout = "ok.";
            //            Console.ReadLine();
        }
예제 #18
0
 public void Test_localVar_array()
 {
     NakoCompiler nc = new NakoCompiler();
     NakoInterpreter ni = new NakoInterpreter();
     nc.WriteIL(
         "Cとは変数\n"+
         "C¥1¥2¥3=2222\n" +
         "C¥1¥2¥3を継続表示。\n" +
         "");
     ni.Run(nc.Codes);
     Assert.AreEqual("2222", ni.PrintLog);
 }
예제 #19
0
 public void Test_Hash_Access_By_String()
 {
     NakoCompiler nc = new NakoCompiler();
     NakoInterpreter ni = new NakoInterpreter();
     nc.WriteIL(
         "A[`a`]=566\n" +
         "A[`b c d`]=566\n" +
         "c=「b c d」\n" +
         "A[c]を継続表示\n" +
         "");
     ni.Run(nc.Codes);
     Assert.AreEqual("566", ni.PrintLog);
 }
예제 #20
0
        public void TestOneLine()
        {
            NakoCompiler ns = new NakoCompiler();
            NakoInterpreter runner = new NakoInterpreter();
            NakoILCodeList codes = null;

            // (1)
            codes = ns.WriteIL("もし、1=1ならば、PRINT 3");
            runner.Run(codes);
            Assert.AreEqual(runner.PrintLog, "3");

            // (2)
            runner.Reset();
            codes = ns.WriteIL("もし、1=2ならば、PRINT 3、違えば、PRINT 5");
            runner.Run(codes);
            Assert.AreEqual(runner.PrintLog, "5");

            // (3)
            runner.Reset();
            codes = ns.WriteIL("A=1,B=2。もし,A=Bならば、PRINT`NG`。違えば、PRINT`OK`");
            runner.Run(codes);
            Assert.AreEqual(runner.PrintLog, "OK");
        }
예제 #21
0
 public void Test_array_array2()
 {
     NakoCompiler nc = new NakoCompiler();
     NakoInterpreter ni = new NakoInterpreter();
     nc.WriteIL(
         "C¥1¥2¥3=2222\n" +
         "C¥1¥2¥3を継続表示\n" +
         "");
     Console.WriteLine(nc.Codes);
     ni.Run(nc.Codes);
     Assert.AreEqual("2222", ni.PrintLog);
 }
예제 #22
0
 public void Test_array4()
 {
     NakoCompiler nc = new NakoCompiler();
     NakoInterpreter ni = new NakoInterpreter();
     nc.WriteIL(
         "A=「1\r\n" +
         "10\r\n" +
         "100\r\n" +
         "566」\n" +
         "PRINT A[3]\n" +
         "");
     ni.Run(nc.Codes);
     Assert.AreEqual("566", ni.PrintLog);
 }
예제 #23
0
 public void TestInsertArray()
 {
     NakoCompiler nc = new NakoCompiler();
     NakoInterpreter ni = new NakoInterpreter();
     nc.WriteIL(
         "I[0]=000\n" +
         "I[1]=333\n" +
         "I[2]=444\n" +
         "J=「111{~}222」\n" +
         "Iの1にJを配列一括挿入\n" +
         "Iの配列要素数を継続表示\n" +
         "「:」継続表示\n" +
         "I[3]を継続表示\n" +
         "");
     ni.Run(nc.Codes);
     Assert.AreEqual("5:333",ni.PrintLog);
 }
예제 #24
0
        void OneLinerMode(string code)
        {
            var compiler = new NakoCompiler(GetLoaderInfo())
            {
                DebugMode = DebugMode,
            };

            var runner = new NakoInterpreter(compiler.WriteIL(code));
            SetCommandLine(runner);

            if (DescriptMode)
            {
                Console.WriteLine("----------");
                Console.WriteLine("* TOKENS:");
                Console.WriteLine(compiler.Tokens.toTypeString());
                Console.WriteLine("----------");
                Console.WriteLine("* NODES:");
                Console.WriteLine(compiler.TopNode.Children.toTypeString());
                Console.WriteLine("----------");
                Console.WriteLine("* CODES:");
                Console.WriteLine(compiler.Codes.ToAddressString());
                Console.WriteLine("----------");
                Console.WriteLine("* RUN");
                runner.debugMode = DebugMode;
                runner.Run();
                Console.WriteLine("LOG=" + runner.PrintLog);
                Console.WriteLine("----------");
                Console.WriteLine("ok.");
            }
            else
            {
                runner.debugMode = DebugMode;
                runner.Run();
                PrintLog = runner.PrintLog;
                // Console.WriteLine(runner.PrintLog); // Consoleでは stdout へ直接出力しているはずなので不要のはず
            }
        }
예제 #25
0
        public void TestNormal()
        {
            NakoCompiler ns = new NakoCompiler();
            NakoInterpreter runner = new NakoInterpreter();
            NakoILCodeList codes = null;

            // (1)
            codes = ns.WriteIL(
                "A=1\n" +
                "B=2\n" +
                "もし、A=Bならば\n" +
                "  PRINT`真`\n" +
                "違えば\n" +
                "  PRINT`偽`\n");
            runner.Run(codes);
            Assert.AreEqual(runner.PrintLog, "偽");

            // (2)
            codes = ns.WriteIL(
                "A=2\n" +
                "もし、A=1ならば\n" +
                "  PRINT 1\n" +
                "違えば、もし、A=2ならば\n" +
                "  PRINT 2\n" +
                "違えば\n" +
                "  PRINT `*`\n"
                );
            runner.Run(codes);
            Assert.AreEqual(runner.PrintLog, "2");

            // (3)
            codes = ns.WriteIL(
                "A=1\n" +
                "もし、A=1ならば\n" +
                "  PRINT 1\n" +
                "違えば、もし、A=2ならば\n" +
                "  PRINT 2\n" +
                "違えば\n" +
                "  PRINT `*`\n"
                );
            runner.Run(codes);
            Assert.AreEqual(runner.PrintLog, "1");

            // (4)
            codes = ns.WriteIL(
                "A=3\n" +
                "もし、A=1ならば\n" +
                "  PRINT 1\n" +
                "違えば、もし、A=2ならば\n" +
                "  PRINT 2\n" +
                "違えば、もし、A=3ならば\n" +
                "  PRINT 3\n" +
                "違えば、もし、A=4ならば\n" +
                "  PRINT 4\n" +
                "違えば\n" +
                "  PRINT `*`\n"
                );
            runner.Run(codes);
            Assert.AreEqual(runner.PrintLog, "3");

            // (5)
            codes = ns.WriteIL(
                "A=8\n" +
                "もし、A=1ならば\n" +
                "  PRINT 1\n" +
                "違えば、もし、A=2ならば\n" +
                "  PRINT 2\n" +
                "違えば、もし、A=3ならば\n" +
                "  PRINT 3\n" +
                "違えば、もし、A=4ならば\n" +
                "  PRINT 4\n" +
                "違えば\n" +
                "  PRINT `*`\n"
                );
            runner.Run(codes);
            Assert.AreEqual(runner.PrintLog, "*");
        }
예제 #26
0
 public void Test_occurrence()
 {
     NakoCompiler nc = new NakoCompiler();
     NakoInterpreter ni = new NakoInterpreter();
     ni.Run(nc.WriteIL(
         "`abcdabcabdcab`で`ab`の出現回数\n" +
         "それを継続表示\n" +
         ""));
     Assert.AreEqual("4", ni.PrintLog);
     ni.Run(nc.WriteIL(
         "`ほげふがほbcaふがげふがほふげがふがほ`で`ふが`の出現回数\n" +
         "それを継続表示\n" +
         ""));
     Assert.AreEqual("4", ni.PrintLog);
 }
예제 #27
0
 public void Test_array_array8()
 {
     NakoCompiler nc = new NakoCompiler();
     NakoInterpreter ni = new NakoInterpreter();
     nc.WriteIL(
         "A[3][`a`]=222\n" +
         "B[`b`]=A\n" +
         "PRINT B[`b`][3][`a`]\n" +
         "");
     ni.Run(nc.Codes);
     Assert.AreEqual("222",ni.PrintLog);
 }
예제 #28
0
 public void Test_array_yen_access()
 {
     NakoCompiler nc = new NakoCompiler();
     NakoInterpreter ni = new NakoInterpreter();
     nc.WriteIL(
         "A¥3=999\n" +
         "A¥3を継続表示\n" +
         "");
     ni.Run(nc.Codes);
     Assert.AreEqual("999",ni.PrintLog);
 }
예제 #29
0
 public TestArray()
 {
     com = new NakoCompiler();
     runner = new NakoInterpreter();
 }
예제 #30
0
 /// <summary>
 /// ソースコードをトークンに分ける
 /// </summary>
 /// <param name="src"></param>
 /// <param name="filename"></param>
 public void ParseEx(string src, string filename)
 {
     cur = new NakoCompiler(LoaderInfo);
     cur.DebugMode = this.DebugMode;
     cur.source = src;
     cur.fullpath = filename;
     cur.name = this.GetNamespaceFromPath(filename);
     cur.Tokenize();
     cur.Parse();
     cur.WriteIL();
     namespaceList.Add(cur);
 }
예제 #31
0
 public void TestUserFunc_sub2()
 {
     NakoCompiler nc = new NakoCompiler();
     NakoInterpreter ni = new NakoInterpreter();
     nc.WriteIL(
         "3を10から引く。\n" +
         "PRINT それ\n" +
         "\n");
     ni.Run(nc.Codes);
     Assert.AreEqual("7", ni.PrintLog);
 }