Example #1
0
        public void ImmediateGoTest()
        {
            string[] lines =
            {
                "CHAT c",
                "SAY hello $animal.",
                "SAY ok.",
                "GO c1",
                "CHAT c1",
                "SAY goodbye."
            };
            ChatRuntime rt = new ChatRuntime();

            rt.ParseText(String.Join("\n", lines));

            var s = rt.InvokeImmediate(globals);

            Assert.That(s, Is.EqualTo("hello dog.\nok.\ngoodbye."));

            s = rt.InvokeImmediate(globals, "c");
            Assert.That(s, Is.EqualTo("hello dog.\nok.\ngoodbye."));

            s = rt.InvokeImmediate(globals, "c1");
            Assert.That(s, Is.EqualTo("goodbye."));

            Assert.Throws <UnboundSymbol>(() => rt.InvokeImmediate(null));


            ChatRuntime.SILENT = true;
            rt.strictMode      = false;
            s = rt.InvokeImmediate(null);
            ChatRuntime.SILENT = false;
            Assert.That(s, Is.EqualTo("hello $animal.\nok.\ngoodbye."));
        }
Example #2
0
        public void GroupsWithMissingSymbol()
        {
            ChatRuntime rt;
            string      txt;

            txt = "a | b | c";
            rt  = new ChatRuntime();
            rt.ParseText(txt);

            Resolver.DBUG = false;

            for (int i = 0; i < 5; i++)
            {
                var s = rt.InvokeImmediate(globals);
                //Console.WriteLine("#" + i + ": " + s);
                Assert.That(s.IsOneOf(new[] { "a", "b", "c" }));
            }

            txt = "CHAT c1\nSET a = $object | $object.Call() | honk\nSAY $a";
            rt  = new ChatRuntime();
            rt.ParseText(txt);
            //Resolver.DBUG = true;
            rt.strictMode      = false;
            ChatRuntime.SILENT = true;
            for (int i = 0; i < 5; i++)
            {
                var s = rt.InvokeImmediate(globals);
                //Console.WriteLine("#"+i+": "+s);
                Assert.That(s.IsOneOf(new[] { "$object", "$object.Call()", "honk" }));
            }
            ChatRuntime.SILENT = false;
        }
Example #3
0
        private void CheckEquals(ChatRuntime r1, ChatRuntime r2, bool hasDynamics = false)
        {
            // check they are identical
            Assert.That(r2, Is.EqualTo(r1));

            // double-check the chats themselves
            Chat c1 = r2.Chats().First();
            Chat c2 = r1.Chats().First();

            Assert.That(c1, Is.EqualTo(c2));
            Assert.That(c1.ToTree(), Is.EqualTo(c2.ToTree()));
            Assert.That(c1.text, Is.EqualTo(c2.text));
            for (int i = 0; i < c1.commands.Count; i++)

            {
                var cmd1 = c1.commands[i];
                var cmd2 = c2.commands[i];
                Assert.That(c1.commands[i], Is.EqualTo(c2.commands[i]));
            }

            if (!hasDynamics)
            {
                // no dynamics, so output should be the same
                var res1 = r2.InvokeImmediate(globals);
                var res2 = r1.InvokeImmediate(globals);
                Assert.That(res1, Is.EqualTo(res2));
            }
        }
Example #4
0
        public void RawCharacters()
        {
            ChatRuntime rt;
            string      s;

            Resolver.DBUG = false;


            string[] test = new[]
            {
                "SAY The = op",
                "SAY cute**",
                "SAY <wait>",
                "SAY ^-^",
                "SAY =_="
            };
            for (int i = 0; i < test.Length; i++)
            {
                rt = new ChatRuntime();
                rt.ParseText(test[i], true);
                s = rt.InvokeImmediate(globals);
                Console.WriteLine(i + ": '" + s + "' ?= '" + test[i].Substring(4) + "'");
                Assert.That(s.Equals(test[i].Substring(4)));
            }
        }
