From 67f56f0795ac0214f9828c42f8face229e204c1d Mon Sep 17 00:00:00 2001 From: David Miller Date: Sat, 21 Feb 2009 06:55:20 +0000 Subject: ClojureCLR: added ClojureCLR project to repo. --- .../Clojure/Clojure.Console/ClojureConsole.cs | 217 +++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 ClojureCLR/Clojure/Clojure.Console/ClojureConsole.cs (limited to 'ClojureCLR/Clojure/Clojure.Console/ClojureConsole.cs') diff --git a/ClojureCLR/Clojure/Clojure.Console/ClojureConsole.cs b/ClojureCLR/Clojure/Clojure.Console/ClojureConsole.cs new file mode 100644 index 00000000..f0f88869 --- /dev/null +++ b/ClojureCLR/Clojure/Clojure.Console/ClojureConsole.cs @@ -0,0 +1,217 @@ +/** + * Copyright (c) David Miller. All rights reserved. + * The use and distribution terms for this software are covered by the + * Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) + * which can be found in the file epl-v10.html at the root of this distribution. + * By using this software in any fashion, you are agreeing to be bound by + * the terms of this license. + * You must not remove this notice, or any other, from this software. + **/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Scripting.Hosting.Shell; +using clojure.lang; +using System.IO; +using Microsoft.Linq.Expressions; +using Microsoft.Scripting.Generation; +using Microsoft.Scripting; +using Microsoft.Scripting.Runtime; +using Microsoft.Scripting.Hosting; +using Microsoft.Scripting.Hosting.Providers; +using System.Diagnostics; +using System.Resources; +using System.Threading; + + +using clojure.runtime; +using clojure.compiler; + + +namespace clojure.console +{ + class ClojureConsole : ConsoleHost, Compiler.EEHooks + { + #region Data + + private bool _isInitialized = false; + + #endregion + + #region Convenience accessors + + private ClojureContext GetLanguageContext() + { + return (ClojureContext)HostingHelpers.GetLanguageContext(Engine); + } + + + private static SourceUnit GetSourceUnit(ScriptSource scriptSource) + { + return HostingHelpers.GetSourceUnit(scriptSource); + } + + #endregion + + #region Basic overrides + + protected override Type Provider + { + get + { + return typeof(ClojureContext); + } + } + + protected override CommandLine CreateCommandLine() + { + return new ClojureCommandLine(); + } + + #endregion + + #region Main routine + + [STAThread] + static int Main(string[] args) + { + ClojureConsole cc = new ClojureConsole(); + + int ret = cc.Run(args); + + Console.ReadLine(); + return ret; + } + + #endregion + + #region Execution override + + protected override void ExecuteInternal() + { + Debug.Assert(Engine != null); + + Var.pushThreadBindings( + RT.map(RT.CURRENT_NS, RT.CURRENT_NS.deref())); + try + { + Snippets.SetSaveAssemblies(true, "."); + MaybeInitialize(); + Snippets.SaveAndVerifyAssemblies(); + base.ExecuteInternal(); + } + catch (Exception e) + { + UnhandledException(Engine, e); + } + + finally + { + Snippets.SaveAndVerifyAssemblies(); + Var.popThreadBindings(); + } + } + + + #endregion + + #region Initialization + + private void MaybeInitialize() + { + if (_isInitialized) + return; + + _isInitialized = true; + + Compiler.SetHooks(this); + + Stopwatch sw = new Stopwatch(); + sw.Start(); + + LoadFromStream(new StringReader(clojure.properties.Resources.core)); + LoadFromStream(new StringReader(clojure.properties.Resources.core_print)); + LoadFromStream(new StringReader(clojure.properties.Resources.test)); + + sw.Stop(); + Console.WriteLine("Loading took {0} milliseconds.", sw.ElapsedMilliseconds); + + + } + + #endregion + + #region EEHooks Members + + public object Eval(object form) + { + ScriptSource scriptSource = Engine.CreateScriptSourceFromString(""); + + Expression expr = Generator.Eval(GetLanguageContext(), form); + LambdaExpression ast = Expression.Lambda(expr); + ast = new GlobalLookupRewriter().RewriteLambda(ast); + ScriptCode code = new ScriptCode(ast, GetSourceUnit(scriptSource)); + return code.Run(); + } + + public object Macroexpand1(object form) + { + return Generator.Macroexpand1(GetLanguageContext(), form); + } + + public object LoadFromStream(TextReader rdr) + { + ScriptSource scriptSource = Engine.CreateScriptSourceFromString(""); + //PushbackReader pbr = new PushbackReader(rdr); + + return LoadFromPushbackReader(scriptSource, rdr, false); + } + + public object LoadFile(string filename) + { + ScriptSource scriptSource = Engine.CreateScriptSourceFromFile(filename); + + return LoadFromPushbackReader(scriptSource, scriptSource.GetReader(), false); + } + + private static object LoadFromPushbackReader(ScriptSource scriptSource, TextReader pbr, bool addPrint) + { + object ret = null; + object eofVal = new object(); + object form; + while ((form = LispReader.read(pbr, false, eofVal, false)) != eofVal) + { + LambdaExpression ast = Generator.Generate(form, addPrint); + ast = new GlobalLookupRewriter().RewriteLambda(ast); + + ScriptCode code = new ScriptCode(ast, GetSourceUnit(scriptSource)); + ret = code.Run(); + } + + return ret; + } + + public Delegate GenerateTypedDelegate(Type delegateType, Symbol optName, IPersistentVector argList, ISeq body) + { + ScriptSource scriptSource = Engine.CreateScriptSourceFromString(""); + + LambdaExpression ast = Generator.GenerateTypedDelegateExpression(GetLanguageContext(), delegateType, optName, argList, body); + return ast.Compile(); + + //ast = new GlobalLookupRewriter().RewriteLambda(ast); -- doesn't work unless no args + //ScriptCode code = new ScriptCode(ast, GetSourceUnit(scriptSource)); + //return code; + } + + #endregion + + protected override ScriptRuntimeSetup CreateRuntimeSetup() + { + ScriptRuntimeSetup setup = base.CreateRuntimeSetup(); + setup.DebugMode = true; + return setup; + } + } +} -- cgit v1.2.3-18-g5258