aboutsummaryrefslogtreecommitdiff
path: root/new-luxc
diff options
context:
space:
mode:
authorEduardo Julian2019-09-18 19:20:50 -0400
committerEduardo Julian2019-09-18 19:20:50 -0400
commit5d9fe393959c4c9c9bcbd04cef3115f7f834612f (patch)
treea683700f7221a5410a65502d73d3d46016951b3c /new-luxc
parentf0a95ee657fef968df1f5f88dc741256e1153e63 (diff)
Added packaging machinery for the JVM compiler.
Diffstat (limited to '')
-rw-r--r--new-luxc/source/luxc/lang/packager.lux112
-rw-r--r--new-luxc/source/luxc/lang/translation/jvm/runtime.lux8
-rw-r--r--new-luxc/source/program.lux36
3 files changed, 138 insertions, 18 deletions
diff --git a/new-luxc/source/luxc/lang/packager.lux b/new-luxc/source/luxc/lang/packager.lux
new file mode 100644
index 000000000..3f8cb36cb
--- /dev/null
+++ b/new-luxc/source/luxc/lang/packager.lux
@@ -0,0 +1,112 @@
+(.module:
+ [lux #*
+ ["." host (#+ import: do-to)]
+ [data
+ ["." binary (#+ Binary)]
+ ["." text]
+ [number
+ ["n" nat]]
+ [collection
+ ["." row]
+ ["." list ("#@." fold)]]]
+ [target
+ [jvm
+ [encoding
+ ["." name]]]]
+ [tool
+ [compiler
+ [phase
+ [generation (#+ Buffer Output)]]
+ [meta
+ [archive
+ [descriptor (#+ Module)]]]]]]
+ [//
+ [host
+ [jvm (#+ Definition)]]])
+
+(import: #long java/lang/Object)
+
+(import: #long java/lang/String)
+
+(import: #long java/util/jar/Attributes
+ (put [java/lang/Object java/lang/Object] #? java/lang/Object))
+
+(import: #long java/util/jar/Attributes$Name
+ (#static MAIN_CLASS java/util/jar/Attributes$Name)
+ (#static MANIFEST_VERSION java/util/jar/Attributes$Name))
+
+(import: #long java/util/jar/Manifest
+ (new [])
+ (getMainAttributes [] java/util/jar/Attributes))
+
+(import: #long java/io/Flushable
+ (flush [] void))
+
+(import: #long java/io/Closeable
+ (close [] void))
+
+(import: #long java/io/OutputStream)
+
+(import: #long java/io/ByteArrayOutputStream
+ (new [int])
+ (toByteArray [] [byte]))
+
+(import: #long java/util/zip/ZipEntry)
+
+(import: #long java/util/zip/ZipOutputStream
+ (write [[byte] int int] void)
+ (closeEntry [] void))
+
+(import: #long java/util/jar/JarEntry
+ (new [java/lang/String]))
+
+(import: #long java/util/jar/JarOutputStream
+ (new [java/io/OutputStream java/util/jar/Manifest])
+ (putNextEntry [java/util/zip/ZipEntry] void))
+
+(def: byte 1)
+(def: kilo-byte (n.* 1,000 byte))
+(def: mega-byte (n.* 1,000 kilo-byte))
+
+(def: manifest-version "1.0")
+
+(def: class-name
+ (-> Module Text)
+ (text.suffix ".class"))
+
+(def: main "_")
+
+(def: (manifest module)
+ (-> Module java/util/jar/Manifest)
+ (let [manifest (java/util/jar/Manifest::new)]
+ (exec (do-to (java/util/jar/Manifest::getMainAttributes manifest)
+ (java/util/jar/Attributes::put (java/util/jar/Attributes$Name::MAIN_CLASS) ..main)
+ (java/util/jar/Attributes::put (java/util/jar/Attributes$Name::MANIFEST_VERSION) ..manifest-version))
+ manifest)))
+
+(def: (write-class [def-name [class-name bytecode]] sink)
+ (-> [Name Definition] java/util/jar/JarOutputStream java/util/jar/JarOutputStream)
+ (let [class-name (|> class-name name.internal name.read ..class-name)]
+ (do-to sink
+ (java/util/jar/JarOutputStream::putNextEntry (java/util/jar/JarEntry::new class-name))
+ (java/util/zip/ZipOutputStream::write bytecode +0 (.int (binary.size bytecode)))
+ (java/io/Flushable::flush)
+ (java/util/zip/ZipOutputStream::closeEntry))))
+
+(def: (write-module [module classes] sink)
+ (-> [Module (Buffer Definition)] java/util/jar/JarOutputStream java/util/jar/JarOutputStream)
+ (|> classes
+ row.to-list
+ (list@fold ..write-class sink)))
+
+(def: #export (package module outputs)
+ (-> Module (Output Definition) Binary)
+ (let [buffer (java/io/ByteArrayOutputStream::new (.int mega-byte))
+ sink (java/util/jar/JarOutputStream::new buffer (manifest module))]
+ (exec (|> outputs
+ row.to-list
+ (list@fold ..write-module sink))
+ (do-to sink
+ (java/io/Flushable::flush)
+ (java/io/Closeable::close))
+ (java/io/ByteArrayOutputStream::toByteArray buffer))))
diff --git a/new-luxc/source/luxc/lang/translation/jvm/runtime.lux b/new-luxc/source/luxc/lang/translation/jvm/runtime.lux
index d616d62e9..f97831ac5 100644
--- a/new-luxc/source/luxc/lang/translation/jvm/runtime.lux
+++ b/new-luxc/source/luxc/lang/translation/jvm/runtime.lux
@@ -322,7 +322,7 @@
(def: reflection (|>> type.reflection reflection.reflection))
(def: translate-runtime
- (Operation ByteCode)
+ (Operation Any)
(let [runtime-class (..reflection //.$Runtime)
bytecode ($d.class #$.V1_6 #$.Public $.finalC runtime-class (list) (type.class "java.lang.Object" (list)) (list)
(|>> adt-methods
@@ -331,10 +331,10 @@
io-methods))]
(do phase.monad
[_ (generation.execute! runtime-class [runtime-class bytecode])]
- (wrap bytecode))))
+ (generation.save! false ["" runtime-class] [runtime-class bytecode]))))
(def: translate-function
- (Operation ByteCode)
+ (Operation Any)
(let [applyI (|> (list.n/range 2 num-apply-variants)
(list@map (function (_ arity)
($d.method #$.Public $.noneM apply-method (apply-signature arity)
@@ -363,7 +363,7 @@
applyI))]
(do phase.monad
[_ (generation.execute! function-class [function-class bytecode])]
- (wrap bytecode))))
+ (generation.save! false ["" function-class] [function-class bytecode]))))
(def: #export translate
(Operation Any)
diff --git a/new-luxc/source/program.lux b/new-luxc/source/program.lux
index f22d9ef58..dd44128df 100644
--- a/new-luxc/source/program.lux
+++ b/new-luxc/source/program.lux
@@ -10,6 +10,8 @@
[parser
[cli (#+ program:)]]]
[data
+ [text
+ ["%" format (#+ format)]]
[collection
[array (#+ Array)]
["." dictionary]]]
@@ -32,6 +34,7 @@
["/." cli]]]
[luxc
[lang
+ ["." packager]
[host
["_" jvm
["$d" def]
@@ -132,8 +135,8 @@
$i.SWAP
($i.GOTO @loop)
($i.label @end)
- $i.POP
- ($i.ASTORE 0)))
+ $i.POP))
+ feed-inputsI ($i.INVOKEVIRTUAL jvm.$Function runtime.apply-method (runtime.apply-signature 1))
run-ioI (|>> ($i.CHECKCAST jvm.$Function)
$i.NULL
($i.INVOKEVIRTUAL jvm.$Function runtime.apply-method (runtime.apply-signature 1)))
@@ -148,19 +151,24 @@
(list) $Object
(list)
(|>> ($d.method #_.Public _.staticM "main" main-type
- (|>> prepare-input-listI
- programI
+ (|>> programI
+ prepare-input-listI
+ feed-inputsI
run-ioI
- $i.POP
$i.RETURN))))]))
(program: [{service /cli.service}]
- (/.compiler @.jvm
- ".jvm"
- ..expander
- analysis.bundle
- ..platform
- translation.bundle
- directive.bundle
- ..program
- service))
+ (let [(^slots [#/cli.target #/cli.module]) (case service
+ (#/cli.Compilation configuration) configuration
+ (#/cli.Interpretation configuration) configuration)
+ jar-path (format target (:: file.system separator) "program.jar")]
+ (/.compiler @.jvm
+ ".jvm"
+ ..expander
+ analysis.bundle
+ ..platform
+ translation.bundle
+ directive.bundle
+ ..program
+ service
+ [(packager.package module) jar-path])))