aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEduardo Julian2014-12-12 18:46:37 -0400
committerEduardo Julian2014-12-12 18:46:37 -0400
commit5b4e9f024b19f5f246d3ddeb3d7e5f5b53d4ac47 (patch)
treeb07ad1c7cfc4e87f7dd465dadc77a33b9c69f701 /src
parent9e2f13474246faebc0ab3126208b99acd715ec3c (diff)
Analyser can now distinguish between local and global vars & point the compiler to the right place to look for data.
Diffstat (limited to 'src')
-rw-r--r--src/lang.clj4
-rw-r--r--src/lang/analyser.clj58
-rw-r--r--src/lang/compiler.clj34
3 files changed, 57 insertions, 39 deletions
diff --git a/src/lang.clj b/src/lang.clj
index 1ca16a3d9..a5aef4f6e 100644
--- a/src/lang.clj
+++ b/src/lang.clj
@@ -59,11 +59,11 @@
;; TODO: Add type-level computations.
;; TODO: Add interpreter.
;; TODO: Add Java-interop.
- ;; TODO: Add signatures & structures.
+ ;; TODO: Add signatures & structures OR type-classes.
;; TODO: Allow importing Java classes.
;; TODO: Allow using other modules.
;; TODO: Add thunks.
- ;; TODO:
+ ;; TODO: Re-implement compiler in language.
;; TODO:
;; TODO:
;; TODO:
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