예제 #1
0
 private static void ClearBreakpoints(LispDebugger debugger, string cmd)
 {
     if (debugger != null)
     {
         string rest = cmd.Substring(5).Trim();
         if (rest.Length > 0)
         {
             Tuple <bool, int> val = ConvertToInt(rest);
             if (!val.Item1 || !debugger.ClearBreakpoint(val.Item2))
             {
                 debugger.Output.WriteLine("Warning: no breakpoint cleared");
             }
         }
         else
         {
             debugger.Output.WriteLine("Really delete all breakpoints? (y/n)");
             string answer;
             do
             {
                 answer = debugger.Input.ReadLine();
                 if (answer != null)
                 {
                     answer = answer.ToUpper();
                 }
             } while (!(answer == "Y" || answer == "N" || answer == "YES" || answer == "NO"));
             if (answer == "Y" || answer == "YES")
             {
                 debugger.ClearAllBreakpoints();
             }
         }
     }
 }
예제 #2
0
 private static void ShowSourceCode(LispDebugger debugger, string sourceCode, string moduleName, int?currentLineNo)
 {
     if (debugger != null)
     {
         string[] sourceCodeLines = sourceCode.Split('\n');
         for (var i = 0; i < sourceCodeLines.Length; i++)
         {
             string breakMark = debugger.HasBreakpointAt(i + 1, moduleName) ? "B " : "  ";
             string mark      = currentLineNo != null && currentLineNo.Value == i + 1 ? "-->" : string.Empty;
             debugger.Output.WriteLine("{0,3} {1,2} {2,3} {3}", i + 1, breakMark, mark, sourceCodeLines[i]);
         }
     }
 }
예제 #3
0
        /// <summary>
        /// Adds a breakpoint.
        /// Possible command strings after break:
        /// break 7             --&gt; breakpoint with just one line number in the current module
        /// break modulename:7  --&gt; breakpoint with line number and module name
        /// break 7 condition   --&gt; breakpoint with line number and condition
        /// break modulename:7 condition --&gt; breakpoint with line number, module name and condition
        /// break "modulename with spaces":7 condition --&gt; breakpoint with line number, module name and condition
        /// </summary>
        /// <param name="debugger">The debugger.</param>
        /// <param name="cmd">The command.</param>
        /// <param name="currentModuleName">Name of the current module.</param>
        private static void AddBreakpoint(LispDebugger debugger, string cmd, string currentModuleName)
        {
            bool added = false;

            if (debugger != null)
            {
                var    cmdArgs    = new string[0];
                string moduleName = currentModuleName;
                string rest       = cmd.Substring(cmd.IndexOf(" ", StringComparison.Ordinal)).Trim();
                if (rest.StartsWith("\""))
                {
                    // process: filename:linenumber
                    int iStopPos;
                    moduleName = GetStringLiteral(rest.Substring(1), out iStopPos);
                    rest       = rest.Substring(iStopPos + 2); // adjust for the two "
                    if (rest.StartsWith(":"))
                    {
                        cmdArgs = rest.Substring(1).Split(' ');
                    }
                }
                else
                {
                    // process: linennumber
                    cmdArgs = rest.Split(' ');
                }
                int indexRest = rest.IndexOf(" ", StringComparison.Ordinal);
                rest = indexRest >= 0 ? rest.Substring(indexRest).Trim() : string.Empty;
                if (cmdArgs.Length > 0)
                {
                    string lineNumberString   = cmdArgs[0];
                    int    posModuleSeparator = cmdArgs[0].LastIndexOf(":", StringComparison.Ordinal);
                    if (posModuleSeparator >= 0)
                    {
                        lineNumberString = cmdArgs[0].Substring(posModuleSeparator + 1);
                        moduleName       = cmdArgs[0].Substring(0, posModuleSeparator);
                    }
                    Tuple <bool, int> val = ConvertToInt(lineNumberString);
                    if (val.Item1)
                    {
                        debugger.AddBreakpoint(val.Item2, moduleName, rest.Length > 0 ? rest : string.Empty);
                        added = true;
                    }
                }
            }
            if (!added && debugger != null)
            {
                debugger.Output.WriteLine("Warning: no breakpoint set or modified");
            }
        }