Example #5
0
        public void SearchFailWithConstraint()
        {
            var lines = new[] {
                "CHAT Test {type=a,stage=b}",
                "SAY Find",
                "FIND {type=a,x=b}",
                "CHAT next {type=a,stage=b}",
                "SAY Done",
            };

            ChatRuntime rt = new ChatRuntime(AppConfig.TAC);

            rt.ParseText(String.Join("\n", lines));

            var s = rt.InvokeImmediate(null);

            Assert.That(s, Is.EqualTo("Find\nDone"));

            //FuzzySearch.DBUG = true;

            lines = new[] {
                "CHAT Test {type=a,stage=b}",
                "SAY Find",
                "FIND {type=a,staleness<5}",
                "CHAT next {type=a,stage=b,staleness=5}",
                "SAY Done",
            };

            rt = new ChatRuntime(AppConfig.TAC);
            rt.ParseText(String.Join("\n", lines));

            s = rt.InvokeImmediate(null);
            Assert.That(s, Is.EqualTo("Find\nDone"));
        }
Example #6
0
        public void MultiTransformResolution()
        {
            var str = "(well|well).cap() don't you look (anger).emoadj().";
            var rt  = new ChatRuntime(Client.AppConfig.TAC);

            rt.ParseText(str);
            //rt.strictMode = false;
            var s = rt.InvokeImmediate(globals);

            //Console.WriteLine(s);
            Assert.That(s.StartsWith("Well don't you look ", Util.INV), Is.True);
            Assert.That(s.Contains("anger"), Is.False);
            Assert.That(s.Contains("emoadj"), Is.False);

            str = "The (dog|).Cap() ran.";
            rt  = new ChatRuntime(Client.AppConfig.TAC);
            rt.ParseText(str);

            //rt.strictMode = false;
            for (int i = 0; i < 5; i++)
            {
                s = rt.InvokeImmediate(globals);
                //Console.WriteLine(i + ") " + s);
                Assert.That(s.IsOneOf("The Dog ran.", "The ran."));
            }
        }
Example #7
0
        public void BoundedVarSolutions()
        {
            ChatRuntime rt;

            string[] lines;
            string   s;

            lines = new[] {
                "CHAT c1",
                "SET doop = bop",
                "SET deep = beep",
                "SAY [a=$deep][b=$doop]"
            };
            rt = new ChatRuntime();
            rt.ParseText(String.Join("\n", lines), true);

            s = rt.InvokeImmediate(globals);
            Assert.That(s, Is.EqualTo("beepbop"));

            lines = new[] {
                "CHAT c1",
                "SET doop = bop",
                "SET deep = beep",
                "SAY ($deep)-($doop)"
            };
            rt = new ChatRuntime();
            rt.ParseText(String.Join("\n", lines), true);

            s = rt.InvokeImmediate(globals);
            Assert.That(s, Is.EqualTo("beep-bop"));


            lines = new[] {
                "CHAT c1",
                "SET doop = bop",
                "SET deep = beep",
                "SAY ($deep)($doop)"
            };
            rt = new ChatRuntime();
            rt.ParseText(String.Join("\n", lines), true);

            s = rt.InvokeImmediate(globals);
            Assert.That(s, Is.EqualTo("beepbop"));


            lines = new[] {
                "CHAT c1",
                "SET doop = bop",
                "SET deep = beep",
                "SAY [a=$deep]+[b=$doop]"
            };
            rt = new ChatRuntime();
            rt.ParseText(String.Join("\n", lines), true);

            s = rt.InvokeImmediate(globals);
            Assert.That(s, Is.EqualTo("beep+bop"));
        }
