diff options
Diffstat (limited to 'src/lang')
-rw-r--r-- | src/lang/analyser.clj | 58 | ||||
-rw-r--r-- | src/lang/compiler.clj | 34 |
2 files changed, 55 insertions, 37 deletions
diff --git a/src/lang/analyser.clj b/src/lang/analyser.clj index a7f6a7dd5..98543e13e 100644 --- a/src/lang/analyser.clj +++ b/src/lang/analyser.clj @@ -10,9 +10,25 @@ (declare analyse-form) ;; [Util] -(defn ^:private with-env [env monad] +(defn ^:private annotated [form type] + {:form form + :type type}) + +(def ^:private module-name + (fn [state] + [::&util/ok [state (:name state)]])) + +(defn ^:private define [name desc] + (fn [state] + [::&util/ok [(-> state + (assoc-in [:defs (:name state) name] desc) + (assoc-in [:env :mappings name] (annotated [::global (:name state) name] (:type desc)))) nil]])) + +(defn ^:private with-local [name type body] (fn [state] - (let [=return (monad (update-in state [:env] merge env))] + (let [=return (body (update-in state [:env] #(-> % + (update-in [:counter] inc) + (assoc-in [:mappings name] (annotated [::local (:counter %)] type)))))] (match =return [::&util/ok [?state ?value]] [::&util/ok [(assoc ?state :env (:env state)) ?value]] @@ -20,24 +36,12 @@ _ =return)))) -(def ^:private module-name - (fn [state] - [::&util/ok [state (:name state)]])) - (defn ^:private resolve [ident] (fn [state] - (if-let [=ident (get-in state [:env ident])] - [::&util/ok [state =ident]] + (if-let [resolved (get-in state [:env :mappings ident])] + [::&util/ok [state resolved]] [::&util/failure (str "Unresolved identifier: " ident)]))) -(defn ^:private define [name desc] - (fn [state] - [::&util/ok [(assoc-in state [:defs (:name state) name] desc) nil]])) - -(defn ^:private annotated [form type] - {:form form - :type type}) - (defmacro ^:private defanalyser [name match return] `(def ~name (fn [{[token# & left#] :forms :as state#}] @@ -72,9 +76,8 @@ (return (annotated [::variant ?tag =value] [::&type/variant ?tag (:type =value)])))) (defanalyser analyse-ident - [::&parser/ident ?name] - (exec [=ident (resolve ?name)] - (return (annotated [::ident ?name] =ident)))) + [::&parser/ident ?ident] + (resolve ?ident)) (defanalyser analyse-ann-class [::&parser/ann-class ?class ?members] @@ -93,10 +96,10 @@ (return (annotated [::dynamic-access =object [?method =args]] ::&type/nothing)))))) (defanalyser analyse-fn-call - [::&parser/fn-call [::&parser/ident ?fn] ?args] - (exec [name module-name + [::&parser/fn-call ?fn ?args] + (exec [=fn (analyse-form* ?fn) =args (map-m analyse-form* ?args)] - (return (annotated [::call [name ?fn] =args] ::&type/nothing)))) + (return (annotated [::call =fn =args] ::&type/nothing)))) (defanalyser analyse-if [::&parser/if ?test ?then ?else] @@ -130,7 +133,7 @@ (exec [=value (analyse-form* ?value) _ (define ?name {:mode ::constant :access ::public - :type =value})] + :type (:type =value)})] (return (annotated [::def ?name =value] ::&type/nothing))) [::&parser/fn-call [::&parser/ident ?name] ?args] @@ -144,8 +147,10 @@ (assoc ?name =function) (into (map vector args =args))) _ (prn 'env env)] - =value (with-env env - (analyse-form* ?value)) + =value (reduce (fn [inner [label type]] + (with-local label type inner)) + (analyse-form* ?value) + (map vector args =args)) :let [_ (prn '=value =value)] =function (within :types (exec [_ (&type/solve =return (:type =value))] (&type/clean =function))) @@ -180,7 +185,8 @@ (defn analyse [module-name tokens] (match ((repeat-m analyse-form) {:name module-name, :forms tokens - :env {} + :env {:counter 0 + :mappings {}} :types &type/+init+}) [::&util/ok [?state ?forms]] (if (empty? (:forms ?state)) diff --git a/src/lang/compiler.clj b/src/lang/compiler.clj index 1976c48e9..a71a66b8b 100644 --- a/src/lang/compiler.clj +++ b/src/lang/compiler.clj @@ -18,7 +18,8 @@ (defmacro ^:private defcompiler [name match body] `(defn ~name [~'*state*] - (let [~'*writer* (:writer ~'*state*)] + (let [~'*writer* (:writer ~'*state*) + ~'*type* (:type (:form ~'*state*))] (match (:form (:form ~'*state*)) ~match (do ~body @@ -71,17 +72,27 @@ :else (assert false (str "[Unknown literal type] " ?literal " : " (class ?literal))))) -(defcompiler ^:private compile-ident - [::&analyser/ident ?name] - (doto *writer* - (.visitVarInsn Opcodes/ALOAD (int 0)))) +(defcompiler ^:private compile-local + [::&analyser/local ?idx] + (do (prn 'LOCAL ?idx) + (doto *writer* + (.visitVarInsn Opcodes/ALOAD (int ?idx))))) -(defcompiler ^:private compile-call - [::&analyser/call [?owner-class ?fn] ?args] - (do (doseq [arg ?args] - (compile-form (assoc *state* :form arg))) +(defcompiler ^:private compile-global + [::&analyser/global ?owner-class ?name] + (do (prn 'GLOBAL ?owner-class ?name *type*) (doto *writer* - (.visitMethodInsn Opcodes/INVOKESTATIC (->class ?owner-class) ?fn "(Ljava/lang/Object;)Ljava/lang/Object;")))) + (.visitFieldInsn Opcodes/GETSTATIC (->class ?owner-class) ?name (->java-sig *type*))))) + +(defcompiler ^:private compile-call + [::&analyser/call ?fn ?args] + (do (prn 'compile-call ?fn) + (doseq [arg ?args] + (compile-form (assoc *state* :form arg))) + (match (:form ?fn) + [::&analyser/global ?owner-class ?fn-name] + (doto *writer* + (.visitMethodInsn Opcodes/INVOKESTATIC (->class ?owner-class) ?fn-name "(Ljava/lang/Object;)Ljava/lang/Object;"))))) (defcompiler ^:private compile-static-access [::&analyser/static-access ?class ?member] @@ -203,7 +214,8 @@ )) (let [+compilers+ [compile-literal - compile-ident + compile-local + compile-global compile-call compile-static-access compile-dynamic-access |