예제 #4
0
        /// <summary>
        /// Processing of the interactive loop of the debugger.
        /// </summary>
        /// <param name="debugger">The debugger.</param>
        /// <param name="initialTopScope">The initial top scope.</param>
        /// <param name="startedFromMain">if set to <c>true</c> [started from main].</param>
        /// <param name="tracing">if set to <c>true</c> tracing is enabled.</param>
        /// <returns>True if program should be restarted.</returns>
        /// <exception cref="LispStopDebuggerException"></exception>
        /// <exception cref="CsLisp.LispStopDebuggerException"></exception>
        public static bool InteractiveLoop(LispDebugger debugger = null, LispScope initialTopScope = null, bool startedFromMain = false, bool tracing = false)
        {
            string interactiveScript = string.Empty;

            startedFromMain = startedFromMain || debugger == null;
            if (debugger == null)
            {
                debugger = new LispDebugger();
            }
            var globalScope = initialTopScope != null ? initialTopScope.GlobalScope : LispEnvironment.CreateDefaultScope();

            // do not switch off tracing if already enabled
            if (!globalScope.Tracing)
            {
                globalScope.Tracing = tracing;
            }
            var topScope     = initialTopScope != null ? initialTopScope : globalScope;
            var currentScope = topScope;
            var bContinueWithNextStatement = false;
            var bRestart = false;

            do
            {
                debugger.Output.Write(debugger != null ? DbgPrompt : Prompt);

                // Warning:
                // QProcess and .NET >3.5 does not work correclty reading from input !!!
                // see: http://www.qtcentre.org/threads/62415-QProcess-not-communicating-with-net-framework-gt-3-5
                // ==> CsLisp is now using .NET 3.5 !
                var cmd = debugger.Input.ReadLine();
                cmd = cmd != null?cmd.Trim() : null;

                if (cmd == null || cmd.Equals("exit") || cmd.Equals("quit") || cmd.Equals("q"))
                {
                    bContinueWithNextStatement = true;
                    bRestart = false;
                    if (!startedFromMain)
                    {
                        throw new LispStopDebuggerException();
                    }
                }
                else if (cmd.Equals("help") || cmd.Equals("h"))
                {
                    ShowInteractiveCmds(debugger.Output);
                }
                else if (cmd.Equals("about"))
                {
                    LispUtils.ShowAbout(debugger.Output);
                }
                else if (cmd.Equals("funcs"))
                {
                    globalScope.DumpFunctions();
                }
                else if (cmd.Equals("macros"))
                {
                    globalScope.DumpMacros();
                }
                else if (cmd.Equals("builtins"))
                {
                    globalScope.DumpBuiltinFunctions();
                }
                else if (cmd.StartsWith("doc"))
                {
                    var items = cmd.Split(' ');
                    if (items.Length > 1)
                    {
                        string      docCmd = "(doc '" + items[1] + ")";
                        LispVariant result = Lisp.Eval(docCmd, currentScope, currentScope.ModuleName);
                        debugger.Output.WriteLine("{0}", result);
                    }
                    else
                    {
                        globalScope.DumpBuiltinFunctionsHelp();
                    }
                }
                else if (cmd.StartsWith("searchdoc"))
                {
                    var items = cmd.Split(' ');
                    if (items.Length > 1)
                    {
                        string      docCmd = "(searchdoc '" + items[1] + ")";
                        LispVariant result = Lisp.Eval(docCmd, currentScope, currentScope.ModuleName);
                        debugger.Output.WriteLine("{0}", result);
                    }
                    else
                    {
                        globalScope.DumpBuiltinFunctionsHelp();
                    }
                }
                else if (cmd.Equals("modules"))
                {
                    globalScope.DumpModules();
                }
                else if (cmd.StartsWith("clear"))
                {
                    ClearBreakpoints(debugger, cmd);
                }
                else if (cmd.Equals("stack") || cmd.StartsWith("k"))
                {
                    topScope.DumpStack(currentScope.GetCallStackSize());
                }
                else if (cmd.Equals("code") || cmd.StartsWith("c"))
                {
                    var script     = string.Empty;
                    var moduleName = currentScope.ModuleName;
                    if (moduleName == null)
                    {
                        script = interactiveScript;
                    }
                    else
                    {
                        script = moduleName.StartsWith(LispEnvironment.EvalStrTag) ? moduleName.Substring(LispEnvironment.EvalStrTag.Length + moduleName.IndexOf(":", LispEnvironment.EvalStrTag.Length)) : LispUtils.ReadFileOrEmptyString(moduleName);
                    }
                    // use the script given on command line if no valid module name was set
                    if (string.IsNullOrEmpty(script))
                    {
                        script = debugger.CommandLineScript;
                    }
                    ShowSourceCode(debugger, script, currentScope.ModuleName, currentScope.CurrentLineNo);
                }
                else if (cmd.StartsWith("list") || cmd.StartsWith("t"))
                {
                    debugger.ShowBreakpoints();
                }
                else if (cmd.StartsWith("break ") || cmd.StartsWith("b "))
                {
                    AddBreakpoint(debugger, cmd, currentScope.ModuleName);
                }
                else if (cmd.Equals("up") || cmd.StartsWith("u"))
                {
                    if (currentScope.Next != null)
                    {
                        currentScope = currentScope.Next;
                    }
                }
                else if (cmd.Equals("down") || cmd.StartsWith("d"))
                {
                    if (currentScope.Previous != null)
                    {
                        currentScope = currentScope.Previous;
                    }
                }
                else if (cmd.Equals("step") || cmd.Equals("s"))
                {
                    debugger.DoStep(currentScope);
                    bContinueWithNextStatement = true;
                }
                else if (cmd.Equals("over") || cmd.Equals("v"))
                {
                    debugger.DoStepOver(currentScope);
                    bContinueWithNextStatement = true;
                }
                else if (cmd.Equals("out") || cmd.Equals("o"))
                {
                    debugger.DoStepOut(currentScope);
                    bContinueWithNextStatement = true;
                }
                else if (cmd.Equals("run") || cmd.Equals("r"))
                {
                    debugger.DoRun();
                    bContinueWithNextStatement = true;
                }
                else if (cmd.Equals("locals") || cmd.StartsWith("l"))
                {
                    currentScope.DumpVars();
                }
                else if (cmd.Equals("globals") || cmd.StartsWith("g"))
                {
                    globalScope.DumpVars();
                }
                else if (cmd.Equals("restart"))
                {
                    bContinueWithNextStatement = true;
                    bRestart = true;
                }
                else if (cmd.Equals("version") || cmd.Equals("ver"))
                {
                    LispUtils.ShowVersion(debugger.Output);
                }
                else
                {
                    try
                    {
                        LispVariant result = Lisp.Eval(cmd, currentScope, currentScope.ModuleName);
                        debugger.Output.WriteLine("result={0}", result);
                        interactiveScript += cmd + '\n';
                    }
                    catch (Exception ex)
                    {
                        debugger.Output.WriteLine("Exception: " + ex.Message);
                    }
                }
            } while (!bContinueWithNextStatement);

            return(bRestart);
        }