Example #8
0
        public void ImmediateAskTest()
        {
            string[] lines =
            {
                "CHAT c",
                "SAY hello $animal.",
                "ASK are you a $animal?",
                "OPT Yes #c2",
                "OPT No #c2",
                "CHAT c1 {a=b}",
                "SAY nope.",
                "CHAT c2 {a=b}",
                "SAY goodbye."
            };
            ChatRuntime rt = new ChatRuntime();

            rt.ParseText(String.Join("\n", lines));

            var s = rt.InvokeImmediate(globals);

            //Assert.That(s, Is.EqualTo("hello dog.\nare you a dog?\ngoodbye."));
            //Assert.That(s, Is.EqualTo("hello dog.\nare you a dog?\ngoodbye."));
            Assert.That(s, Is.EqualTo("hello dog.\nare you a dog?\n[No]\ngoodbye.")
                        .Or.EqualTo("hello dog.\nare you a dog?\n[Yes]\ngoodbye."));


            s = rt.InvokeImmediate(globals, "c");
            Assert.That(s, Is.EqualTo("hello dog.\nare you a dog?\n[No]\ngoodbye.")
                        .Or.EqualTo("hello dog.\nare you a dog?\n[Yes]\ngoodbye."));
            //Assert.That(s, Is.EqualTo("hello dog.\nare you a dog?\ngoodbye."));

            s = rt.InvokeImmediate(globals, "c2");
            Assert.That(s, Is.EqualTo("goodbye."));

            Assert.Throws <UnboundSymbol>(() => rt.InvokeImmediate(null));


            ChatRuntime.SILENT = true;
            rt.strictMode      = false;
            s = rt.InvokeImmediate(null);
            ChatRuntime.SILENT = false;
            Assert.That(s, Is.EqualTo("hello $animal.\nare you a $animal?\n[No]\ngoodbye.")
                        .Or.EqualTo("hello $animal.\nare you a $animal?\n[Yes]\ngoodbye."));
        }
Example #9
0
        public void SubstringIssue()
        {
            ChatRuntime rt = new ChatRuntime();

            //Resolver.DBUG = true;
            rt.ParseText("SET $a = A\nSET $b = $a1\nSET $a1 = B\nSAY $a $b\n", true);
            var s = rt.InvokeImmediate(globals);

            Assert.That(s, Is.EqualTo("A B"));
        }
Example #10
0
        public void SaveAndRestoreChatWithAsk()
        {
            var lines = new[] {
                "CHAT Test {type=a,stage=b}",
                "ASK Is it ok?",
                "OPT yes #next ",
                "OPT no #next",
                "CHAT next {type=a,stage=b}",
                "SAY Done",
            };
            Chat        c1, c2;
            ChatRuntime rtOut, rtIn;

            var text = String.Join("\n", lines);

            rtIn = new ChatRuntime(Client.AppConfig.TAC);
            rtIn.ParseText(text);

            // serialize the runtime to bytes
            var bytes = serializer.ToBytes(rtIn);

            // create a new runtime from the bytes
            rtOut = ChatRuntime.Create(serializer, bytes, AppConfig.TAC);

            // check they are identical
            Assert.That(rtIn, Is.EqualTo(rtOut));

            // double-check the chats themselves
            c1 = rtIn.Chats().First();
            c2 = rtOut.Chats().First();

            //Console.WriteLine(c1.ToTree()+"\n\n"+c2.ToTree());

            Assert.That(c1, Is.EqualTo(c2));
            Assert.That(c1.ToTree(), Is.EqualTo(c2.ToTree()));
            Assert.That(c1.text, Is.EqualTo(c2.text));
            for (int i = 0; i < c1.commands.Count; i++)
            {
                var cmd1 = c1.commands[i];
                Assert.That(cmd1.parent, Is.Not.Null);

                var cmd2 = c2.commands[i];
                Assert.That(cmd2.parent, Is.Not.Null);

                Assert.That(c1.commands[i], Is.EqualTo(c2.commands[i]));
            }

            // no dynamics, so output should be the same
            var res1 = rtIn.InvokeImmediate(globals);
            var res2 = rtOut.InvokeImmediate(globals);

            Assert.That(res1, Is.EqualTo(res2));
        }
