From 04259ac74894f5e0b3319efe17c833b179d483e3 Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Mon, 8 Dec 2014 23:38:12 -0400 Subject: Can now define inside modules: simple classes with public fields. --- src/lang.clj | 3 +++ src/lang/compiler.clj | 20 ++++++++++++++++++-- src/lang/parser.clj | 9 +++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) (limited to 'src') 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] -- cgit v1.2.3