aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEduardo Julian2015-01-11 03:06:34 -0400
committerEduardo Julian2015-01-11 03:06:34 -0400
commit9e39423ab1eec0486e752bfdd06e34a64b6cfdd8 (patch)
treea3aa9873be0ac9143c7d8117b1195ca79cd1facf /src
parent409821d93f2781559677cdc2595ed15aa41eb933 (diff)
- Added substraction, multiplication and division for ints.
Diffstat (limited to 'src')
-rw-r--r--src/lux.clj2
-rw-r--r--src/lux/analyser.clj19
-rw-r--r--src/lux/compiler.clj34
-rw-r--r--src/lux/parser.clj18
-rw-r--r--src/lux/type.clj23
5 files changed, 80 insertions, 16 deletions
diff --git a/src/lux.clj b/src/lux.clj
index 3c466e86f..517396182 100644
--- a/src/lux.clj
+++ b/src/lux.clj
@@ -20,10 +20,8 @@
;; TODO: Add extra arities (apply2, apply3, ..., apply16)
;; TODO: When doing partial application, skip "apply" and just call constructor appropiatedly.
;; TODO: Add "new". Allow setting fields.
- ;; TODO: Don't take into account newlines in strings unless they come from \n to allow better coding.
;; TODO: monitor enter & monitor exit.
;; TODO: Reinplement "if" as a macro on top of case.
- ;; TODO: Eliminate the reliance of variants upon tuples for storage.
;; TODO:
(let [source-code (slurp "test2.lux")
diff --git a/src/lux/analyser.clj b/src/lux/analyser.clj
index e21431cef..f45ed4c2d 100644
--- a/src/lux/analyser.clj
+++ b/src/lux/analyser.clj
@@ -764,6 +764,19 @@
[::&parser/quote ?quoted]
(return (annotated [::quote ?quoted] ::&type/nothing)))
+(do-template [<name> <input-tag> <output-tag>]
+ (defanalyser <name>
+ [<input-tag> ?x ?y]
+ (exec [=x (analyse-form* ?x)
+ =y (analyse-form* ?y)]
+ (return (annotated [<output-tag> =x =y] [::&type/object "java.lang.Integer" []]))))
+
+ ^:private analyse-jvm-i+ ::&parser/jvm-i+ ::jvm-i+
+ ^:private analyse-jvm-i- ::&parser/jvm-i- ::jvm-i-
+ ^:private analyse-jvm-i* ::&parser/jvm-i* ::jvm-i*
+ ^:private analyse-jvm-idiv ::&parser/jvm-idiv ::jvm-idiv
+ )
+
(def analyse-form
(try-all-m [analyse-bool
analyse-int
@@ -786,7 +799,11 @@
analyse-defmacro
analyse-import
analyse-use
- analyse-quote]))
+ analyse-quote
+ analyse-jvm-i+
+ analyse-jvm-i-
+ analyse-jvm-i*
+ analyse-jvm-idiv]))
;; [Interface]
(defn analyse [module-name tokens]
diff --git a/src/lux/compiler.clj b/src/lux/compiler.clj
index d603df4df..c95beeb7f 100644
--- a/src/lux/compiler.clj
+++ b/src/lux/compiler.clj
@@ -1,7 +1,8 @@
(ns lux.compiler
(:refer-clojure :exclude [compile])
- (:require [clojure.string :as string]
- [clojure.set :as set]
+ (:require (clojure [string :as string]
+ [set :as set]
+ [template :refer [do-template]])
[clojure.core.match :refer [match]]
(lux [util :as &util :refer [exec return* return fail fail*
repeat-m try-m try-all-m map-m reduce-m
@@ -76,7 +77,7 @@
(match type
::&type/any
(->java-sig [::&type/object "java.lang.Object" []])
-
+
[::&type/object ?name []]
(->type-signature ?name)
@@ -879,6 +880,27 @@
[::&analyser/quote ?quoted]
(compile-form (assoc *state* :form (quoted->token ?quoted))))
+(let [+int-class+ (->class "java.lang.Integer")]
+ (do-template [<name> <tag> <opcode>]
+ (defcompiler <name>
+ [<tag> ?x ?y]
+ (do (compile-form (assoc *state* :form ?x))
+ (doto *writer*
+ (.visitTypeInsn Opcodes/CHECKCAST +int-class+)
+ (.visitMethodInsn Opcodes/INVOKEVIRTUAL +int-class+ "intValue" "()I"))
+ (compile-form (assoc *state* :form ?y))
+ (doto *writer*
+ (.visitTypeInsn Opcodes/CHECKCAST +int-class+)
+ (.visitMethodInsn Opcodes/INVOKEVIRTUAL +int-class+ "intValue" "()I")
+ (.visitInsn <opcode>)
+ (.visitMethodInsn Opcodes/INVOKESTATIC +int-class+ "valueOf" (str "(I)" (->type-signature "java.lang.Integer"))))))
+
+ ^:private compile-jvm-i+ ::&analyser/jvm-i+ Opcodes/IADD
+ ^:private compile-jvm-i- ::&analyser/jvm-i- Opcodes/ISUB
+ ^:private compile-jvm-i* ::&analyser/jvm-i* Opcodes/IMUL
+ ^:private compile-jvm-idiv ::&analyser/jvm-idiv Opcodes/IDIV
+ ))
+
(let [+compilers+ [compile-literal
compile-variant
compile-tuple
@@ -900,7 +922,11 @@
compile-definterface
compile-import
compile-use
- compile-quote]]
+ compile-quote
+ compile-jvm-i+
+ compile-jvm-i-
+ compile-jvm-i*
+ compile-jvm-idiv]]
(defn ^:private compile-form [state]
;; (prn 'compile-form/state state)
(or (some #(% state) +compilers+)
diff --git a/src/lux/parser.clj b/src/lux/parser.clj
index a383e78a5..bfc23fef8 100644
--- a/src/lux/parser.clj
+++ b/src/lux/parser.clj
@@ -180,6 +180,20 @@
?args)]
(return [::fn-call =f =args])))
+;; Java interop
+(do-template [<name> <ident> <tag>]
+ (defparser <name>
+ [::&lexer/list ([[::&lexer/ident <ident>] ?x ?y] :seq)]
+ (exec [=x (apply-m parse-form (list ?x))
+ =y (apply-m parse-form (list ?y))]
+ (return [<tag> =x =y])))
+
+ ^:private parse-jvm-i+ "jvm/i+" ::jvm-i+
+ ^:private parse-jvm-i- "jvm/i-" ::jvm-i-
+ ^:private parse-jvm-i* "jvm/i*" ::jvm-i*
+ ^:private parse-jvm-idiv "jvm/i/" ::jvm-idiv
+ )
+
(def ^:private parse-form
(try-all-m [parse-bool
parse-int
@@ -205,6 +219,10 @@
parse-definterface
parse-import
parse-use
+ parse-jvm-i+
+ parse-jvm-i-
+ parse-jvm-i*
+ parse-jvm-idiv
parse-fn-call]))
;; [Interface]
diff --git a/src/lux/type.clj b/src/lux/type.clj
index b29fcd5d1..854610de7 100644
--- a/src/lux/type.clj
+++ b/src/lux/type.clj
@@ -65,15 +65,20 @@
_ (update ?id =top actual)]
success)]))
- [[::primitive ?prim] _]
- (let [as-obj (case ?prim
- "boolean" [:lang.type/object "java.lang.Boolean" []]
- "int" [:lang.type/object "java.lang.Integer" []]
- "long" [:lang.type/object "java.lang.Long" []]
- "char" [:lang.type/object "java.lang.Character" []]
- "float" [:lang.type/object "java.lang.Float" []]
- "double" [:lang.type/object "java.lang.Double" []])]
- (solve as-obj actual))
+ ;; [[::primitive ?prim] _]
+ ;; (let [as-obj (case ?prim
+ ;; "boolean" [:lang.type/object "java.lang.Boolean" []]
+ ;; "int" [:lang.type/object "java.lang.Integer" []]
+ ;; "long" [:lang.type/object "java.lang.Long" []]
+ ;; "char" [:lang.type/object "java.lang.Character" []]
+ ;; "float" [:lang.type/object "java.lang.Float" []]
+ ;; "double" [:lang.type/object "java.lang.Double" []])]
+ ;; (solve as-obj actual))
+
+ [[::primitive ?e-prim] [::primitive ?a-prim]]
+ (if (= ?e-prim ?a-prim)
+ success
+ (fail (str "Can't solve types: " (pr-str expected actual))))
[[::object ?eclass []] [::object ?aclass []]]
(if (.isAssignableFrom (Class/forName ?eclass) (Class/forName ?aclass))