Example #11
0
        public void ValidateParensTest()
        {
            string[] lines = new[] {
                "CHAT c1",
                "SET ab = (a | b))",
                "SAY $ab"
            };
            ChatRuntime rt = new ChatRuntime();

            rt.ParseText(String.Join("\n", lines), true);
            Assert.Throws <MismatchedParens>(() => rt.InvokeImmediate(globals));
        }
Example #12
0
        public void MergeFromFile()
        {
            var lines = new[] {
                "CHAT Test {type=a,stage=b}",
                "SAY Find",
                "FIND {type=a,stage=b,other=c}",
                "CHAT next {type=a,stage=b}",
                "SAY Done",
            };

            ChatRuntime rt;

            rt = new ChatRuntime(Client.AppConfig.TAC);
            rt.ParseText(String.Join("\n", lines));

            var s = rt.InvokeImmediate(null);

            Assert.That(s, Is.EqualTo("Find\nDone"));


            // Add more chats via Update, with higher search score
            var lines2 = new[] {
                "CHAT switch {type=a,stage=b,other=c,statelness=}",
                "SAY Added",
            };

            var file = new FileInfo(AppDomain.CurrentDomain.BaseDirectory + Util.EpochMs() + ".ser");

            ChatRuntime rt2 = new ChatRuntime(Client.AppConfig.TAC);

            rt2.ParseText(String.Join("\n", lines2));
            rt2.Save(serializer, file);

            // append the 2nd runtime to the first
            rt.Merge(serializer, file);

            s = rt.InvokeImmediate(null);
            Assert.That(s, Is.EqualTo("Find\nAdded"));
        }
Example #13
0
        public void PartialTransformIssue()
        {
            ChatRuntime rt = new ChatRuntime();

            rt.ParseText("SET $test = (a) (b)\nSAY $test.Cap()", true);
            Assert.That(rt.InvokeImmediate(globals), Is.EqualTo("A b"));

            Resolver.DBUG = false;

            rt = new ChatRuntime();
            rt.ParseText("SET $test = (a | a) (b | b)\nSAY $test.Cap()", true);
            Assert.That(rt.InvokeImmediate(globals), Is.EqualTo("A b"));
        }
Example #14
0
        public void ImmediateTransformFails()
        {
            string[] lines =
            {
                "CHAT c",
                "SAY hello (a | a).noFun(),",
                "SAY ok.",
            };

            ChatRuntime rt = new ChatRuntime();

            rt.ParseText(String.Join("\n", lines));

            Assert.Throws <UnboundFunction>(() => rt.InvokeImmediate(null));

            //ChatRuntime.SILENT = true;
            rt.strictMode = false;
            var s = rt.InvokeImmediate(globals);

            //ChatRuntime.SILENT = false;
            Assert.That(s, Is.EqualTo("hello a.noFun(),\nok."));
        }
Example #15
0
        public void ATransformWithinAChoice()
        {
            var         txt = "CHAT c1\nSET a = a ($animal.Cap() | $prep.Cap())\nSAY $a";
            ChatRuntime rt  = new ChatRuntime();

            rt.ParseText(txt);
            Resolver.DBUG = false;
            rt.strictMode = false;
            for (int i = 0; i < 1; i++)
            {
                var s = rt.InvokeImmediate(globals);
                Assert.That(s.IsOneOf(new[] { "a Dog", "a Then" }));
            }
        }
Example #16
0
        private void CheckEquals(ChatRuntime r1, ChatRuntime r2, bool hasDynamics = false)//, bool ignoreStaleness = false)
        {
            // check they are identical
            Assert.That(r2, Is.EqualTo(r1), "FAILED\n" + r1 + "\n" + r2);

            // if no dynamics, output should be the same
            var res1 = r2.InvokeImmediate(globals, null, true);
            var res2 = r1.InvokeImmediate(globals, null, true);

            if (!hasDynamics)
            {
                Assert.That(res1, Is.EqualTo(res2));
            }
        }
