示例#1
0
        /// <summary>
        /// Evals the specified lisp code.
        /// An exception may occure if the lisp code is invalid.
        /// </summary>
        /// <param name="lispCode">The lisp code.</param>
        /// <param name="scope">The scope.</param>
        /// <param name="moduleName">The module name and path.</param>
        /// <param name="tracing">if set to <c>true</c> [tracing].</param>
        /// <param name="onlyMacroExpand">if set to <c>true</c> [macro expanding].</param>
        /// <param name="nativeItems">The dictionary with native items.</param>
        /// <returns>The result of the script evaluation</returns>
        public static LispVariant Eval(string lispCode, LispScope scope = null, string moduleName = null, bool tracing = false, bool onlyMacroExpand = false, Dictionary <string, object> nativeItems = null)
        {
            // first create global scope, needed for macro expanding
            var currentScope = scope ?? LispEnvironment.CreateDefaultScope();

            currentScope.ModuleName = moduleName;
            currentScope.Tracing    = tracing;
            RegisterNativeObjects(nativeItems, currentScope);
            int    offset;
            string code = LispUtils.DecorateWithBlock(lispCode, out offset);
            var    ast  = LispParser.Parse(code, offset, currentScope);

#if ENABLE_COMPILE_TIME_MACROS
            var expandedAst = LispInterpreter.ExpandMacros(ast, currentScope);
#else
            var expandedAst = ast;
#endif
            LispVariant result = null;
            if (onlyMacroExpand)
            {
                result = new LispVariant(expandedAst);
            }
            else
            {
                result = LispInterpreter.EvalAst(expandedAst, currentScope);
            }
            return(result);
        }
示例#2
0
        /// <summary>
        /// Compiles the specified lisp code into C# code.
        /// </summary>
        /// <param name="code">The lisp code.</param>
        /// <returns>The C# code packed into a LispVariant</returns>
        public /*static*/ LispVariant CompileToCsCode(string code)
        {
            var globalScope = LispEnvironment.CreateDefaultScope();
            int offset;

            code = LispUtils.DecorateWithBlock(code, out offset);
            var ast = LispParser.Parse(code, offset, globalScope);
            //var expandedAst = ExpandMacros(ast, globalScope);
            var compileResult = Compile(ast, globalScope, "        ", "__return__", "scope");
            var csCode        = "namespace CsLisp\n{\nusing System;\nclass CompiledLisp\n{\n    // functions:\n" +
                                ShiftLines(compileResult.Item2, "    ") +
                                "\n    public static LispVariant LispMain(string[] args)\n    {\n        var scope = new LispScope();\n        LispVariant __return__;\n\n" +
                                ShiftLines(compileResult.Item1, "        ") +
                                "        return __return__;\n    }\n\n    public static void Main(string[] args)\n    {\n        var startTickCount = Environment.TickCount;\n        LispMain(args);\n        Console.WriteLine(string.Format(\"Execution time = {0} s\", (Environment.TickCount - startTickCount)*0.001));\n    }\n}\n}";

            return(new LispVariant(csCode));
        }
示例#3
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);
        }