aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lang.clj3
-rw-r--r--src/lang/compiler.clj20
-rw-r--r--src/lang/parser.clj9
-rw-r--r--test2.lang2
4 files changed, 32 insertions, 2 deletions
diff --git a/src/lang.clj b/src/lang.clj
index 6502c3a29..22492eac6 100644
--- a/src/lang.clj
+++ b/src/lang.clj
@@ -37,5 +37,8 @@
;; TODO: Add signatures & structures.
;; TODO: Add type-system.
;; TODO: Allow defining constants.
+ ;; TODO: Allow importing Java classes.
+ ;; TODO: Allow using other modules.
+ ;; TODO:
;; TODO:
)
diff --git a/src/lang/compiler.clj b/src/lang/compiler.clj
index 3e63fc801..26236da93 100644
--- a/src/lang/compiler.clj
+++ b/src/lang/compiler.clj
@@ -128,7 +128,22 @@
(defcompiler ^:private compile-module
[::&parser/module]
(.visit *writer* Opcodes/V1_5 (+ Opcodes/ACC_PUBLIC Opcodes/ACC_SUPER)
- *name* nil "java/lang/Object" nil))
+ (->class *name*) nil "java/lang/Object" nil))
+
+(defcompiler ^:private compile-defclass
+ [::&parser/defclass ?name ?fields]
+ (do (prn 'compile-defclass ?name ?fields)
+ (let [=class (doto (new ClassWriter ClassWriter/COMPUTE_MAXS)
+ (.visit Opcodes/V1_5 (+ Opcodes/ACC_PUBLIC Opcodes/ACC_SUPER)
+ (->class (str *name* "." ?name)) nil "java/lang/Object" nil))]
+ (doseq [[class field] ?fields]
+ (doto (.visitField =class Opcodes/ACC_PUBLIC field (->type-signature class) nil nil)
+ (.visitEnd)))
+ (.visitEnd =class)
+ (let [parent-dir (->class *name*)]
+ (.mkdirs (java.io.File. parent-dir))
+ (with-open [stream (java.io.BufferedOutputStream. (java.io.FileOutputStream. (str parent-dir "/" ?name ".class")))]
+ (.write stream (.toByteArray =class)))))))
(let [+compilers+ [compile-boolean
compile-string
@@ -139,7 +154,8 @@
compile-ann-class
compile-if
compile-def
- compile-module]]
+ compile-module
+ compile-defclass]]
(defn ^:private compile-form [state]
(prn 'compile-form/state state)
(some #(% state) +compilers+)))
diff --git a/src/lang/parser.clj b/src/lang/parser.clj
index 5adf36030..beb14302d 100644
--- a/src/lang/parser.clj
+++ b/src/lang/parser.clj
@@ -107,6 +107,14 @@
[::&lexer/list ([[::&lexer/ident "module"]] :seq)]
(return [::module]))
+(defparser ^:private parse-defclass
+ [::&lexer/list ([[::&lexer/ident "defclass"] [::&lexer/ident ?name] [::&lexer/tuple ?fields]] :seq)]
+ (let [fields (for [field ?fields]
+ (match field
+ [::&lexer/tuple ([[::&lexer/ident ?class] [::&lexer/ident ?field]] :seq)]
+ [?class ?field]))]
+ (return [::defclass ?name fields])))
+
(defparser ^:private parse-tagged
[::&lexer/list ([[::&lexer/tag ?tag] ?data] :seq)]
(exec [=data (apply-m parse-form (list ?data))]
@@ -190,6 +198,7 @@
parse-dynamic-access
parse-ann-class
parse-module
+ parse-defclass
parse-fn-call]))
;; [Interface]
diff --git a/test2.lang b/test2.lang
index 7c1f35f38..f248c3d0d 100644
--- a/test2.lang
+++ b/test2.lang
@@ -10,6 +10,8 @@
fields
(: out java.io.PrintStream))
+(defclass Tagged [[java.lang.String tag] [java.lang.Object data]])
+
#( (ann id #type (All [x] (-> [x] x))) )#
(def (id x)
x)