Example #17
0
        public void MergeFromBytes()
        {
            var lines = new[] {
                "CHAT Test {type=a,stage=b}",
                "SAY Find",
                "FIND {type=a,stage=b,other=c}",
                "CHAT next {type=a,stage=b}",
                "SAY Done",
            };

            ChatRuntime rt;

            rt = new ChatRuntime(Client.AppConfig.TAC);
            rt.ParseText(String.Join("\n", lines));

            var s = rt.InvokeImmediate(null);

            Assert.That(s, Is.EqualTo("Find\nDone"));


            // Add more chats via Update, with higher search score
            var lines2 = new[] {
                "CHAT switch {type=a,stage=b,other=c,statelness=}",
                "SAY Added",
            };

            ChatRuntime rt2 = new ChatRuntime(Client.AppConfig.TAC);

            rt2.ParseText(String.Join("\n", lines2));

            // append the 2nd runtime to the first
            rt.Merge(serializer, serializer.ToBytes(rt2));

            s = rt.InvokeImmediate(null);
            Assert.That(s, Is.EqualTo("Find\nAdded"));
        }
Example #18
0
        public void ContinueAskTest()
        {
            string[] lines =
            {
                "CHAT c",
                "ASK Hello?",
                "OPT Yes",
                "OPT No",
                "SAY Ok"
            };
            ChatRuntime rt = new ChatRuntime();

            rt.ParseText(String.Join("\n", lines));
            var s = rt.InvokeImmediate(globals);

            Assert.That(s, Is.EqualTo("Hello?\n[No]\nOk").Or.EqualTo("Hello?\n[Yes]\nOk"));
        }
Example #19
0
        public void ImmediateSimpleLoop()
        {
            var lines = new[] {
                "CHAT Test {type=a,stage=b}",
                "SAY Find",
                "GO #Test"
            };

            ChatRuntime rt = new ChatRuntime(Client.AppConfig.TAC);

            rt.ParseText(String.Join("\n", lines));

            var s = rt.InvokeImmediate(null);

            // Note: exits before GO to avoid infinite loop
            Assert.That(s, Is.EqualTo("Find\nFind\n\nGO #Test looped"));
        }
Example #20
0
        public void ImmediateModeResume()
        {
            string[] lines =
            {
                "CHAT c",
                "SAY hello",
                "GO #c1",
                "SAY ok",
                "CHAT c1",
                "SAY goodbye"
            };
            ChatRuntime rt = new ChatRuntime();

            rt.ParseText(String.Join("\n", lines));

            var s = rt.InvokeImmediate(globals);

            Assert.That(s, Is.EqualTo("hello\ngoodbye\nok"));
        }
Example #21
0
        public void PreloadingTest()
        {
            string[] lines = new[] {
                "CHAT c1",
                "SET ab = hello",
                "SAY $ab $de",

                "CHAT c2 {preload=true}",
                "SET $de = preload",
            };
            ChatRuntime rt = new ChatRuntime();

            rt.ParseText(String.Join("\n", lines), true);
            rt.Preload(globals);

            var s = rt.InvokeImmediate(globals);

            Assert.That(s, Is.EqualTo("hello preload"));
        }
Example #22
0
        public void ImmediateTripleLoop()
        {
            string[] lines =
            {
                "CHAT c1",
                "SAY C1",
                "GO #c2",
                "CHAT c2",
                "SAY C2",
                "GO #c1",
            };

            ChatRuntime rt = new ChatRuntime();

            rt.ParseText(String.Join("\n", lines));

            var s = rt.InvokeImmediate(globals);

            Assert.That(s, Is.EqualTo("C1\nC2\nC1\n\nGO #c2 looped"));
        }
Example #23
0
        public void ImmediateWithDynamicGo()
        {
            string[] lines =
            {
                "CHAT c1",
                "GO #(line1|line2)",
                "CHAT line1",
                "Done",
                "CHAT line2",
                "Done"
            };

            ChatRuntime rt = new ChatRuntime();

            rt.ParseText(String.Join("\n", lines));

            var s = rt.InvokeImmediate(globals);

            //Console.WriteLine(s);
            Assert.That(s, Is.EqualTo("Done"));
        }
