diff options
author | Eduardo Julian | 2019-04-24 21:28:56 -0400 |
---|---|---|
committer | Eduardo Julian | 2019-04-24 21:28:56 -0400 |
commit | f2c0473640e8029f27797f6ecf21662dddb0685b (patch) | |
tree | d1f881b7c8416ecfa49e8752420ad23da7f9b578 /lux-php | |
parent | 448eb9d9ae01569459f72ad4de740f960b02bfad (diff) |
WIP: PHP compiler.
Diffstat (limited to 'lux-php')
-rw-r--r-- | lux-php/project.clj | 33 | ||||
-rw-r--r-- | lux-php/source/program.lux | 460 |
2 files changed, 493 insertions, 0 deletions
diff --git a/lux-php/project.clj b/lux-php/project.clj new file mode 100644 index 000000000..8dfe91d27 --- /dev/null +++ b/lux-php/project.clj @@ -0,0 +1,33 @@ +(def version "0.6.0-SNAPSHOT") +(def repo "https://github.com/LuxLang/lux") +(def sonatype-releases "https://oss.sonatype.org/service/local/staging/deploy/maven2/") +(def sonatype-snapshots "https://oss.sonatype.org/content/repositories/snapshots/") + +(defproject com.github.luxlang/lux-php #=(identity version) + :description "A Ruby compiler for Lux." + :url ~repo + :license {:name "Lux License v0.1" + :url ~(str repo "/blob/master/license.txt")} + :scm {:name "git" + :url ~(str repo ".git")} + :pom-addition [:developers [:developer + [:name "Eduardo Julian"] + [:url "https://github.com/eduardoejp"]]] + + :repositories [["releases" ~sonatype-releases] + ["snapshots" ~sonatype-snapshots] + ["jitpack" "https://jitpack.io"]] + :deploy-repositories [["releases" {:url ~sonatype-releases :creds :gpg}] + ["snapshots" {:url ~sonatype-snapshots :creds :gpg}]] + + :plugins [[com.github.luxlang/lein-luxc ~version]] + :dependencies [[com.github.luxlang/luxc-jvm ~version] + [com.github.luxlang/stdlib ~version] + ;; PHP 5 + [org.develnext.jphp/jphp-core "0.9.2"] + [org.develnext.jphp/jphp-scripting "0.9.2"]] + + :manifest {"lux" ~version} + :source-paths ["source"] + :lux {:program "program"} + ) diff --git a/lux-php/source/program.lux b/lux-php/source/program.lux new file mode 100644 index 000000000..f3f445bd9 --- /dev/null +++ b/lux-php/source/program.lux @@ -0,0 +1,460 @@ +(.module: + [lux #* + [abstract + ["." monad (#+ do)]] + [control + pipe + ["." exception (#+ exception:)] + ["." io (#+ IO io)] + ["p" parser + [cli (#+ program:)]]] + [data + ["." maybe] + ["." error (#+ Error)] + [number + ["." i64]] + ["." text ("#@." hash) + format] + [collection + ["." array (#+ Array)] + ["." list ("#@." functor)]]] + [macro + ["." template]] + [world + ["." file]] + ["." host (#+ import: interface: do-to object) + ["_" php]] + [tool + [compiler + ["." name] + ["." synthesis] + [phase + [macro (#+ Expander)] + ["." generation + ["." php + ["." runtime] + ["." extension]]]] + [default + ["." platform (#+ Platform)]]]] + ["." debug]] + [program + ["/" compositor + ["/." cli]]]) + +(import: #long java/lang/String) + +(import: #long (java/lang/Class a)) + +(import: #long java/lang/Object + (toString [] java/lang/String) + (getClass [] (java/lang/Class java/lang/Object))) + +(import: #long java/lang/Integer) + +(import: #long java/lang/Long + (intValue [] java/lang/Integer)) + +(import: #long php/runtime/Memory) + +(import: #long php/runtime/Memory$Type + (#enum ARRAY)) + +(import: #long php/runtime/memory/NullMemory) + +(import: #long php/runtime/memory/FalseMemory) +(import: #long php/runtime/memory/TrueMemory) + +(import: #long php/runtime/memory/LongMemory + (new [long]) + (toLong [] long)) + +(import: #long php/runtime/memory/DoubleMemory + (toDouble [] double)) + +(import: #long php/runtime/memory/StringMemory + (new [java/lang/String]) + (toString [] java/lang/String)) + +(import: #long php/runtime/memory/ReferenceMemory + (getValue [] php/runtime/Memory)) + +(import: #long php/runtime/memory/ArrayMemory + (new [(Array java/lang/Object)]) + (size [] int) + (isMap [] boolean) + (get [php/runtime/Memory] php/runtime/Memory)) + +(import: #long php/runtime/lang/IObject) + +(import: #long php/runtime/memory/ObjectMemory + (value php/runtime/lang/IObject)) + +(import: #long php/runtime/env/Environment + (#static current [] php/runtime/env/Environment)) + +(import: #long php/runtime/env/TraceInfo + (new [java/lang/String int int])) + +(import: #long php/runtime/reflection/FunctionEntity) + +(import: #long php/runtime/invoke/InvokeHelper + (#static callAny [php/runtime/Memory (Array php/runtime/Memory) php/runtime/env/Environment php/runtime/env/TraceInfo] + #try php/runtime/Memory)) + +(import: #long php/runtime/lang/Closure + (call [php/runtime/env/Environment (Array php/runtime/Memory)] #try php/runtime/Memory)) + +(template [<name>] + [(interface: <name> + (getValue [] java/lang/Object)) + + (`` (import: (~~ (template.identifier ["program/" <name>])) + (getValue [] java/lang/Object)))] + + [StructureValue] + ) + +(type: Reader + (-> java/lang/Object (Error Any))) + +(exception: (unknown-kind-of-object {object java/lang/Object}) + (exception.report + ["Class" (java/lang/Object::toString (java/lang/Object::getClass object))] + ["Object" (java/lang/Object::toString object)])) + +(def: (lux-structure value) + (-> (Array java/lang/Object) + ## php/runtime/memory/ArrayMemory + php/runtime/Memory) + (`` (object [] php/runtime/Memory ## php/runtime/memory/ArrayMemory + [program/StructureValue] + [{php/runtime/Memory$Type php/runtime/Memory$Type::ARRAY}] + ## Methods + (program/StructureValue + (getValue) + java/lang/Object + (:assume value)) + + ## (php/runtime/memory/ArrayMemory + ## (size) + ## int + ## (exec + ## (log! "{lux-structure#size}") + ## (:assume (array.size value)))) + + ## (php/runtime/memory/ArrayMemory + ## (get {key php/runtime/Memory}) + ## php/runtime/Memory + ## (exec + ## (log! (format "{lux-structure#get}" text.new-line + ## (exception.construct unknown-kind-of-object key))) + ## (error! "OOPS!"))) + + ## (php/runtime/memory/ArrayMemory + ## (getOrCreate {key php/runtime/Memory}) + ## php/runtime/memory/ReferenceMemory + ## (exec + ## (log! (format "{lux-structure#getOrCreate}" text.new-line + ## (exception.construct unknown-kind-of-object key))) + ## (error! "OOPS!"))) + + ## (php/runtime/memory/ArrayMemory + ## (getOrCreateAsShortcut {key php/runtime/Memory}) + ## php/runtime/memory/ReferenceMemory + ## (exec + ## (log! (format "{lux-structure#getOrCreateAsShortcut}" text.new-line + ## (exception.construct unknown-kind-of-object key))) + ## (error! "OOPS!"))) + + ## (php/runtime/memory/ArrayMemory + ## (getByScalarOrCreateAsShortcut {key java/lang/Object}) + ## php/runtime/memory/ReferenceMemory + ## (exec + ## (log! (format "{lux-structure#getByScalarOrCreateAsShortcut}" text.new-line + ## (exception.construct unknown-kind-of-object key))) + ## (error! "OOPS!"))) + + ## (php/runtime/memory/ArrayMemory + ## (getByScalarOrCreate {key java/lang/Object}) + ## php/runtime/memory/ReferenceMemory + ## (exec + ## (log! (format "{lux-structure#getByScalarOrCreate}" text.new-line + ## (exception.construct unknown-kind-of-object key))) + ## (error! "OOPS!"))) + + ## (php/runtime/memory/ArrayMemory + ## (getByScalar {key java/lang/Object}) + ## php/runtime/memory/ReferenceMemory + ## (exec + ## (log! (format "{lux-structure#getByScalar}" text.new-line + ## (exception.construct unknown-kind-of-object key))) + ## (error! "OOPS!"))) + + (php/runtime/Memory + (refOfIndex {trace php/runtime/env/TraceInfo} + {index php/runtime/Memory}) + php/runtime/Memory + (exec + (log! (format "{lux-structure#refOfIndex}" text.new-line + (exception.construct unknown-kind-of-object index))) + (error! "OOPS!"))) + + (php/runtime/Memory + (refOfIndexAsShortcut {trace php/runtime/env/TraceInfo} + {index php/runtime/Memory}) + php/runtime/Memory + (exec + (log! (format "{lux-structure#refOfIndexAsShortcut}" text.new-line + (exception.construct unknown-kind-of-object index))) + (error! "OOPS!"))) + + (php/runtime/Memory + (refOfIndex {trace php/runtime/env/TraceInfo} + {index long}) + php/runtime/Memory + (exec + (log! (format "{lux-structure#refOfIndex long}" text.new-line + (exception.construct unknown-kind-of-object index))) + (error! "OOPS!"))) + + (php/runtime/Memory + (refOfIndex {trace php/runtime/env/TraceInfo} + {index java/lang/String}) + php/runtime/Memory + (exec + (log! (format "{lux-structure#refOfIndex java/lang/String}" text.new-line + (exception.construct unknown-kind-of-object index))) + (error! "OOPS!"))) + + (~~ (template [<name>] + [(php/runtime/Memory (<name>) php/runtime/Memory (undefined))] + + [inc] [dec] [negative] [toNumeric] + )) + + (~~ (template [<name>] + [(php/runtime/Memory (<name> {other php/runtime/Memory}) php/runtime/Memory (undefined))] + + [plus] [minus] [mul] [pow] [div] + [identical] [equal] [notEqual] + [smaller] [smallerEq] [greater] [greaterEq] + )) + + (php/runtime/Memory (toLong) long (undefined)) + (php/runtime/Memory (toDouble) double (undefined)) + (php/runtime/Memory (toBoolean) boolean (undefined)) + (php/runtime/Memory (toString) java/lang/String (undefined)) + (php/runtime/Memory (getBinaryBytes {input java/nio/charset/Charset}) ByteArray (undefined)) + ))) + +(def: (read-tuple read host-object) + (-> Reader php/runtime/memory/ArrayMemory (Error Any)) + (let [size (:coerce Nat (php/runtime/memory/ArrayMemory::size host-object))] + (loop [idx 0 + output (:coerce (Array Any) (array.new size))] + (if (n/< size idx) + (let [value (|> host-object + (php/runtime/memory/ArrayMemory::get (php/runtime/memory/LongMemory::new (.int idx))) + (:coerce php/runtime/memory/ReferenceMemory) + php/runtime/memory/ReferenceMemory::getValue)] + (case (host.check php/runtime/memory/NullMemory value) + (#.Some _) + (recur (inc idx) output) + + #.None + (case (read value) + (#error.Failure error) + (#error.Failure error) + + (#error.Success lux-value) + (recur (inc idx) (array.write idx lux-value output))))) + (#error.Success output))))) + +(def: (read-variant read host-object) + (-> Reader php/runtime/memory/ArrayMemory (Error Any)) + (case [(|> host-object + (php/runtime/memory/ArrayMemory::get (php/runtime/memory/StringMemory::new runtime.variant-tag-field)) + read) + (|> host-object + (php/runtime/memory/ArrayMemory::get (php/runtime/memory/StringMemory::new runtime.variant-value-field)) + read)] + [(#error.Success tag) (#error.Success value)] + (#error.Success [(java/lang/Long::intValue (:coerce java/lang/Long tag)) + (: Any + (case (|> host-object + (php/runtime/memory/ArrayMemory::get (php/runtime/memory/StringMemory::new runtime.variant-flag-field)) + (:coerce php/runtime/memory/ReferenceMemory) + php/runtime/memory/ReferenceMemory::getValue + (host.check php/runtime/memory/NullMemory)) + (#.Some _) + (host.null) + + #.None + synthesis.unit)) + value]) + + _ + (exception.throw ..unknown-kind-of-object host-object))) + +(exception: #export nulll-has-no-lux-representation) + +(def: (read host-object) + Reader + (`` (<| (~~ (template [<class> <constant>] + [(case (host.check <class> host-object) + (#.Some _) + (#error.Success <constant>) + + #.None)] + + [php/runtime/memory/FalseMemory false] + [php/runtime/memory/TrueMemory true] + )) + (~~ (template [<class> <post>] + [(case (host.check <class> host-object) + (#.Some value) + (`` (|> value (~~ (template.splice <post>)))) + + #.None)] + + [php/runtime/memory/LongMemory [php/runtime/memory/LongMemory::toLong #error.Success]] + [php/runtime/memory/DoubleMemory [php/runtime/memory/DoubleMemory::toDouble #error.Success]] + [php/runtime/memory/StringMemory [php/runtime/memory/StringMemory::toString #error.Success]] + [php/runtime/memory/ReferenceMemory [php/runtime/memory/ReferenceMemory::getValue read]] + [php/runtime/memory/ObjectMemory [#error.Success]] + )) + (case (host.check php/runtime/memory/ArrayMemory host-object) + (#.Some value) + (if (php/runtime/memory/ArrayMemory::isMap value) + (read-variant read value) + (read-tuple read value)) + + #.None) + (exception.throw ..unknown-kind-of-object host-object) + ))) + +(exception: (cannot-apply-a-non-function {object java/lang/Object}) + (exception.report + ["Class" (java/lang/Object::toString (java/lang/Object::getClass object))] + ["Non-function" (java/lang/Object::toString object)])) + +(import: #long javax/script/ScriptEngine + (eval [String] #try Object)) + +(import: #long org/develnext/jphp/scripting/JPHPScriptEngine + (new [])) + +(def: (ensure-macro macro) + ## (-> Macro (Maybe php/runtime/lang/Closure)) + ## (do maybe.monad + ## [object-memory (|> macro + ## (:coerce java/lang/Object) + ## (host.check php/runtime/memory/ObjectMemory))] + ## (|> object-memory + ## php/runtime/memory/ObjectMemory::value + ## (host.check php/runtime/lang/Closure))) + (-> Macro (Maybe php/runtime/memory/ObjectMemory)) + (|> macro + (:coerce java/lang/Object) + (host.check php/runtime/memory/ObjectMemory))) + +(def: (call-macro inputs lux macro) + (-> (List Code) Lux + php/runtime/memory/ObjectMemory + ## php/runtime/lang/Closure + (Error (Error [Lux (List Code)]))) + (<| :assume + (do error.monad + [#let [_ (log! (format "{call-macro 0} " (exception.construct ..unknown-kind-of-object (:coerce java/lang/Object (php/runtime/memory/ObjectMemory::value macro)))))] + output (php/runtime/lang/Closure::call (php/runtime/env/Environment::current) + (|> (host.array php/runtime/Memory 3) + (host.array-write 0 macro) + (host.array-write 1 + ## (php/runtime/memory/ArrayMemory::new (:coerce (Array java/lang/Object) inputs)) + (lux-structure (:coerce (Array java/lang/Object) inputs)) + ) + (host.array-write 2 + ## (php/runtime/memory/ArrayMemory::new (:coerce (Array java/lang/Object) lux)) + (lux-structure (:coerce (Array java/lang/Object) lux)) + )) + (:coerce php/runtime/lang/Closure + (php/runtime/memory/ObjectMemory::value macro))) + ## output (php/runtime/invoke/InvokeHelper::callAny macro + ## (|> (host.array php/runtime/Memory 2) + ## ## (host.array-write 0 macro) + ## ## (host.array-write 1 macro) + ## (host.array-write 0 ## (php/runtime/memory/ArrayMemory::new (:coerce (Array java/lang/Object) inputs)) + ## (lux-structure (:coerce (Array java/lang/Object) inputs)) + ## ) + ## (host.array-write 1 ## (php/runtime/memory/ArrayMemory::new (:coerce (Array java/lang/Object) lux)) + ## (lux-structure (:coerce (Array java/lang/Object) lux)) + ## )) + ## (php/runtime/env/Environment::current) + ## (php/runtime/env/TraceInfo::new "" +0 +0)) + #let [_ (log! (format "{call-macro 1} " (debug.inspect output))) + _ (log! (format "{call-macro 2} " (exception.construct ..unknown-kind-of-object (:coerce java/lang/Object output))))]] + (..read (:coerce java/lang/Object output))))) + +(def: (expander macro inputs lux) + Expander + (case (ensure-macro macro) + (#.Some macro) + (call-macro inputs lux macro) + + #.None + (exception.throw cannot-apply-a-non-function (:coerce java/lang/Object macro))) + ) + +(def: separator "___") + +(type: Host + (generation.Host (_.Expression Any) _.Statement)) + +(def: host + (IO Host) + (io (let [interpreter (org/develnext/jphp/scripting/JPHPScriptEngine::new) + run! (: (-> Text (_.Code Any) (Error Any)) + (function (_ dummy-name code) + (do error.monad + [output (javax/script/ScriptEngine::eval (format "<?php " (_.code code)) interpreter)] + (..read output))))] + (: Host + (structure + (def: (evaluate! dummy-name code) + (run! dummy-name (_.return code))) + + (def: execute! run!) + + (def: (define! [module name] input) + (let [global (format (text.replace-all .module-separator ..separator module) + ..separator (name.normalize name) + "___" (%n (text@hash name))) + @global (_.global global)] + (do error.monad + [#let [definition (_.; (_.set @global input))] + _ (run! global definition) + value (run! global (_.return @global))] + (wrap [global value definition]))))))))) + +(def: platform + (IO (Platform IO _.Var (_.Expression Any) _.Statement)) + (do io.monad + [host ..host] + (wrap {#platform.&monad io.monad + #platform.&file-system file.system + #platform.host host + #platform.phase php.generate + #platform.runtime runtime.generate}))) + +(def: (program program) + (-> (_.Expression Any) _.Statement) + (_.; (_.apply/2 [(runtime.lux//program-args _.command-line-arguments) + _.null] + program))) + +(program: [{service /cli.service}] + (/.compiler ..expander + ..platform + extension.bundle + ..program + service)) |