From f24f2864a1d2eee360cca7dcb5cef8fb2dc7afe0 Mon Sep 17 00:00:00 2001 From: Ramsey Nasser Date: Thu, 19 Apr 2018 18:54:23 -0400 Subject: [PATCH 1/3] Add support for ClojureCLR Adds reader conditionals for ClojureCLR to the Clojure implementation and a C# support class. Uses implementation details of the ClojureCLR compiler as of clojure/clojure-clr@57507a554219bb48406b47492f810dcefc071b0c --- src/riddley/Riddley.cs | 39 ++++++++++++++++++++++++++ src/riddley/compiler.clj | 59 +++++++++++++++++++++++++++------------- src/riddley/walk.clj | 10 +++---- 3 files changed, 84 insertions(+), 24 deletions(-) create mode 100644 src/riddley/Riddley.cs diff --git a/src/riddley/Riddley.cs b/src/riddley/Riddley.cs new file mode 100644 index 0000000..6085d75 --- /dev/null +++ b/src/riddley/Riddley.cs @@ -0,0 +1,39 @@ +using System; +using clojure.lang; +using clojure.lang.CljCompiler.Ast; + +namespace Riddley +{ + public static class Util + { + public static LocalBinding LocalBinding(int num, Symbol sym, Symbol tag, Object form) + { + return new LocalBinding(num, sym, tag, Compiler.Analyze(new ParserContext(RHC.Expression), form), typeof(Object), false, false, false); + } + + public static LocalBinding LocalArgument(int num, Symbol sym, Symbol tag) + { + return new LocalBinding(num, sym, tag, null, typeof(Object), false, true, false); + } + } + + public class ObjMethod : clojure.lang.CljCompiler.Ast.ObjMethod + { + public ObjMethod () : base(new ObjExpr(null), null) + { + + } + + public override bool IsVariadic => throw new NotImplementedException(); + + public override int NumParams => throw new NotImplementedException(); + + public override int RequiredArity => throw new NotImplementedException(); + + public override string MethodName => throw new NotImplementedException(); + + public override Type ReturnType => throw new NotImplementedException(); + + public override Type[] ArgTypes => throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/src/riddley/compiler.clj b/src/riddley/compiler.clj index 325e1a6..eadab50 100644 --- a/src/riddley/compiler.clj +++ b/src/riddley/compiler.clj @@ -3,23 +3,31 @@ [clojure.lang Var Compiler - Compiler$ObjMethod - Compiler$ObjExpr] - [riddley - Util])) + #?@(:clj [Compiler$ObjMethod + Compiler$ObjExpr])] + #?(:clj [riddley Util] + :cljr [Riddley Util ObjMethod]))) (defn- stub-method [] - (proxy [Compiler$ObjMethod] [(Compiler$ObjExpr. nil) nil])) + #?(:clj (proxy [Compiler$ObjMethod] [(Compiler$ObjExpr. nil) nil]) + :cljr (ObjMethod.))) + (defn tag-of "Returns a symbol representing the tagged class of the symbol, or `nil` if none exists." [x] (when-let [tag (-> x meta :tag)] (let [sym (symbol - (if (instance? Class tag) - (.getName ^Class tag) - (name tag)))] - (when-not (= 'java.lang.Object sym) + #?(:clj (if (instance? Class tag) + (.getName ^Class tag) + (name tag)) + :cljr (if (instance? Type tag) + (.FullName ^Type tag) + (name tag)) + ))] + (when-not (= #?(:clj 'java.lang.Object + :cljr 'System.Object) + sym) sym)))) (let [n (atom 0)] @@ -29,25 +37,38 @@ (defn locals "Returns the local binding map, equivalent to the value of `&env`." [] - (when (.isBound Compiler/LOCAL_ENV) - @Compiler/LOCAL_ENV)) + #?(:clj (when (.isBound Compiler/LOCAL_ENV) + @Compiler/LOCAL_ENV) + :cljr (when (.isBound Compiler/LocalEnvVar) + @Compiler/LocalEnvVar))) (defmacro with-base-env [& body] `(binding [*warn-on-reflection* false] (with-bindings (if (locals) {} - {Compiler/LOCAL_ENV {}}) + {#?(:clj Compiler/LOCAL_ENV + :cljr clojure.lang.Compiler/LocalEnvVar) {}}) ~@body))) (defmacro with-lexical-scoping "Defines a lexical scope where new locals may be registered." [& body] - `(with-bindings {Compiler/LOCAL_ENV (locals)} + `(with-bindings {#?(:clj Compiler/LOCAL_ENV + :cljr clojure.lang.Compiler/LocalEnvVar) (locals)} ~@body)) +#?(:cljr (defn get-method-var [] + (let [field + (.GetField Compiler + "MethodVar" + (enum-or System.Reflection.BindingFlags/NonPublic + System.Reflection.BindingFlags/Static))] + (.GetValue field Compiler)))) + (defmacro with-stub-vars [& body] - `(with-bindings {Compiler/CLEAR_SITES nil - Compiler/METHOD (stub-method)} + `(with-bindings #?(:clj {Compiler/CLEAR_SITES nil + Compiler/METHOD (stub-method)} + :cljr {(get-method-var) (stub-method)}) ~@body)) ;; if we don't do this in Java, the checkcasts emitted by Clojure cause an @@ -56,13 +77,13 @@ "Registers a locally bound variable `v`, which is being set to form `x`." [v x] (with-stub-vars - (.set ^Var Compiler/LOCAL_ENV + (.set ^Var #?(:clj Compiler/LOCAL_ENV :cljr Compiler/LocalEnvVar) ;; we want to allow metadata on the symbols to persist, so remove old symbols first (-> (locals) (dissoc v) (assoc v (try - (Util/localBinding (local-id) v (tag-of v) x) + (Util/LocalBinding (local-id) v (tag-of v) x) (catch Exception _ ::analyze-failure))))))) @@ -70,10 +91,10 @@ "Registers a function argument `x`." [x] (with-stub-vars - (.set ^Var Compiler/LOCAL_ENV + (.set ^Var #?(:clj Compiler/LOCAL_ENV :cljr Compiler/LocalEnvVar) (-> (locals) (dissoc x) - (assoc x (Util/localArgument (local-id) x (tag-of x))))))) + (assoc x (Util/LocalArgument (local-id) x (tag-of x))))))) diff --git a/src/riddley/walk.clj b/src/riddley/walk.clj index c93f437..76a3024 100644 --- a/src/riddley/walk.clj +++ b/src/riddley/walk.clj @@ -190,7 +190,7 @@ (cmp/with-base-env (let [x (try (macroexpand x special-form?) - (catch ClassNotFoundException _ + (catch #?(:clj ClassNotFoundException :cljr TypeLoadException) _ x)) walk-exprs' (partial walk-exprs predicate handler special-form?) x' (cond @@ -222,10 +222,10 @@ #(doall (map %1 %2))) walk-exprs' x)) - (instance? java.util.Map$Entry x) - (clojure.lang.MapEntry. - (walk-exprs' (key x)) - (walk-exprs' (val x))) + #?@(:clj [(instance? java.util.Map$Entry x) + (clojure.lang.MapEntry. + (walk-exprs' (key x)) + (walk-exprs' (val x)))]) (or (set? x) From 9666689ff38fe1de3b0712f3ce1a66afe771e313 Mon Sep 17 00:00:00 2001 From: Ramsey Nasser Date: Mon, 23 Apr 2018 12:49:22 -0400 Subject: [PATCH 2/3] Use older C# syntax in Riddley.cs For Unity compatibility --- src/riddley/Riddley.cs | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/src/riddley/Riddley.cs b/src/riddley/Riddley.cs index 6085d75..c3bd245 100644 --- a/src/riddley/Riddley.cs +++ b/src/riddley/Riddley.cs @@ -6,14 +6,14 @@ namespace Riddley { public static class Util { - public static LocalBinding LocalBinding(int num, Symbol sym, Symbol tag, Object form) + public static LocalBinding LocalBinding(int num, Symbol sym, Symbol tag, object form) { - return new LocalBinding(num, sym, tag, Compiler.Analyze(new ParserContext(RHC.Expression), form), typeof(Object), false, false, false); + return new LocalBinding(num, sym, tag, Compiler.Analyze(new ParserContext(RHC.Expression), form), typeof(object), false, false, false); } public static LocalBinding LocalArgument(int num, Symbol sym, Symbol tag) { - return new LocalBinding(num, sym, tag, null, typeof(Object), false, true, false); + return new LocalBinding(num, sym, tag, null, typeof(object), false, true, false); } } @@ -24,16 +24,34 @@ public ObjMethod () : base(new ObjExpr(null), null) } - public override bool IsVariadic => throw new NotImplementedException(); + public override bool IsVariadic + { + get { throw new NotImplementedException(); } + } - public override int NumParams => throw new NotImplementedException(); + public override int NumParams + { + get { throw new NotImplementedException(); } + } - public override int RequiredArity => throw new NotImplementedException(); + public override int RequiredArity + { + get { throw new NotImplementedException(); } + } - public override string MethodName => throw new NotImplementedException(); + public override string MethodName + { + get { throw new NotImplementedException(); } + } - public override Type ReturnType => throw new NotImplementedException(); + public override Type ReturnType + { + get { throw new NotImplementedException(); } + } - public override Type[] ArgTypes => throw new NotImplementedException(); + public override Type[] ArgTypes + { + get { throw new NotImplementedException(); } + } } } \ No newline at end of file From bcd517949f0aa9cbfb87d5704a4cdbf5b7e43961 Mon Sep 17 00:00:00 2001 From: Ramsey Nasser Date: Mon, 23 Apr 2018 13:19:04 -0400 Subject: [PATCH 3/3] Rename clj to cljc for reader conditionals --- src/riddley/{compiler.clj => compiler.cljc} | 0 src/riddley/{walk.clj => walk.cljc} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/riddley/{compiler.clj => compiler.cljc} (100%) rename src/riddley/{walk.clj => walk.cljc} (100%) diff --git a/src/riddley/compiler.clj b/src/riddley/compiler.cljc similarity index 100% rename from src/riddley/compiler.clj rename to src/riddley/compiler.cljc diff --git a/src/riddley/walk.clj b/src/riddley/walk.cljc similarity index 100% rename from src/riddley/walk.clj rename to src/riddley/walk.cljc