Example #24
0
        public void PreloadingBindingFunc()
        {
            string[] lines = new[] {
                "CHAT c1",
                "SAY $d $e",

                "CHAT c2 {preload=true}",
                "SET $d = hello",
                "SET $e = $emotion.Cap()",
            };
            ChatRuntime rt = new ChatRuntime();

            rt.ParseText(String.Join("\n", lines), true);
            rt.Preload(globals);

            globals.Add("emotion", "darkness");

            var s = rt.InvokeImmediate(globals);

            Assert.That(s, Is.EqualTo("hello Darkness"));
        }
        //public static string Validate(IDictionary<string, string> kvs)
        //{
        //    return ParseScript(kvs).ToJSON();
        //}

        public static string Execute(IDictionary <string, string> kvs)
        {
            var parsed = ParseScript(kvs);

            if (parsed.Status != Result.OK)
            {
                return(parsed.ToJSON());
            }

            var result = string.Empty;

            try
            {
                runtime.Preload(globals);
                result = runtime.InvokeImmediate(globals);
                // result = WebUtility.HtmlEncode(result);
                //result = result.Replace("\"", "\\\""); // yuck
                //result = result.Replace("\n", "\\n"); // yuck
            }
            catch (Exception e)
            {
                Console.WriteLine("GOT ERROR");
                result = WebUtility.HtmlEncode(result);
                //result = result.Replace("\"", "\\\""); // yuck
                //result = result.Replace("\n", "\\n"); // yuck
                return(Result.Error(e.Message).ToJSON());
            }

            if (result.IsNullOrEmpty())
            {
                result = " ";
            }

            //result = result.Replace("\"", "\\\""); // yuck
            //result = result.Replace("\n", "\\n"); // yuck


            return(Result.Success(result).ToJSON());
        }
Example #26
0
        public void ImmediateGoFails()
        {
            string[] lines =
            {
                "CHAT c",
                "SAY hello $animal.",
                "SAY ok.",
                "GO c2",
                "CHAT c1",
                "SAY goodbye."
            };

            ChatRuntime rt = new ChatRuntime();

            rt.ParseText(String.Join("\n", lines));

            ChatRuntime.SILENT = true;
            rt.strictMode      = false;
            var s = rt.InvokeImmediate(globals);

            ChatRuntime.SILENT = false;
            Assert.That(s, Is.EqualTo("hello dog.\nok.\n\nGO #c2 failed"));
        }
Example #27
0
        public void ParensCheck()
        {
            string[]    lines;
            ChatRuntime rt;
            string      s;

            Resolver.DBUG = false;

            lines = new[] {
                "CHAT c",
                "SET $aa = Word",
                "SET $bb = (A | B) | (A | B)",
                "SAY $aa $bb"
            };
            rt = new ChatRuntime();
            rt.ParseText(String.Join("\n", lines), true);

            for (int i = 0; i < 10; i++)
            {
                s = rt.InvokeImmediate(globals);
                //Console.WriteLine(i+") "+s);
                Assert.That(s.IsOneOf("Word A", "Word B"));
            }
        }
