aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEduardo Julian2016-03-12 23:33:54 -0400
committerEduardo Julian2016-03-12 23:33:54 -0400
commit3baa6d87f9e0be009c5b23f0702da368ceab13a3 (patch)
treeb4ddd470c1fe44d07227ed4fc01f029252cc0eb2
parent65ca7c0dd7a54f6973bf3ca65e13c8272f6b6a1a (diff)
- Added a REPL mode.
Diffstat (limited to '')
-rw-r--r--src/lux.clj10
-rw-r--r--src/lux/analyser.clj12
-rw-r--r--src/lux/analyser/base.clj4
-rw-r--r--src/lux/base.clj2
-rw-r--r--src/lux/compiler.clj25
-rw-r--r--src/lux/compiler/lux.clj5
-rw-r--r--src/lux/optimizer.clj7
-rw-r--r--src/lux/repl.clj77
8 files changed, 121 insertions, 21 deletions
diff --git a/src/lux.clj b/src/lux.clj
index f1f43b7af..40e8a0d24 100644
--- a/src/lux.clj
+++ b/src/lux.clj
@@ -8,19 +8,23 @@
(:require [lux.base :as & :refer [|let |do return fail return* fail* |case]]
[lux.compiler.base :as &compiler-base]
[lux.compiler :as &compiler]
+ [lux.repl :as &repl]
:reload-all)
(:import (java.io File)))
(defn -main [& args]
(|case (&/->list args)
- (&/$Cons "compile" (&/$Cons program-module (&/$Nil)))
+ (&/$Cons program-module (&/$Nil))
(time (&compiler/compile-program &/$Release program-module))
- (&/$Cons "compile" (&/$Cons "release" (&/$Cons program-module (&/$Nil))))
+ (&/$Cons program-module (&/$Cons "release" (&/$Nil)))
(time (&compiler/compile-program &/$Release program-module))
- (&/$Cons "compile" (&/$Cons "debug" (&/$Cons program-module (&/$Nil))))
+ (&/$Cons program-module (&/$Cons "debug" (&/$Nil)))
(time (&compiler/compile-program &/$Debug program-module))
+ (&/$Nil)
+ (&repl/repl)
+
_
(println "Can't understand command.")))
diff --git a/src/lux/analyser.clj b/src/lux/analyser.clj
index 42d92b859..44c173864 100644
--- a/src/lux/analyser.clj
+++ b/src/lux/analyser.clj
@@ -711,3 +711,15 @@
(defn analyse [eval! compile-module compile-token]
(|do [asts &parser/parse]
(&/flat-map% (partial analyse-ast eval! compile-module compile-token &/$VoidT) asts)))
+
+(defn clean-output [?var analysis]
+ (|do [:let [[[?output-type ?output-cursor] ?output-term] analysis]
+ =output-type (&type/clean ?var ?output-type)]
+ (return (&&/|meta =output-type ?output-cursor ?output-term))))
+
+(defn repl-analyse [eval! compile-module compile-token]
+ (|do [asts &parser/parse]
+ (&type/with-var
+ (fn [?var]
+ (|do [outputs (&/flat-map% (partial analyse-ast eval! compile-module compile-token ?var) asts)]
+ (&/map% (partial clean-output ?var) outputs))))))
diff --git a/src/lux/analyser/base.clj b/src/lux/analyser/base.clj
index 130f238da..bb835a524 100644
--- a/src/lux/analyser/base.clj
+++ b/src/lux/analyser/base.clj
@@ -160,6 +160,10 @@
(|let [[[type _] _] analysis]
type))
+(defn expr-term [analysis]
+ (|let [[[type _] term] analysis]
+ term))
+
(defn with-type [new-type analysis]
(|let [[[type cursor] adt] analysis]
(&/T [(&/T [new-type cursor]) adt])))
diff --git a/src/lux/base.clj b/src/lux/base.clj
index 56a59e31b..901011bb1 100644
--- a/src/lux/base.clj
+++ b/src/lux/base.clj
@@ -734,7 +734,7 @@
(T [;; "lux;info"
(default-compiler-info mode)
;; "lux;source"
- $None
+ $Nil
;; "lux;cursor"
(T ["" -1 -1])
;; "lux;modules"
diff --git a/src/lux/compiler.clj b/src/lux/compiler.clj
index ec8786ecc..1b852f789 100644
--- a/src/lux/compiler.clj
+++ b/src/lux/compiler.clj
@@ -36,10 +36,10 @@
ClassWriter
MethodVisitor)))
-;; [Utils/Compilers]
+;; [Resources]
(def ^:private !source->last-line (atom nil))
-(defn ^:private compile-expression [syntax]
+(defn compile-expression [syntax]
(|let [[[?type [_file-name _line _column]] ?form] syntax]
(|do [^MethodVisitor *writer* &/get-writer
:let [debug-label (new Label)
@@ -434,7 +434,7 @@
))
))
-(defn ^:private compile-token [syntax]
+(defn compile-token [syntax]
(|case syntax
(&o/$def ?name ?body ?meta)
(&&lux/compile-def compile-expression ?name ?body ?meta)
@@ -449,7 +449,14 @@
(&&host/compile-jvm-class compile-expression ?name ?super-class ?interfaces ?anns ?inheritance-modifier ?fields ?methods ??env ??ctor-args)
))
-(defn ^:private eval! [expr]
+(defn init! []
+ (reset! !source->last-line {})
+ (.mkdirs (java.io.File. &&/output-dir))
+ (doto (.getDeclaredMethod java.net.URLClassLoader "addURL" (into-array [java.net.URL]))
+ (.setAccessible true)
+ (.invoke (ClassLoader/getSystemClassLoader) (to-array [(-> (new java.io.File "./resources") .toURI .toURL)]))))
+
+(defn eval! [expr]
(&/with-eval
(|do [module &/get-module-name
id &/gen-id
@@ -480,7 +487,7 @@
(.get nil)
return))))
-(defn ^:private compile-module [name]
+(defn compile-module [name]
(let [file-name (str name ".lux")]
(|do [file-content (&&io/read-file file-name)
:let [file-hash (hash file-content)]]
@@ -548,14 +555,6 @@
))
))
-(defn ^:private init! []
- (reset! !source->last-line {})
- (.mkdirs (java.io.File. &&/output-dir))
- (doto (.getDeclaredMethod java.net.URLClassLoader "addURL" (into-array [java.net.URL]))
- (.setAccessible true)
- (.invoke (ClassLoader/getSystemClassLoader) (to-array [(-> (new java.io.File "./resources") .toURI .toURL)]))))
-
-;; [Resources]
(defn compile-program [mode program-module]
(init!)
(let [m-action (&/map% compile-module (&/|list "lux" program-module))]
diff --git a/src/lux/compiler/lux.clj b/src/lux/compiler/lux.clj
index 8f784cc11..3b0ae5b29 100644
--- a/src/lux/compiler/lux.clj
+++ b/src/lux/compiler/lux.clj
@@ -156,7 +156,7 @@
_
(|do [:let [=value-type (&a/expr-type* ?body)]
- ^ClassWriter *writer* &/get-writer
+ ;; ^ClassWriter *writer* &/get-writer
[file-name _ _] &/cursor
:let [datum-sig "Ljava/lang/Object;"
def-name (&host/def-name ?name)
@@ -187,7 +187,8 @@
(.visitMaxs 0 0)
(.visitEnd))]]
(return nil)))
- :let [_ (.visitEnd *writer*)]
+ ;; :let [_ (.visitEnd *writer*)]
+ :let [_ (.visitEnd =class)]
_ (&&/save-class! def-name (.toByteArray =class))
:let [def-class (&&/load-class! class-loader (&host-generics/->class-name current-class))
[def-type is-type?] (|case (&a-meta/meta-get &a-meta/type?-tag ?meta)
diff --git a/src/lux/optimizer.clj b/src/lux/optimizer.clj
index 48db1e2cf..6f4fd27bd 100644
--- a/src/lux/optimizer.clj
+++ b/src/lux/optimizer.clj
@@ -154,7 +154,8 @@
("jvm-lshr" 1)
("jvm-lushr" 1))
-(defn ^:private optimize-token [analysis]
+;; [Exports]
+(defn optimize-token [analysis]
"(-> Analysis Optimized)"
(|case analysis
(&-base/$bool value)
@@ -543,9 +544,11 @@
(&-base/$jvm-lushr value)
(return ($jvm-lushr value))
+
+ _
+ (assert false (prn-str 'optimize-token (&/adt->text analysis)))
))
-;; [Exports]
(defn optimize [eval! compile-module compile-token]
(|do [analyses (&analyser/analyse eval! compile-module compile-token)]
(&/map% optimize-token analyses)))
diff --git a/src/lux/repl.clj b/src/lux/repl.clj
new file mode 100644
index 000000000..138eb695f
--- /dev/null
+++ b/src/lux/repl.clj
@@ -0,0 +1,77 @@
+;; Copyright (c) Eduardo Julian. All rights reserved.
+;; This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
+;; If a copy of the MPL was not distributed with this file,
+;; You can obtain one at http://mozilla.org/MPL/2.0/.
+
+(ns lux.repl
+ (:require clojure.core.match
+ clojure.core.match.array
+ (lux [base :as & :refer [|let |do return* return fail fail* |case]]
+ [type :as &type]
+ [analyser :as &analyser]
+ [optimizer :as &optimizer]
+ [compiler :as &compiler])
+ [lux.analyser.base :as &a-base]
+ [lux.analyser.module :as &module])
+ (:import (java.io InputStreamReader
+ BufferedReader)))
+
+;; [Utils]
+(def ^:private repl-module "REPL")
+
+(defn ^:private init []
+ (do (println "Welcome to the REPL!")
+ (&compiler/init!)
+ (|case ((|do [_ (&compiler/compile-module "lux")]
+ (&module/enter-module repl-module))
+ (&/init-state &/$Debug))
+ (&/$Right ?state _)
+ (&/set$ &/$source &/$Nil ?state)
+
+ (&/$Left ?message)
+ (assert false ?message))
+ ))
+
+(defn ^:private repl-cursor [repl-line]
+ (&/T [repl-module repl-line 0]))
+
+;; [Values]
+(defn repl []
+ (with-open [input (->> System/in (new InputStreamReader) (new BufferedReader))]
+ (loop [state (init)
+ repl-line 0]
+ (let [_ (.print System/out "> ")
+ line (.readLine input)
+ line* (&/|list (&/T [(repl-cursor repl-line) line]))
+ state* (&/update$ &/$source
+ (fn [_source] (&/|++ _source line*))
+ state)]
+ (|case ((|do [analysed-tokens (&analyser/repl-analyse &compiler/eval! &compiler/compile-module &compiler/compile-token)
+ optimized-tokens (->> analysed-tokens
+ (&/|map &a-base/expr-term)
+ (&/map% &optimizer/optimize-token))
+ :let [optimized-tokens* (&/->list (map (fn [analysis optim]
+ (|let [[[_type _cursor] _term] analysis]
+ (&a-base/|meta _type _cursor optim)))
+ (&/->seq analysed-tokens)
+ (&/->seq optimized-tokens)))]
+ eval-values (&/map% &compiler/eval! optimized-tokens*)
+ :let [outputs (map (fn [analysis value]
+ (|let [[[_type _cursor] _term] analysis]
+ [_type value]))
+ (&/->seq analysed-tokens)
+ (&/->seq eval-values))]]
+ (return outputs))
+ state*)
+ (&/$Right state** outputs)
+ (do (doseq [[_type _value] outputs]
+ (.println System/out (str "=> " (&type/show-type _type) "\n" (pr-str _value) "\n")))
+ (recur state** (inc repl-line)))
+
+ (&/$Left ^String ?message)
+ (if (or (= "[Reader Error] EOF" ?message)
+ (.startsWith ?message "[Parser Error] Unbalanced "))
+ (recur state* (inc repl-line))
+ (assert false ?message))
+ ))
+ )))