aboutsummaryrefslogtreecommitdiff
path: root/src/lux/compiler/base.clj
blob: 39c67f5d035ea605e12424f45eb7b71e08f001f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
(ns lux.compiler.base
  (:require [clojure.string :as string]
            (lux [base :as & :refer [exec return* return fail fail*
                                     repeat-m exhaust-m try-m try-all-m map-m reduce-m
                                     apply-m
                                     normalize-ident]]))
  (:import (org.objectweb.asm Opcodes
                              Label
                              ClassWriter
                              MethodVisitor)))

;; [Resources]
(def local-prefix "l")
(def partial-prefix "p")
(def closure-prefix "c")
(def tuple-field-prefix "_")
(def apply-signature "(Ljava/lang/Object;)Ljava/lang/Object;")

(defn add-nulls [writer amount]
  (dotimes [_ amount]
    (.visitInsn writer Opcodes/ACONST_NULL)))

(defn write-file [file data]
  (with-open [stream (java.io.BufferedOutputStream. (java.io.FileOutputStream. file))]
    (.write stream data)))

(defn write-class [name data]
  (write-file (str "output/" name ".class") data))

(defn load-class! [loader name]
  (.loadClass loader name))

(defn save-class! [name bytecode]
  (exec [loader &/loader
         :let [_ (write-class name bytecode)
               _ (load-class! loader (string/replace name #"/" "."))]]
    (return nil)))