Example #28
0
        public static string SendEditorResponse(HttpListenerRequest request)
        {
            var html = PageContent.Replace("%%URL%%", SERVER_URL);
            var wmsg = "Enter your script here";

            IDictionary <string, string> kvs = ParsePostData(request);
            var path = kvs.ContainsKey("path") ? kvs["path"] : null;
            var code = kvs.ContainsKey("code") ? kvs["code"] : null;
            var mode = kvs.ContainsKey("mode") ? kvs["mode"] : "validate";

            // fetch code from file
            if (!string.IsNullOrEmpty(path))
            {
                code = new WebClient().DownloadString(path);
            }

            // default info message
            if (string.IsNullOrEmpty(code))
            {
                return(html.Replace("%%CODE%%", wmsg));
            }

            html = html.Replace("%%CODE%%", WebUtility.HtmlEncode(code));
            html = html.Replace("%%CCLASS%%", "shown");

            // only process the selection if there is one
            if (kvs.ContainsKey("selectionStart"))
            {
                code = kvs["selection"];
                html = html.Replace("%%STARTINDEX%%", kvs["selectionStart"]);
                html = html.Replace("%%ENDINDEX%%", kvs["selectionEnd"]);
            }

            try
            {
                string content = string.Empty;
                var    globals = new Dictionary <string, object>();
                runtime            = new ChatRuntime(Client.AppConfig.TAC);
                runtime.strictMode = false;                              // allow unbound symbols/functions
                runtime.ParseText(code, !kvs.ContainsKey("useValidators") ||
                                  !kvs["useValidators"].Equals("true")); // true to disable validators
                runtime.Chats().ForEach(c => { content += c.ToTree() + "\n\n"; });

                var result = string.Empty;
                if (mode == "execute")
                {
                    // first run any chats marked with 'preload=true'
                    runtime.Preload(globals);

                    // run the first chat with all timing disabled
                    result = WebUtility.HtmlEncode(runtime.InvokeImmediate(globals));

                    if (result.IsNullOrEmpty())
                    {
                        result = "[empty-string]";
                    }
                }

                html = html.Replace("%%RESULT%%", WebUtility.HtmlEncode(content));
                html = html.Replace("%%EXECUTE%%", result);
                html = html.Replace("%%RCLASS%%", "success");
            }
            catch (ParseException ex)
            {
                OnError(ref html, ex, ex.lineNumber);
            }
            catch (Exception e)
            {
                OnError(ref html, e, -1);
            }

            return(html);
        }
Example #29
0
        public void DynamicRules()
        {
            string[]    lines;
            ChatRuntime rt;
            string      s;

            Resolver.DBUG = false;

            lines = new[] {
                "CHAT c",
                "SET $emo = anger",
                "SAY ($emo)_rule"
            };
            rt = new ChatRuntime();
            rt.ParseText(String.Join("\n", lines), true);
            s = rt.InvokeImmediate(globals);
            Assert.That(s, Is.EqualTo("anger_rule"));

            lines = new[] {
                "CHAT c",
                "SET $emo = a|a",
                "SAY $$emo"
            };
            rt            = new ChatRuntime();
            rt.strictMode = false;
            rt.ParseText(String.Join("\n", lines), true);
            s = rt.InvokeImmediate(globals);
            Assert.That(s, Is.EqualTo("A"));

            lines = new[] {
                "CHAT c",
                "SET $emo = a|a",
                "SAY $($emo)."
            };
            rt            = new ChatRuntime();
            rt.strictMode = false;
            rt.ParseText(String.Join("\n", lines), true);
            s = rt.InvokeImmediate(globals);
            Assert.That(s, Is.EqualTo("A."));

            lines = new[] {
                "CHAT c",
                "SET $emo = anger",
                "SAY $($emo)_rule"
            };

            rt            = new ChatRuntime();
            rt.strictMode = false;
            rt.ParseText(String.Join("\n", lines), true);
            ChatRuntime.SILENT = true;
            s = rt.InvokeImmediate(globals);
            ChatRuntime.SILENT = false;
            Assert.That(s, Is.EqualTo("$anger_rule"));

            lines = new[] {
                "CHAT c",
                "SET $emo = anger",
                "SET start = $($emo)_rule",
                "SET anger_rule = I am angry",
                "SET happy_rule = I am happy",
                "SAY $start"
            };
            rt = new ChatRuntime();
            rt.ParseText(String.Join("\n", lines), true);
            s = rt.InvokeImmediate(globals);
            Assert.That(s, Is.EqualTo("I am angry"));
        }