aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEduardo Julian2014-12-08 20:36:41 -0400
committerEduardo Julian2014-12-08 20:36:41 -0400
commitc68be3366cb67ff96ec88904ccc9d1efd7a78bed (patch)
tree720aff5c5cc6960aec6e66130edf5397263a793d /src
parent8f8467773fa2c5fb6556355a826b03050f75824e (diff)
Added modules.
Diffstat (limited to 'src')
-rw-r--r--src/lang.clj24
-rw-r--r--src/lang/compiler.clj102
-rw-r--r--src/lang/parser.clj5
3 files changed, 85 insertions, 46 deletions
diff --git a/src/lang.clj b/src/lang.clj
index 77235dcf0..6502c3a29 100644
--- a/src/lang.clj
+++ b/src/lang.clj
@@ -14,12 +14,28 @@
_ (prn 'tokens tokens)
syntax (&parser/parse tokens)
_ (prn 'syntax syntax)
- class-data (&compiler/compile syntax)]
- (write-file "output.class" class-data))
+ class-data (&compiler/compile "test2" syntax)]
+ (write-file "test2.class" class-data))
(->> (slurp "test2.lang")
&lexer/lex
&parser/parse
- &compiler/compile
- (write-file "output.class"))
+ (&compiler/compile "test2")
+ (write-file "test2.class"))
+
+ ;; TODO: Define the Function abstract class.
+ ;; TODO: Define functions as classes inheriting Function.
+ ;; TODO: Add tuples.
+ ;; TODO: Add let.
+ ;; TODO: Add pattern-matching.
+ ;; TODO: Add tagged values.
+ ;; TODO: Do tail-call optimization.
+ ;; TODO: Add macros.
+ ;; TODO: Add type-level computations.
+ ;; TODO: Add interpreter.
+ ;; TODO: Add Java-interop.
+ ;; TODO: Add signatures & structures.
+ ;; TODO: Add type-system.
+ ;; TODO: Allow defining constants.
+ ;; TODO:
)
diff --git a/src/lang/compiler.clj b/src/lang/compiler.clj
index 52195d2f2..3e63fc801 100644
--- a/src/lang/compiler.clj
+++ b/src/lang/compiler.clj
@@ -13,13 +13,19 @@
;; [Utils/General]
(defmacro ^:private defcompiler [name match body]
- `(defn ~name [~'*writer* ~'*form*]
- (match ~'*form*
- ~match
- (do ~body
- true)
- _#
- false)))
+ `(defn ~name [~'*state*]
+ (let [~'*name* (:name ~'*state*)
+ ~'*writer* (:writer ~'*state*)
+ ~'*form* (:form ~'*state*)]
+ (match ~'*form*
+ ~match
+ (do ~body
+ true)
+ _#
+ false))))
+
+(defn compile-form* [writer form]
+ (compile-form {:writer writer, :form form}))
(defn ^:private unwrap-ident [ident]
(match ident
@@ -61,9 +67,9 @@
(defcompiler ^:private compile-fn-call
[::&parser/fn-call [::&parser/ident ?fn] ?args]
(do (doseq [arg ?args]
- (compile-form *writer* arg))
+ (compile-form (assoc *state* :form arg)))
(doto *writer*
- (.visitMethodInsn Opcodes/INVOKESTATIC "output" ?fn "(Ljava/lang/Object;)Ljava/lang/Object;"))))
+ (.visitMethodInsn Opcodes/INVOKESTATIC *name* ?fn "(Ljava/lang/Object;)Ljava/lang/Object;"))))
(defcompiler ^:private compile-static-access
[::&parser/static-access ?class ?member]
@@ -72,11 +78,11 @@
(defcompiler ^:private compile-dynamic-access
[::&parser/dynamic-access ?object ?access]
- (let [=object (compile-form *writer* ?object)
+ (let [=object (compile-form (assoc *state* :form ?object))
method (match ?access
[::&parser/fn-call [::&parser/ident ?method] ?args]
(do (doseq [arg ?args]
- (compile-form *writer* arg))
+ (compile-form (assoc *state* :form arg)))
?method))]
(doto *writer*
(.visitMethodInsn Opcodes/INVOKEVIRTUAL (->class "java.io.PrintStream") method "(Ljava/lang/Object;)V"))))
@@ -89,13 +95,13 @@
[::&parser/if ?test ?then ?else]
(let [else-label (new Label)
end-label (new Label)]
- (compile-form *writer* ?test)
+ (compile-form (assoc *state* :form ?test))
(.visitJumpInsn *writer* Opcodes/IFEQ else-label)
- (compile-form *writer* ?then)
+ (compile-form (assoc *state* :form ?then))
(doto *writer*
(.visitJumpInsn Opcodes/GOTO end-label)
(.visitLabel else-label))
- (compile-form *writer* ?else)
+ (compile-form (assoc *state* :form ?else))
(.visitLabel *writer* end-label)))
(defcompiler ^:private compile-def
@@ -103,20 +109,27 @@
(match ?form
[::&parser/fn-call [::&parser/ident ?name] ?args]
(if (= "main" ?name)
- (doto (.visitMethod *writer* (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) ?name "([Ljava/lang/String;)V" nil nil)
- (.visitCode)
- (compile-form ?body)
- (.visitInsn Opcodes/RETURN)
- (.visitMaxs 0 0)
- (.visitEnd))
- (doto (.visitMethod *writer* (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) ?name "(Ljava/lang/Object;)Ljava/lang/Object;" nil nil)
- (.visitCode)
- (compile-form ?body)
- (.visitInsn Opcodes/ARETURN)
- (.visitMaxs 0 0)
- (.visitEnd)))
+ (let [=method (doto (.visitMethod *writer* (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) ?name "([Ljava/lang/String;)V" nil nil)
+ (.visitCode))]
+ (compile-form (assoc *state* :writer =method :form ?body))
+ (doto =method
+ (.visitInsn Opcodes/RETURN)
+ (.visitMaxs 0 0)
+ (.visitEnd)))
+ (let [=method (doto (.visitMethod *writer* (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) ?name "(Ljava/lang/Object;)Ljava/lang/Object;" nil nil)
+ (.visitCode))]
+ (compile-form (assoc *state* :writer =method :form ?body))
+ (doto =method
+ (.visitInsn Opcodes/ARETURN)
+ (.visitMaxs 0 0)
+ (.visitEnd))))
))
+(defcompiler ^:private compile-module
+ [::&parser/module]
+ (.visit *writer* Opcodes/V1_5 (+ Opcodes/ACC_PUBLIC Opcodes/ACC_SUPER)
+ *name* nil "java/lang/Object" nil))
+
(let [+compilers+ [compile-boolean
compile-string
compile-ident
@@ -125,24 +138,29 @@
compile-dynamic-access
compile-ann-class
compile-if
- compile-def]]
- (defn ^:private compile-form [writer form]
- (prn 'compile-form/form form)
- (some #(% writer form) +compilers+)))
+ compile-def
+ compile-module]]
+ (defn ^:private compile-form [state]
+ (prn 'compile-form/state state)
+ (some #(% state) +compilers+)))
;; [Interface]
-(defn compile [inputs]
+(defn compile [class-name inputs]
(prn 'inputs inputs)
- (let [=class (doto (new ClassWriter ClassWriter/COMPUTE_MAXS)
- (.visit Opcodes/V1_5 (+ Opcodes/ACC_PUBLIC Opcodes/ACC_SUPER)
- "output" nil "java/lang/Object" nil))]
- (doto (.visitMethod =class Opcodes/ACC_PUBLIC "<init>" "()V" nil nil)
- (.visitCode)
- (.visitVarInsn Opcodes/ALOAD 0)
- (.visitMethodInsn Opcodes/INVOKESPECIAL "java/lang/Object" "<init>" "()V")
- (.visitInsn Opcodes/RETURN)
- (.visitMaxs 0 0)
- (.visitEnd))
- (doall (map (partial compile-form =class) inputs))
+ (let [=class (new ClassWriter ClassWriter/COMPUTE_MAXS)
+ ;; (doto (new ClassWriter ClassWriter/COMPUTE_MAXS)
+ ;; (.visit Opcodes/V1_5 (+ Opcodes/ACC_PUBLIC Opcodes/ACC_SUPER)
+ ;; "output" nil "java/lang/Object" nil))
+ state {:name class-name
+ :writer =class
+ :form nil}]
+ ;; (doto (.visitMethod =class Opcodes/ACC_PUBLIC "<init>" "()V" nil nil)
+ ;; (.visitCode)
+ ;; (.visitVarInsn Opcodes/ALOAD 0)
+ ;; (.visitMethodInsn Opcodes/INVOKESPECIAL "java/lang/Object" "<init>" "()V")
+ ;; (.visitInsn Opcodes/RETURN)
+ ;; (.visitMaxs 0 0)
+ ;; (.visitEnd))
+ (doall (map #(compile-form (assoc state :form %)) inputs))
(.visitEnd =class)
(.toByteArray =class)))
diff --git a/src/lang/parser.clj b/src/lang/parser.clj
index f09d87145..5adf36030 100644
--- a/src/lang/parser.clj
+++ b/src/lang/parser.clj
@@ -103,6 +103,10 @@
(partition 2 ?bindings)))]
(return [::let =bindings =expr])))
+(defparser ^:private parse-module
+ [::&lexer/list ([[::&lexer/ident "module"]] :seq)]
+ (return [::module]))
+
(defparser ^:private parse-tagged
[::&lexer/list ([[::&lexer/tag ?tag] ?data] :seq)]
(exec [=data (apply-m parse-form (list ?data))]
@@ -185,6 +189,7 @@
parse-static-access
parse-dynamic-access
parse-ann-class
+ parse-module
parse-fn-call]))
;; [Interface]