From 0c75fd67e3fcfbfb09d8c11b6cf396084ce40a15 Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Wed, 10 Mar 2021 10:32:30 -0400 Subject: Wrestling with JPHP. --- commands.md | 16 +- compilers.md | 245 +----------- lux-js/commands.md | 45 +++ lux-jvm/commands.md | 60 +++ lux-lua/commands.md | 36 ++ lux-php/project.clj | 6 +- lux-php/source/program.lux | 432 +++++++++++++-------- lux-python/commands.md | 35 ++ lux-ruby/commands.md | 35 ++ stdlib/source/lux.lux | 21 +- stdlib/source/lux/target/php.lux | 159 +++++--- .../lux/phase/extension/generation/php/common.lux | 173 ++++----- .../lux/phase/extension/generation/ruby/common.lux | 4 +- .../language/lux/phase/generation/php/case.lux | 57 ++- .../language/lux/phase/generation/php/function.lux | 23 +- .../language/lux/phase/generation/php/loop.lux | 90 +++-- .../language/lux/phase/generation/php/runtime.lux | 261 ++++++++----- .../language/lux/phase/generation/reference.lux | 7 +- 18 files changed, 962 insertions(+), 743 deletions(-) create mode 100644 lux-js/commands.md create mode 100644 lux-jvm/commands.md create mode 100644 lux-lua/commands.md create mode 100644 lux-python/commands.md create mode 100644 lux-ruby/commands.md diff --git a/commands.md b/commands.md index 1628068bc..148ad9040 100644 --- a/commands.md +++ b/commands.md @@ -6,11 +6,21 @@ cd ~/lux/ && find . -name '*.lux' | xargs wc -l --- -# Clean all +# Clean everything ``` cd ~/lux/lux-bootstrapper/ && lein clean && \ -cd ~/lux/stdlib/ && lein clean +cd ~/lux/stdlib/ && lein clean && \ +cd ~/lux/lux-jvm/ && lein clean && \ +cd ~/lux/lux-js/ && lein clean && \ +cd ~/lux/lux-python/ && lein clean && \ +cd ~/lux/lux-lua/ && lein clean && \ +cd ~/lux/lux-ruby/ && lein clean && \ +cd ~/lux/lux-php/ && lein clean && \ +cd ~/lux/lux-cl/ && lein clean && \ +cd ~/lux/lux-scheme/ && lein clean && \ +cd ~/lux/lux-r/ && lein clean + ``` --- @@ -18,7 +28,7 @@ cd ~/lux/stdlib/ && lein clean # Read generated bytecode ``` -cd ~/lux/jbe/ && ./jbe.sh +cd ~/lux/jbe/bin/ && java ee.ioc.cs.jbe.browser.BrowserApplication ``` --- diff --git a/compilers.md b/compilers.md index 3e70d6137..d757f123b 100644 --- a/compilers.md +++ b/compilers.md @@ -1,240 +1,3 @@ -# Clean all - -``` -cd ~/lux/lux-jvm/ && lein clean && \ -cd ~/lux/lux-js/ && lein clean && \ -cd ~/lux/lux-python/ && lein clean && \ -cd ~/lux/lux-lua/ && lein clean && \ -cd ~/lux/lux-ruby/ && lein clean && \ -cd ~/lux/lux-php/ && lein clean && \ -cd ~/lux/lux-cl/ && lein clean && \ -cd ~/lux/lux-scheme/ && lein clean && \ -cd ~/lux/lux-r/ && lein clean -``` - ---- - -# JVM compiler - -## Test - -``` -cd ~/lux/lux-jvm/ && lein lux auto test -cd ~/lux/lux-jvm/ && lein clean && lein lux auto test -``` - -## Build - -``` -cd ~/lux/lux-jvm/ && lein lux auto build - -## Use bootstrapping compiler to build new JVM compiler -cd ~/lux/lux-jvm/ \ -&& lein clean \ -&& lein lux auto build -``` - -## REPL - -``` -cd ~/lux/lux-jvm/ && java -jar target/program.jar repl --source ~/lux/stdlib/source --target ~/lux/stdlib/target -``` - -## Try - -``` -cd ~/lux/lux-jvm/ && time java -jar target/program.jar build --source ~/lux/stdlib/source --target ~/lux/stdlib/target --module test/lux -cd ~/lux/lux-jvm/ && java -jar target/program.jar export --source ~/lux/stdlib/source --target ~/lux/stdlib/target - -cd ~/lux/stdlib/ \ -&& cd ~/lux/lux-jvm/ \ -&& time java -jar target/program.jar build --source ~/lux/stdlib/source --library ~/lux/stdlib/target/library.tar --target ~/lux/stdlib/target --module test/lux - -## Use new JVM compiler to compile tests for the Standard Library -cd ~/lux/stdlib/ \ -&& lein clean \ -&& time java -jar ~/lux/lux-jvm/target/program.jar build --source ~/lux/stdlib/source --target ~/lux/stdlib/target --module test/lux - -## Run tests for the Standard Library -cd ~/lux/stdlib/target/ \ -&& java -jar program.jar -``` - -## Deploy - -``` -cd ~/lux/lux-jvm/ && mvn install:install-file -Dfile=target/program.jar -DgroupId=com.github.luxlang -DartifactId=lux-jvm -Dversion=0.6.0-SNAPSHOT -Dpackaging=jar - -cd ~/lux/lux-jvm/ && mvn deploy:deploy-file \ --Durl=https://:@oss.sonatype.org/content/repositories/snapshots/ \ --Dfile=target/program.jar \ --DgroupId=com.github.luxlang \ --DartifactId=lux-jvm \ --Dversion=0.6.0-SNAPSHOT \ --Dpackaging=jar -``` - ---- - -# JavaScript compiler - -## Test - -``` -cd ~/lux/lux-js/ && lein lux auto test -cd ~/lux/lux-js/ && lein clean && lein lux auto test -``` - -## Build - -``` -cd ~/lux/lux-js/ && lein lux auto build -cd ~/lux/lux-js/ && lein clean && lein lux auto build - -## Build JVM-based compiler -cd ~/lux/lux-js/ \ -&& lein clean \ -&& lein lux build \ -&& mv target/program.jar jvm_based_compiler.jar - -## Use JVM-based compiler to produce a JS/Node-based compiler. -cd ~/lux/lux-js/ \ -&& lein clean \ -&& time java -jar jvm_based_compiler.jar build --source ~/lux/lux-js/source --target ~/lux/lux-js/target --module program \ -&& mv target/program.js node_based_compiler.js - -## Use JS/Node-based compiler to produce another JS/Node-based compiler. -cd ~/lux/lux-js/ \ -&& lein clean \ -&& time node --stack_size=8192 node_based_compiler.js build --source ~/lux/lux-js/source --target ~/lux/lux-js/target --module program \ -&& mv target/program.js lux.js -``` - -## Try - -``` -## Compile Lux's Standard Library's tests using a JS/Node-based compiler. -cd ~/lux/stdlib/ \ -&& lein clean \ -&& time node --stack_size=8192 ~/lux/lux-js/lux.js build --source ~/lux/stdlib/source --target ~/lux/stdlib/target --module test/lux - -node ~/lux/stdlib/target/program.js -``` - ---- - -# Python compiler - -## Test - -``` -cd ~/lux/lux-python/ && lein lux auto test -cd ~/lux/lux-python/ && lein clean && lein lux auto test -``` - -## Build - -``` -## Develop -cd ~/lux/lux-python/ \ -&& lein clean \ -&& lein lux auto build - -## Build JVM-based compiler -cd ~/lux/lux-python/ \ -&& lein clean \ -&& lein lux build \ -&& mv target/program.jar jvm_based_compiler.jar -``` - -## Try - -``` -## Compile Lux's Standard Library's tests using a JVM-based compiler. -cd ~/lux/stdlib/ \ -&& lein clean \ -&& time java -jar ~/lux/lux-python/jvm_based_compiler.jar build --source ~/lux/stdlib/source --target ~/lux/stdlib/target --module test/lux - -python3 ~/lux/stdlib/target/program.py -``` - ---- - -# Lua compiler - -## Test - -``` -cd ~/lux/lux-lua/ && lein lux auto test -cd ~/lux/lux-lua/ && lein clean && lein lux auto test -``` - -## Build - -``` -## Develop -cd ~/lux/lux-lua/ \ -&& lein clean \ -&& lein lux auto build - -## Build JVM-based compiler -## NOTE: Must set lux/control/concurrency/thread.parallelism = 1 before compiling to make sure Rembulan doesn't cause trouble. -cd ~/lux/lux-lua/ \ -&& lein clean \ -&& lein lux build \ -&& mv target/program.jar jvm_based_compiler.jar -``` - -## Try - -``` -## Compile Lux's Standard Library's tests using a JVM-based compiler. -cd ~/lux/stdlib/ \ -&& lein clean \ -&& time java -jar ~/lux/lux-lua/jvm_based_compiler.jar build --source ~/lux/stdlib/source --target ~/lux/stdlib/target --module test/lux - -~/lua-5.4.2/install/bin/lua ~/lux/stdlib/target/program.lua -``` - ---- - -# Ruby compiler - -## Test - -``` -cd ~/lux/lux-ruby/ && lein lux auto test -cd ~/lux/lux-ruby/ && lein clean && lein lux auto test -``` - -## Build - -``` -## Develop -cd ~/lux/lux-ruby/ \ -&& lein clean \ -&& lein lux auto build - -## Build JVM-based compiler -cd ~/lux/lux-ruby/ \ -&& lein clean \ -&& lein lux build \ -&& mv target/program.jar jvm_based_compiler.jar -``` - -## Try - -``` -## Compile Lux's Standard Library's tests using a JVM-based compiler. -cd ~/lux/stdlib/ \ -&& lein clean \ -&& time java -jar ~/lux/lux-ruby/target/program.jar build --source ~/lux/stdlib/source --target ~/lux/stdlib/target --module test/lux - -RUBY_THREAD_VM_STACK_SIZE=15700000 ruby ~/lux/stdlib/target/program.rb -``` - ---- - # PHP compiler ## Test @@ -251,12 +14,6 @@ cd ~/lux/lux-php/ && lein clean && lein lux auto test cd ~/lux/lux-php/ \ && lein clean \ && lein lux auto build - -## Build JVM-based compiler -cd ~/lux/lux-php/ \ -&& lein clean \ -&& lein lux build \ -&& mv target/program.jar jvm_based_compiler.jar ``` ## Try @@ -265,7 +22,7 @@ cd ~/lux/lux-php/ \ ## Compile Lux's Standard Library's tests using a JVM-based compiler. cd ~/lux/stdlib/ \ && lein clean \ -&& time java -jar ~/lux/lux-php/jvm_based_compiler.jar build --source ~/lux/stdlib/source --target ~/lux/stdlib/target --module test/lux +&& time java -jar ~/lux/lux-php/target/program.jar build --source ~/lux/stdlib/source --target ~/lux/stdlib/target --module test/lux ``` --- diff --git a/lux-js/commands.md b/lux-js/commands.md new file mode 100644 index 000000000..ff0124850 --- /dev/null +++ b/lux-js/commands.md @@ -0,0 +1,45 @@ +# JavaScript compiler + +## Test + +``` +cd ~/lux/lux-js/ && lein lux auto test +cd ~/lux/lux-js/ && lein clean && lein lux auto test +``` + +## Build + +``` +cd ~/lux/lux-js/ && lein lux auto build +cd ~/lux/lux-js/ && lein clean && lein lux auto build + +## Build JVM-based compiler +cd ~/lux/lux-js/ \ +&& lein clean \ +&& lein lux build \ +&& mv target/program.jar jvm_based_compiler.jar + +## Use JVM-based compiler to produce a JS/Node-based compiler. +cd ~/lux/lux-js/ \ +&& lein clean \ +&& time java -jar jvm_based_compiler.jar build --source ~/lux/lux-js/source --target ~/lux/lux-js/target --module program \ +&& mv target/program.js node_based_compiler.js + +## Use JS/Node-based compiler to produce another JS/Node-based compiler. +cd ~/lux/lux-js/ \ +&& lein clean \ +&& time node --stack_size=8192 node_based_compiler.js build --source ~/lux/lux-js/source --target ~/lux/lux-js/target --module program \ +&& mv target/program.js lux.js +``` + +## Try + +``` +## Compile Lux's Standard Library's tests using a JS/Node-based compiler. +cd ~/lux/stdlib/ \ +&& lein clean \ +&& time node --stack_size=8192 ~/lux/lux-js/lux.js build --source ~/lux/stdlib/source --target ~/lux/stdlib/target --module test/lux + +node ~/lux/stdlib/target/program.js +``` + diff --git a/lux-jvm/commands.md b/lux-jvm/commands.md new file mode 100644 index 000000000..fbfba67ac --- /dev/null +++ b/lux-jvm/commands.md @@ -0,0 +1,60 @@ +# JVM compiler + +## Test + +``` +cd ~/lux/lux-jvm/ && lein lux auto test +cd ~/lux/lux-jvm/ && lein clean && lein lux auto test +``` + +## Build + +``` +cd ~/lux/lux-jvm/ && lein lux auto build + +## Use bootstrapping compiler to build new JVM compiler +cd ~/lux/lux-jvm/ \ +&& lein clean \ +&& lein lux auto build +``` + +## REPL + +``` +cd ~/lux/lux-jvm/ && java -jar target/program.jar repl --source ~/lux/stdlib/source --target ~/lux/stdlib/target +``` + +## Try + +``` +cd ~/lux/lux-jvm/ && time java -jar target/program.jar build --source ~/lux/stdlib/source --target ~/lux/stdlib/target --module test/lux +cd ~/lux/lux-jvm/ && java -jar target/program.jar export --source ~/lux/stdlib/source --target ~/lux/stdlib/target + +cd ~/lux/stdlib/ \ +&& cd ~/lux/lux-jvm/ \ +&& time java -jar target/program.jar build --source ~/lux/stdlib/source --library ~/lux/stdlib/target/library.tar --target ~/lux/stdlib/target --module test/lux + +## Use new JVM compiler to compile tests for the Standard Library +cd ~/lux/stdlib/ \ +&& lein clean \ +&& time java -jar ~/lux/lux-jvm/target/program.jar build --source ~/lux/stdlib/source --target ~/lux/stdlib/target --module test/lux + +## Run tests for the Standard Library +cd ~/lux/stdlib/target/ \ +&& java -jar program.jar +``` + +## Deploy + +``` +cd ~/lux/lux-jvm/ && mvn install:install-file -Dfile=target/program.jar -DgroupId=com.github.luxlang -DartifactId=lux-jvm -Dversion=0.6.0-SNAPSHOT -Dpackaging=jar + +cd ~/lux/lux-jvm/ && mvn deploy:deploy-file \ +-Durl=https://:@oss.sonatype.org/content/repositories/snapshots/ \ +-Dfile=target/program.jar \ +-DgroupId=com.github.luxlang \ +-DartifactId=lux-jvm \ +-Dversion=0.6.0-SNAPSHOT \ +-Dpackaging=jar +``` + diff --git a/lux-lua/commands.md b/lux-lua/commands.md new file mode 100644 index 000000000..3693fecec --- /dev/null +++ b/lux-lua/commands.md @@ -0,0 +1,36 @@ +# Lua compiler + +## Test + +``` +cd ~/lux/lux-lua/ && lein lux auto test +cd ~/lux/lux-lua/ && lein clean && lein lux auto test +``` + +## Build + +``` +## Develop +cd ~/lux/lux-lua/ \ +&& lein clean \ +&& lein lux auto build + +## Build JVM-based compiler +## NOTE: Must set lux/control/concurrency/thread.parallelism = 1 before compiling to make sure Rembulan doesn't cause trouble. +cd ~/lux/lux-lua/ \ +&& lein clean \ +&& lein lux build \ +&& mv target/program.jar jvm_based_compiler.jar +``` + +## Try + +``` +## Compile Lux's Standard Library's tests using a JVM-based compiler. +cd ~/lux/stdlib/ \ +&& lein clean \ +&& time java -jar ~/lux/lux-lua/jvm_based_compiler.jar build --source ~/lux/stdlib/source --target ~/lux/stdlib/target --module test/lux + +~/lua-5.4.2/install/bin/lua ~/lux/stdlib/target/program.lua +``` + diff --git a/lux-php/project.clj b/lux-php/project.clj index 24d36cfa6..ff248abb9 100644 --- a/lux-php/project.clj +++ b/lux-php/project.clj @@ -3,6 +3,8 @@ (def sonatype-releases "https://oss.sonatype.org/service/local/staging/deploy/maven2/") (def sonatype-snapshots "https://oss.sonatype.org/content/repositories/snapshots/") +(def jphp-version "0.9.2") + (defproject com.github.luxlang/lux-php #=(identity version) :description "A PHP compiler for Lux." :url ~repo @@ -24,8 +26,8 @@ :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"]] + [org.develnext.jphp/jphp-core ~jphp-version] + [org.develnext.jphp/jphp-scripting ~jphp-version]] :manifest {"lux" ~version} :source-paths ["source"] diff --git a/lux-php/source/program.lux b/lux-php/source/program.lux index ae41496a2..29fadec16 100644 --- a/lux-php/source/program.lux +++ b/lux-php/source/program.lux @@ -6,6 +6,7 @@ [abstract ["." monad (#+ do)]] [control + [pipe (#+ exec> case>)] ["." try (#+ Try)] ["." exception (#+ exception:)] ["." io (#+ IO io)] @@ -64,7 +65,17 @@ (host.import: java/lang/String) -(host.import: (java/lang/Class a)) +(host.import: java/lang/reflect/Field + ["#::." + (get [java/lang/Object] java/lang/Object)]) + +(host.import: java/lang/reflect/AccessibleObject + ["#::." + (setAccessible [boolean] void)]) + +(host.import: (java/lang/Class a) + ["#::." + (getDeclaredField [java/lang/String] java/lang/reflect/Field)]) (host.import: java/lang/Object ["#::." @@ -77,24 +88,37 @@ ["#::." (intValue [] java/lang/Integer)]) -(host.import: php/runtime/Memory) +(host.import: php/runtime/Memory + ["#::." + (valueOfIndex #as generic_valueOfIndex [php/runtime/env/TraceInfo php/runtime/Memory] php/runtime/Memory) + (valueOfIndex #as long_valueOfIndex [php/runtime/env/TraceInfo long] php/runtime/Memory) + (valueOfIndex #as string_valueOfIndex [php/runtime/env/TraceInfo java/lang/String] php/runtime/Memory)]) (host.import: php/runtime/Memory$Type ["#::." (#enum ARRAY)]) -(host.import: php/runtime/memory/NullMemory) +(host.import: php/runtime/memory/NullMemory + ["#::." + (#static INSTANCE php/runtime/memory/NullMemory)]) -(host.import: php/runtime/memory/FalseMemory) -(host.import: php/runtime/memory/TrueMemory) +(host.import: php/runtime/memory/FalseMemory + ["#::." + (#static INSTANCE php/runtime/memory/FalseMemory)]) + +(host.import: php/runtime/memory/TrueMemory + ["#::." + (#static INSTANCE php/runtime/memory/TrueMemory)]) (host.import: php/runtime/memory/LongMemory ["#::." (new [long]) - (toLong [] long)]) + (toLong [] long) + (#static valueOf #manual [int] php/runtime/Memory)]) (host.import: php/runtime/memory/DoubleMemory ["#::." + (new [double]) (toDouble [] double)]) (host.import: php/runtime/memory/StringMemory @@ -111,7 +135,7 @@ (new [[java/lang/Object]]) (size [] int) (isMap [] boolean) - (get [php/runtime/Memory] php/runtime/Memory)]) + (get [php/runtime/Memory] #? php/runtime/Memory)]) (host.import: php/runtime/lang/IObject) @@ -119,9 +143,7 @@ ["#::." (value php/runtime/lang/IObject)]) -(host.import: php/runtime/env/Environment - ["#::." - (#static current [] php/runtime/env/Environment)]) +(host.import: php/runtime/env/Environment) (host.import: php/runtime/env/TraceInfo ["#::." @@ -157,145 +179,205 @@ ["Class" (java/lang/Object::toString (java/lang/Object::getClass object))] ["Object" (java/lang/Object::toString object)])) +(def: (value_wrapper lux_structure value) + (-> (-> (Array java/lang/Object) php/runtime/Memory) java/lang/Object php/runtime/Memory) + (<| (if (host.null? value) + (php/runtime/memory/NullMemory::INSTANCE)) + (case (host.check java/lang/Boolean value) + (#.Some value) + (if (:coerce Bit value) + (php/runtime/memory/TrueMemory::INSTANCE) + (php/runtime/memory/FalseMemory::INSTANCE)) + + #.None) + (case (host.check java/lang/Long value) + (#.Some value) + (php/runtime/memory/LongMemory::new value) + + #.None) + (case (host.check java/lang/Double value) + (#.Some value) + (php/runtime/memory/DoubleMemory::new value) + + #.None) + (case (host.check java/lang/String value) + (#.Some value) + (php/runtime/memory/StringMemory::new value) + + #.None) + (case (host.check [java/lang/Object] value) + (#.Some value) + (lux_structure (:coerce (Array java/lang/Object) value)) + + #.None) + (case (host.check php/runtime/memory/ObjectMemory value) + (#.Some value) + value + + #.None) + (undefined) + )) + +(def: unit + (php/runtime/memory/StringMemory::new "")) + (def: (lux_structure value) (-> (Array java/lang/Object) - php/runtime/memory/ArrayMemory - ## php/runtime/Memory + ## php/runtime/memory/ArrayMemory + php/runtime/Memory ) - (`` (host.object [] ## php/runtime/Memory - php/runtime/memory/ArrayMemory + (`` (host.object [] php/runtime/Memory + ## php/runtime/memory/ArrayMemory [program/StructureValue] - [## {php/runtime/Memory$Type php/runtime/Memory$Type::ARRAY} - ] + [{php/runtime/Memory$Type php/runtime/Memory$Type::ARRAY}] ## Methods (program/StructureValue [] (getValue self) java/lang/Object (:assume value)) - (php/runtime/memory/ArrayMemory - [] (size self) - int - (exec - (debug.log! "{lux_structure#size}") - (:assume (array.size value)))) - - (php/runtime/memory/ArrayMemory - [] (get self {key php/runtime/Memory}) - php/runtime/Memory - (exec - (debug.log! (format "{lux_structure#get}" text.new_line - (exception.construct unknown_kind_of_object key))) - (error! "OOPS!"))) - - (php/runtime/memory/ArrayMemory - [] (getOrCreate self {key php/runtime/Memory}) - php/runtime/memory/ReferenceMemory - (exec - (debug.log! (format "{lux_structure#getOrCreate}" text.new_line - (exception.construct unknown_kind_of_object key))) - (error! "OOPS!"))) - - (php/runtime/memory/ArrayMemory - [] (getOrCreateAsShortcut self {key php/runtime/Memory}) - php/runtime/memory/ReferenceMemory - (exec - (debug.log! (format "{lux_structure#getOrCreateAsShortcut}" text.new_line - (exception.construct unknown_kind_of_object key))) - (error! "OOPS!"))) - - (php/runtime/memory/ArrayMemory - [] (getByScalarOrCreateAsShortcut self {key java/lang/Object}) - php/runtime/memory/ReferenceMemory - (exec - (debug.log! (format "{lux_structure#getByScalarOrCreateAsShortcut}" text.new_line - (exception.construct unknown_kind_of_object key))) - (error! "OOPS!"))) - - (php/runtime/memory/ArrayMemory - [] (getByScalarOrCreate self {key java/lang/Object}) - php/runtime/memory/ReferenceMemory - (exec - (debug.log! (format "{lux_structure#getByScalarOrCreate}" text.new_line - (exception.construct unknown_kind_of_object key))) - (error! "OOPS!"))) - - (php/runtime/memory/ArrayMemory - [] (getByScalar self {key java/lang/Object}) - php/runtime/memory/ReferenceMemory - (exec - (debug.log! (format "{lux_structure#getByScalar}" text.new_line - (exception.construct unknown_kind_of_object key))) - (error! "OOPS!"))) + (php/runtime/Memory + [] (toString self) + java/lang/String + (debug.inspect value)) - ## (php/runtime/Memory - ## [] (refOfIndex self - ## {trace php/runtime/env/TraceInfo} - ## {index php/runtime/Memory}) + ## (php/runtime/memory/ArrayMemory + ## [] (get self {key php/runtime/Memory}) ## php/runtime/Memory ## (exec - ## (log! (format "{lux_structure#refOfIndex}" text.new_line - ## (exception.construct unknown_kind_of_object index))) + ## (debug.log! (format "{lux_structure#get}" text.new_line + ## (exception.construct ..unknown_kind_of_object key))) ## (error! "OOPS!"))) - ## (php/runtime/Memory - ## [] (refOfIndexAsShortcut self - ## {trace php/runtime/env/TraceInfo} - ## {index php/runtime/Memory}) - ## php/runtime/Memory + ## (php/runtime/memory/ArrayMemory + ## [] (getOrCreate self {key php/runtime/Memory}) + ## php/runtime/memory/ReferenceMemory ## (exec - ## (log! (format "{lux_structure#refOfIndexAsShortcut}" text.new_line - ## (exception.construct unknown_kind_of_object index))) + ## (debug.log! (format "{lux_structure#getOrCreate}" text.new_line + ## (exception.construct ..unknown_kind_of_object key))) ## (error! "OOPS!"))) - ## (php/runtime/Memory - ## [] (refOfIndex self - ## {trace php/runtime/env/TraceInfo} - ## {index long}) - ## php/runtime/Memory + ## (php/runtime/memory/ArrayMemory + ## [] (getOrCreateAsShortcut self {key php/runtime/Memory}) + ## php/runtime/memory/ReferenceMemory ## (exec - ## (log! (format "{lux_structure#refOfIndex long}" text.new_line - ## (exception.construct unknown_kind_of_object index))) + ## (debug.log! (format "{lux_structure#getOrCreateAsShortcut}" text.new_line + ## (exception.construct ..unknown_kind_of_object key))) ## (error! "OOPS!"))) - ## (php/runtime/Memory - ## [] (refOfIndex self - ## {trace php/runtime/env/TraceInfo} - ## {index java/lang/String}) - ## php/runtime/Memory + ## (php/runtime/memory/ArrayMemory + ## [] (getByScalarOrCreateAsShortcut self {key java/lang/Object}) + ## php/runtime/memory/ReferenceMemory ## (exec - ## (log! (format "{lux_structure#refOfIndex java/lang/String}" text.new_line - ## (exception.construct unknown_kind_of_object index))) + ## (debug.log! (format "{lux_structure#getByScalarOrCreateAsShortcut}" text.new_line + ## (exception.construct ..unknown_kind_of_object key))) ## (error! "OOPS!"))) - ## (~~ (template [] - ## [(php/runtime/Memory [] ( self) php/runtime/Memory (undefined))] + ## (php/runtime/memory/ArrayMemory + ## [] (getByScalarOrCreate self {key java/lang/Object}) + ## php/runtime/memory/ReferenceMemory + ## (exec + ## (debug.log! (format "{lux_structure#getByScalarOrCreate}" text.new_line + ## (exception.construct ..unknown_kind_of_object key))) + ## (error! "OOPS!"))) - ## [inc] [dec] [negative] [toNumeric] - ## )) + ## (php/runtime/memory/ArrayMemory + ## [] (getByScalar self {key java/lang/Object}) + ## php/runtime/memory/ReferenceMemory + ## (exec + ## (debug.log! (format "{lux_structure#getByScalar}" text.new_line + ## (exception.construct ..unknown_kind_of_object key))) + ## (error! "OOPS!"))) - ## (~~ (template [] - ## [(php/runtime/Memory [] ( self {other php/runtime/Memory}) php/runtime/Memory (undefined))] + (php/runtime/Memory + [] (valueOfIndex self + {trace php/runtime/env/TraceInfo} + {index php/runtime/Memory}) + php/runtime/Memory + (`` (<| (~~ (template [ ] + [(case (host.check index) + (#.Some index) + ( trace ( index) self) + + #.None)] + + [php/runtime/memory/ReferenceMemory + php/runtime/Memory::generic_valueOfIndex + php/runtime/memory/ReferenceMemory::getValue] + [php/runtime/memory/LongMemory + php/runtime/Memory::long_valueOfIndex + php/runtime/memory/LongMemory::toLong] + [php/runtime/memory/StringMemory + php/runtime/Memory::string_valueOfIndex + php/runtime/memory/StringMemory::toString] + )) + (undefined)))) - ## [plus] [minus] [mul] [pow] [div] - ## [identical] [equal] [notEqual] - ## [smaller] [smallerEq] [greater] [greaterEq] - ## )) + ## (php/runtime/Memory + ## [] (valueOfIndexAsShortcut self + ## {trace php/runtime/env/TraceInfo} + ## {index php/runtime/Memory}) + ## php/runtime/Memory + ## (exec + ## (debug.log! (format "{lux_structure#valueOfIndexAsShortcut}" text.new_line + ## (exception.construct ..unknown_kind_of_object index))) + ## (error! "OOPS!"))) - ## (php/runtime/Memory [] (toLong self) long (undefined)) - ## (php/runtime/Memory [] (toDouble self) double (undefined)) - ## (php/runtime/Memory [] (toBoolean self) boolean (undefined)) - ## (php/runtime/Memory [] (toString self) java/lang/String (undefined)) - ## (php/runtime/Memory [] (getBinaryBytes self {input java/nio/charset/Charset}) ByteArray (undefined)) + (php/runtime/Memory + [] (valueOfIndex self + {trace php/runtime/env/TraceInfo} + {index long}) + php/runtime/Memory + (|> value + (array.read index) + maybe.assume + (..value_wrapper lux_structure))) + + (php/runtime/Memory + [] (valueOfIndex self + {trace php/runtime/env/TraceInfo} + {index java/lang/String}) + php/runtime/Memory + (case (:coerce Text index) + (^ (static runtime.variant_tag_field)) + (|> value + (array.read 0) + maybe.assume + (:coerce java/lang/Integer) + php/runtime/memory/LongMemory::valueOf) + + (^ (static runtime.variant_flag_field)) + (case (array.read 1 value) + #.None + (php/runtime/memory/NullMemory::INSTANCE) + + (#.Some value) + ..unit) + + (^ (static runtime.variant_value_field)) + (|> value + (array.read 2) + maybe.assume + (..value_wrapper lux_structure)) + + (^ (static runtime.tuple_size_field)) + (php/runtime/memory/LongMemory::new (array.size value)) + + _ + (undefined))) ))) (def: (read_tuple read host_object) (-> Reader php/runtime/memory/ArrayMemory (Try Any)) - (let [size (:coerce Nat (php/runtime/memory/ArrayMemory::size host_object))] + (let [size (|> host_object + php/runtime/memory/ArrayMemory::size + (:coerce Nat) + dec)] (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))) + maybe.assume (:coerce php/runtime/memory/ReferenceMemory) php/runtime/memory/ReferenceMemory::getValue)] (case (host.check php/runtime/memory/NullMemory value) @@ -304,26 +386,38 @@ #.None (case (read value) - (#try.Failure error) - (#try.Failure error) - (#try.Success lux_value) - (recur (inc idx) (array.write! idx lux_value output))))) + (recur (inc idx) (array.write! idx lux_value output)) + + error + error))) (#try.Success output))))) +(def: variant_tag_field + (php/runtime/memory/StringMemory::new runtime.variant_tag_field)) + +(def: variant_value_field + (php/runtime/memory/StringMemory::new runtime.variant_value_field)) + +(def: variant_flag_field + (php/runtime/memory/StringMemory::new runtime.variant_flag_field)) + (def: (read_variant read host_object) (-> Reader php/runtime/memory/ArrayMemory (Try Any)) (case [(|> host_object - (php/runtime/memory/ArrayMemory::get (php/runtime/memory/StringMemory::new runtime.variant_tag_field)) + (php/runtime/memory/ArrayMemory::get ..variant_tag_field) + maybe.assume read) (|> host_object - (php/runtime/memory/ArrayMemory::get (php/runtime/memory/StringMemory::new runtime.variant_value_field)) + (php/runtime/memory/ArrayMemory::get ..variant_value_field) + maybe.assume read)] [(#try.Success tag) (#try.Success value)] (#try.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)) + (php/runtime/memory/ArrayMemory::get ..variant_flag_field) + maybe.assume (:coerce php/runtime/memory/ReferenceMemory) php/runtime/memory/ReferenceMemory::getValue (host.check php/runtime/memory/NullMemory)) @@ -339,6 +433,9 @@ (exception: #export nulll_has_no_lux_representation) +(def: tuple_size_field + (php/runtime/memory/StringMemory::new runtime.tuple_size_field)) + (def: (read host_object) Reader (`` (<| (~~ (template [ ] @@ -358,6 +455,7 @@ #.None)] + [program/StructureValue [program/StructureValue::getValue #try.Success]] [php/runtime/memory/LongMemory [php/runtime/memory/LongMemory::toLong #try.Success]] [php/runtime/memory/DoubleMemory [php/runtime/memory/DoubleMemory::toDouble #try.Success]] [php/runtime/memory/StringMemory [php/runtime/memory/StringMemory::toString #try.Success]] @@ -366,7 +464,9 @@ )) (case (host.check php/runtime/memory/ArrayMemory host_object) (#.Some value) - (if (php/runtime/memory/ArrayMemory::isMap value) + (if (|> value + (php/runtime/memory/ArrayMemory::get ..tuple_size_field) + (case> (#.Some _) false #.None true)) (read_variant read value) (read_tuple read value)) @@ -401,41 +501,29 @@ (:coerce java/lang/Object) (host.check php/runtime/memory/ObjectMemory))) +(def: interpreter + (org/develnext/jphp/scripting/JPHPScriptEngine::new)) + +(def: default_environment + php/runtime/env/Environment + (|> ..interpreter + java/lang/Object::getClass + (java/lang/Class::getDeclaredField "environment") + (exec> [(java/lang/reflect/AccessibleObject::setAccessible true)]) + (java/lang/reflect/Field::get ..interpreter) + (:coerce php/runtime/env/Environment))) + (def: (call_macro inputs lux macro) - (-> (List Code) Lux - php/runtime/memory/ObjectMemory - ## php/runtime/lang/Closure - (Try (Try [Lux (List Code)]))) + (-> (List Code) Lux php/runtime/memory/ObjectMemory (Try (Try [Lux (List Code)]))) (<| :assume (do try.monad - [#let [_ (debug.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) + [output (php/runtime/lang/Closure::call ..default_environment (|> (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)) - )) + (host.array_write 1 (lux_structure (:coerce (Array java/lang/Object) inputs))) + (host.array_write 2 (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 [_ (debug.log! (format "{call_macro 1} " (debug.inspect output))) - _ (debug.log! (format "{call_macro 2} " (exception.construct ..unknown_kind_of_object (:coerce java/lang/Object output))))]] + (php/runtime/memory/ObjectMemory::value macro)))] (..read (:coerce java/lang/Object output))))) (def: (expander macro inputs lux) @@ -447,28 +535,37 @@ #.None (exception.throw ..cannot_apply_a_non_function (:coerce java/lang/Object macro)))) -(def: separator "___") - (def: host (IO (Host _.Expression _.Statement)) - (io (let [interpreter (org/develnext/jphp/scripting/JPHPScriptEngine::new) - run! (: (-> (_.Code Any) (Try Any)) - (function (_ code) + (io (let [run! (: (-> (_.Code Any) (Try Any)) + (function (recur code) (do try.monad - [output (javax/script/ScriptEngine::eval (format " Any php/runtime/Memory) (|>> (:coerce (Array java/lang/Object)) lux_structure (:coerce php/runtime/Memory)))] - output (php/runtime/lang/Closure::call (php/runtime/env/Environment::current) + output (php/runtime/lang/Closure::call ..default_environment (|> (host.array php/runtime/Memory 6) (host.array_write 0 handler) (host.array_write 1 (php/runtime/memory/StringMemory::new name)) @@ -548,13 +645,6 @@ (_.; (_.apply/* (list) @program)) ))) -## (program: [{service /cli.service}] -## (/.compiler ..expander -## ..platform -## extension.bundle -## ..program -## service)) - (`` (program: [{service /cli.service}] (let [extension ".php"] (do io.monad @@ -570,7 +660,7 @@ generation.bundle extension/bundle.empty ..program - [_.Var _.Expression _.Statement] + [_.Location _.Expression _.Statement] ..extender service [(packager.package (_.manual "") diff --git a/lux-python/commands.md b/lux-python/commands.md new file mode 100644 index 000000000..e01901d6c --- /dev/null +++ b/lux-python/commands.md @@ -0,0 +1,35 @@ +# Python compiler + +## Test + +``` +cd ~/lux/lux-python/ && lein lux auto test +cd ~/lux/lux-python/ && lein clean && lein lux auto test +``` + +## Build + +``` +## Develop +cd ~/lux/lux-python/ \ +&& lein clean \ +&& lein lux auto build + +## Build JVM-based compiler +cd ~/lux/lux-python/ \ +&& lein clean \ +&& lein lux build \ +&& mv target/program.jar jvm_based_compiler.jar +``` + +## Try + +``` +## Compile Lux's Standard Library's tests using a JVM-based compiler. +cd ~/lux/stdlib/ \ +&& lein clean \ +&& time java -jar ~/lux/lux-python/jvm_based_compiler.jar build --source ~/lux/stdlib/source --target ~/lux/stdlib/target --module test/lux + +python3 ~/lux/stdlib/target/program.py +``` + diff --git a/lux-ruby/commands.md b/lux-ruby/commands.md new file mode 100644 index 000000000..957640abb --- /dev/null +++ b/lux-ruby/commands.md @@ -0,0 +1,35 @@ +# Ruby compiler + +## Test + +``` +cd ~/lux/lux-ruby/ && lein lux auto test +cd ~/lux/lux-ruby/ && lein clean && lein lux auto test +``` + +## Build + +``` +## Develop +cd ~/lux/lux-ruby/ \ +&& lein clean \ +&& lein lux auto build + +## Build JVM-based compiler +cd ~/lux/lux-ruby/ \ +&& lein clean \ +&& lein lux build \ +&& mv target/program.jar jvm_based_compiler.jar +``` + +## Try + +``` +## Compile Lux's Standard Library's tests using a JVM-based compiler. +cd ~/lux/stdlib/ \ +&& lein clean \ +&& time java -jar ~/lux/lux-ruby/target/program.jar build --source ~/lux/stdlib/source --target ~/lux/stdlib/target --module test/lux + +RUBY_THREAD_VM_STACK_SIZE=15700000 ruby ~/lux/stdlib/target/program.rb +``` + diff --git a/stdlib/source/lux.lux b/stdlib/source/lux.lux index 1bb7efa07..b2deead45 100644 --- a/stdlib/source/lux.lux +++ b/stdlib/source/lux.lux @@ -1559,7 +1559,7 @@ ({(#Left msg) (#Left msg) - (#Right state' a) + (#Right [state' a]) (f a state')} (ma state))))}) @@ -2205,7 +2205,7 @@ 1 "1" 2 "2" 3 "3" 4 "4" 5 "5" 6 "6" 7 "7" 8 "8" 9 "9" - _ ("lux io error" "undefined")} + _ ("lux io error" "@digit::format Undefined behavior.")} digit)) (def:''' (nat\encode value) @@ -2700,7 +2700,7 @@ (int\encode value) [_ (#Rev value)] - ("lux io error" "Undefined behavior.") + ("lux io error" "@code\encode Undefined behavior.") [_ (#Frac value)] (frac\encode value) @@ -4943,7 +4943,7 @@ [#Record "{" "}" rejoin_all_pairs]) [new_location (#Rev value)] - ("lux io error" "Undefined behavior.") + ("lux io error" "@doc_example->Text Undefined behavior.") )) (def: (with_baseline baseline [file line column]) @@ -5510,6 +5510,12 @@ _ (fail (..wrong_syntax_error (name_of ..:assume))))) +(def: location + {#.doc "The location of the current expression being analyzed."} + (Meta Location) + (function (_ compiler) + (#Right [compiler (get@ #location compiler)]))) + (macro: #export (undefined tokens) {#.doc (doc "Meant to be used as a stand-in for functions with undefined implementations." "Undefined expressions will type-check against everything, so they make good dummy implementations." @@ -5519,7 +5525,12 @@ (undefined)))} (case tokens #Nil - (return (list (` (..error! "Undefined behavior.")))) + (do meta_monad + [location ..location + #let [[module line column] location + location ($_ "lux text concat" (text\encode module) "," (nat\encode line) "," (nat\encode column)) + message ($_ "lux text concat" "Undefined behavior @ " location)]] + (wrap (list (` (..error! (~ (text$ message))))))) _ (fail (..wrong_syntax_error (name_of ..undefined))))) diff --git a/stdlib/source/lux/target/php.lux b/stdlib/source/lux/target/php.lux index 4cb2f0602..1b1b91e88 100644 --- a/stdlib/source/lux/target/php.lux +++ b/stdlib/source/lux/target/php.lux @@ -2,17 +2,26 @@ [lux (#- Location Code Global static int if cond or and not comment for) ["@" target] ["." host] + [abstract + [equivalence (#+ Equivalence)] + [hash (#+ Hash)] + ["." enum]] [control - [pipe (#+ case> cond> new>)]] + [pipe (#+ case> cond> new>)] + [parser + ["<.>" code]]] [data ["." text ["%" format (#+ format)]] [collection ["." list ("#\." functor fold)]]] [macro - ["." template]] + [syntax (#+ syntax:)] + ["." template] + ["." code]] [math [number + ["n" nat] ["f" frac]]] [type abstract]]) @@ -47,6 +56,18 @@ (abstract: #export (Code brand) Text + (structure: #export equivalence + (All [brand] (Equivalence (Code brand))) + + (def: (= reference subject) + (\ text.equivalence = (:representation reference) (:representation subject)))) + + (structure: #export hash + (All [brand] (Hash (Code brand))) + + (def: &equivalence ..equivalence) + (def: hash (|>> :representation (\ text.hash hash)))) + (def: #export manual (-> Text Code) (|>> :abstraction)) @@ -154,8 +175,13 @@ (def: #export (apply/* args func) (-> (List Expression) Expression Computation) - (:abstraction - (format (:representation func) (..arguments args)))) + (|> (format (:representation func) (..arguments args)) + :abstraction)) + + ## TODO: Remove when no longer using JPHP. + (def: #export (apply/*' args func) + (-> (List Expression) Expression Computation) + (apply/* (list& func args) (..constant "call_user_func"))) (def: parameters (-> (List Argument) Text) @@ -189,47 +215,72 @@ ..group :abstraction))) - (template [ + + +] - [(`` (def: #export ( [(~~ (template.splice +))] function) - (-> [(~~ (template.splice +))] Expression Computation) - (..apply/* (list (~~ (template.splice +))) function))) - - (`` (template [ ] - [(def: #export ( args) - (-> [(~~ (template.splice +))] Computation) - ( args (..constant )))] - - (~~ (template.splice +))))] - - [apply/0 [] [] - [[func_num_args/0 "func_num_args"] - [func_get_args/0 "func_get_args"] - [time/0 "time"]]] - [apply/1 [in0] [Expression] - [[is_null/1 "is_null"] - [empty/1 "empty"] - [count/1 "count"] - [strlen/1 "strlen"] - [array_pop/1 "array_pop"] - [array_reverse/1 "array_reverse"] - [intval/1 "intval"] - [floatval/1 "floatval"] - [strval/1 "strval"] - [ord/1 "ord"] - [chr/1 "chr"] - [print/1 "print"] - [exit/1 "exit"]]] - [apply/2 [in0 in1] [Expression Expression] - [[call_user_func_array/2 "call_user_func_array"] - [array_slice/2 "array_slice"] - [array_push/2 "array_push"]]] - [apply/3 [in0 in1 in2] [Expression Expression Expression] - [[array_slice/3 "array_slice"] - [array_splice/3 "array_splice"] - [strpos/3 "strpos"] - [substr/3 "substr"]]] + (syntax: (arity_inputs {arity .nat}) + (wrap (case arity + 0 (.list) + _ (|> (dec arity) + (enum.range n.enum 0) + (list\map (|>> %.nat code.local_identifier)))))) + + (syntax: (arity_types {arity .nat}) + (wrap (list.repeat arity (` ..Expression)))) + + (template [ +] + [(with_expansions [ (template.identifier ["apply/" ]) + (arity_inputs ) + (arity_types ) + (template.splice +)] + (def: #export ( function []) + (-> Expression [] Computation) + (..apply/* (.list ) function)) + + (template [] + [(`` (def: #export (~~ (template.identifier [ "/" ])) + ( (..constant ))))] + + ))] + + [0 + [["func_num_args"] + ["func_get_args"] + ["time"] + ["phpversion"]]] + + [1 + [["is_null"] + ["empty"] + ["count"] + ["array_pop"] + ["array_reverse"] + ["intval"] + ["floatval"] + ["strval"] + ["ord"] + ["chr"] + ["print"] + ["exit"] + ["iconv_strlen"] ["strlen"]]] + + [2 + [["call_user_func_array"] + ["array_slice"] + ["array_push"] + ["pack"] + ["unpack"] + ["iconv_strpos"] ["strpos"]]] + + [3 + [["array_slice"] + ["array_splice"] + ["iconv"] + ["iconv_strpos"] ["strpos"] + ["iconv_substr"] ["substr"]]] ) + (def: #export (key_value key value) + (-> Expression Expression Expression) + (:abstraction (format (:representation key) " => " (:representation value)))) + (def: #export (array/* values) (-> (List Expression) Literal) (|> values @@ -274,9 +325,9 @@ (def: #export (? test then else) (-> Expression Expression Expression Computation) - (|> (format (:representation test) " ? " - (:representation then) " : " - (:representation else)) + (|> (format (..group (:representation test)) " ? " + (..group (:representation then)) " : " + (..group (:representation else))) ..group :abstraction)) @@ -343,7 +394,7 @@ (def: #export (if test then! else!) (-> Expression Statement Statement Statement) (:abstraction - (format "if " (..group (:representation test)) " " + (format "if" (..group (:representation test)) " " (..block (:representation then!)) " else " (..block (:representation else!))))) @@ -351,7 +402,7 @@ (def: #export (when test then!) (-> Expression Statement Statement) (:abstraction - (format "if " (..group (:representation test)) " " + (format "if" (..group (:representation test)) " " (..block (:representation then!))))) (def: #export (then pre! post!) @@ -364,14 +415,14 @@ (def: #export (while test body!) (-> Expression Statement Statement) (:abstraction - (format "while " (..group (:representation test)) " " + (format "while" (..group (:representation test)) " " (..block (:representation body!))))) (def: #export (do_while test body!) (-> Expression Statement Statement) (:abstraction (format "do " (..block (:representation body!)) - " while " (..group (:representation test)) + " while" (..group (:representation test)) ..statement_suffix))) (def: #export (for_each array value body!) @@ -414,15 +465,15 @@ (def: #export (define name value) (-> Constant Expression Expression) - (..apply/2 [(|> name :representation ..string) - value] - (..constant "define"))) + (..apply/2 (..constant "define") + [(|> name :representation ..string) + value])) (def: #export (define_function name arguments body!) (-> Constant (List Argument) Statement Statement) (:abstraction (format "function " (:representation name) - " " (..parameters arguments) + (..parameters arguments) " " (..block (:representation body!))))) diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/extension/generation/php/common.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/extension/generation/php/common.lux index ab2f480fe..572f1f2a8 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/extension/generation/php/common.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/extension/generation/php/common.lux @@ -47,8 +47,8 @@ (#try.Failure error) (/////.throw extension.invalid_syntax [extension_name %synthesis input])))) -## (template: (!unary function) -## (|>> list _.apply/* (|> (_.var function)))) +(template: (!unary function) + (|>> list _.apply/* (|> (_.constant function)))) ## ## TODO: Get rid of this ASAP ## (def: lux::syntax_char_case! @@ -83,103 +83,98 @@ ## conditionalsG))]] ## (wrap (_.apply/1 closure inputG))))])) -## (def: lux_procs -## Bundle -## (|> /.empty -## (/.install "syntax char case!" lux::syntax_char_case!) -## (/.install "is" (binary (product.uncurry _.=))) -## (/.install "try" (unary //runtime.lux//try)))) +(def: lux_procs + Bundle + (|> /.empty + ## (/.install "syntax char case!" lux::syntax_char_case!) + (/.install "is" (binary (product.uncurry _.=))) + ## (/.install "try" (unary //runtime.lux//try)) + )) -## (def: i64_procs -## Bundle -## (<| (/.prefix "i64") -## (|> /.empty -## (/.install "and" (binary (product.uncurry _.bit_and))) -## (/.install "or" (binary (product.uncurry _.bit_or))) -## (/.install "xor" (binary (product.uncurry _.bit_xor))) -## (/.install "left-shift" (binary (product.uncurry //runtime.i64//left_shift))) -## (/.install "right-shift" (binary (product.uncurry //runtime.i64//right_shift))) -## (/.install "=" (binary (product.uncurry _.=))) -## (/.install "+" (binary (product.uncurry _.+))) -## (/.install "-" (binary (product.uncurry _.-))) -## (/.install "<" (binary (product.uncurry _.<))) -## (/.install "*" (binary (product.uncurry _.*))) -## (/.install "/" (binary (product.uncurry //runtime.i64//division))) -## (/.install "%" (binary (product.uncurry //runtime.i64//remainder))) -## (/.install "f64" (unary (_./ (_.float +1.0)))) -## (/.install "char" (unary (_.apply/1 (_.var "utf8.char")))) -## ))) +(def: i64_procs + Bundle + (<| (/.prefix "i64") + (|> /.empty + (/.install "and" (binary (product.uncurry _.bit_and))) + (/.install "or" (binary (product.uncurry _.bit_or))) + (/.install "xor" (binary (product.uncurry _.bit_xor))) + (/.install "left-shift" (binary (product.uncurry _.bit_shl))) + (/.install "right-shift" (binary (product.uncurry //runtime.i64//right_shift))) + (/.install "=" (binary (product.uncurry _.=))) + (/.install "+" (binary (product.uncurry _.+))) + (/.install "-" (binary (product.uncurry _.-))) + (/.install "<" (binary (product.uncurry _.<))) + (/.install "*" (binary (product.uncurry _.*))) + (/.install "/" (binary (product.uncurry _./))) + (/.install "%" (binary (product.uncurry _.%))) + (/.install "f64" (unary (_./ (_.float +1.0)))) + (/.install "char" (unary //runtime.i64//char)) + ))) -## (def: f64//decode -## (Unary Expression) -## (|>> list _.apply/* (|> (_.var "tonumber")) _.return (_.closure (list)) //runtime.lux//try)) +(def: (f64//% [parameter subject]) + (Binary Expression) + (_./ (_.float +1.0) (_.% parameter subject))) -## (def: f64_procs -## Bundle -## (<| (/.prefix "f64") -## (|> /.empty -## (/.install "+" (binary (product.uncurry _.+))) -## (/.install "-" (binary (product.uncurry _.-))) -## (/.install "*" (binary (product.uncurry _.*))) -## (/.install "/" (binary (product.uncurry _./))) -## (/.install "%" (binary (product.uncurry (function.flip (_.apply/2 (_.var "math.fmod")))))) -## (/.install "=" (binary (product.uncurry _.=))) -## (/.install "<" (binary (product.uncurry _.<))) -## (/.install "i64" (unary (!unary "math.floor"))) -## (/.install "encode" (unary (_.apply/2 (_.var "string.format") (_.string "%.17g")))) -## (/.install "decode" (unary ..f64//decode))))) +(def: f64_procs + Bundle + (<| (/.prefix "f64") + (|> /.empty + (/.install "+" (binary (product.uncurry _.+))) + (/.install "-" (binary (product.uncurry _.-))) + (/.install "*" (binary (product.uncurry _.*))) + (/.install "/" (binary (product.uncurry _./))) + (/.install "%" (binary ..f64//%)) + (/.install "=" (binary (product.uncurry _.=))) + (/.install "<" (binary (product.uncurry _.<))) + (/.install "i64" (unary _.intval/1)) + (/.install "encode" (unary _.strval/1)) + (/.install "decode" (unary //runtime.f64//decode))))) -## (def: (text//char [paramO subjectO]) -## (Binary Expression) -## (//runtime.text//char (_.+ (_.int +1) paramO) subjectO)) +(def: (text//clip [paramO extraO subjectO]) + (Trinary Expression) + (//runtime.text//clip paramO extraO subjectO)) -## (def: (text//clip [paramO extraO subjectO]) -## (Trinary Expression) -## (//runtime.text//clip subjectO paramO extraO)) +(def: (text//index [startO partO textO]) + (Trinary Expression) + (//runtime.text//index textO partO startO)) -## (def: (text//index [startO partO textO]) -## (Trinary Expression) -## (//runtime.text//index textO partO startO)) +(def: text_procs + Bundle + (<| (/.prefix "text") + (|> /.empty + (/.install "=" (binary (product.uncurry _.=))) + (/.install "<" (binary (product.uncurry _.<))) + (/.install "concat" (binary (product.uncurry (function.flip _.concat)))) + (/.install "index" (trinary ..text//index)) + (/.install "size" (unary //runtime.text//size)) + (/.install "char" (binary (product.uncurry //runtime.text//char))) + (/.install "clip" (trinary ..text//clip)) + ))) -## (def: text_procs -## Bundle -## (<| (/.prefix "text") -## (|> /.empty -## (/.install "=" (binary (product.uncurry _.=))) -## (/.install "<" (binary (product.uncurry _.<))) -## (/.install "concat" (binary (product.uncurry (function.flip _.concat)))) -## (/.install "index" (trinary ..text//index)) -## (/.install "size" (unary //runtime.text//size)) -## ## TODO: Use version below once the Lua compiler becomes self-hosted. -## ## (/.install "size" (unary (for {@.lua (!unary "utf8.len")} -## ## (!unary "string.len")))) -## (/.install "char" (binary ..text//char)) -## (/.install "clip" (trinary ..text//clip)) -## ))) +(def: io//log! + (Unary Expression) + (|>> _.print/1 + (_.or //runtime.unit))) -## (def: (io//log! messageO) -## (Unary Expression) -## (|> (_.apply/* (list messageO) (_.var "print")) -## (_.or //runtime.unit))) +(def: io//current-time + (Nullary Expression) + (|>> _.time/0 + (_.* (_.int +1,000)))) -## (def: io_procs -## Bundle -## (<| (/.prefix "io") -## (|> /.empty -## (/.install "log" (unary ..io//log!)) -## (/.install "error" (unary (!unary "error"))) -## (/.install "current-time" (nullary (function.constant (|> (_.var "os.time") -## (_.apply/* (list)) -## (_.* (_.int +1,000))))))))) +(def: io_procs + Bundle + (<| (/.prefix "io") + (|> /.empty + (/.install "log" (unary ..io//log!)) + (/.install "error" (unary //runtime.io//throw!)) + (/.install "current-time" (nullary ..io//current-time))))) (def: #export bundle Bundle (<| (/.prefix "lux") - /.empty - ## (|> lux_procs - ## (dictionary.merge i64_procs) - ## (dictionary.merge f64_procs) - ## (dictionary.merge text_procs) - ## (dictionary.merge io_procs) - ## ) - )) + (|> /.empty + (dictionary.merge lux_procs) + (dictionary.merge i64_procs) + (dictionary.merge f64_procs) + (dictionary.merge text_procs) + (dictionary.merge io_procs)))) diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/extension/generation/ruby/common.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/extension/generation/ruby/common.lux index 50eddb998..39ba71730 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/extension/generation/ruby/common.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/extension/generation/ruby/common.lux @@ -159,8 +159,8 @@ (def: (io//log! messageG) (Unary Expression) - (_.or //runtime.unit - (_.print/2 messageG (_.string text.new_line)))) + (|> (_.print/2 messageG (_.string text.new_line)) + (_.or //runtime.unit))) (def: io//error! (Unary Expression) diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/php/case.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/php/case.lux index e129af245..b04d8e766 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/php/case.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/php/case.lux @@ -231,46 +231,43 @@ (def: (pattern_matching generate archive pathP) (-> Phase Archive Path (Operation Statement)) (do ///////phase.monad - [pattern_matching! (pattern_matching' generate archive pathP)] + [iteration! (pattern_matching' generate archive pathP)] (wrap ($_ _.then (_.do_while (_.bool false) - pattern_matching!) + iteration!) (_.throw (_.new (_.constant "Exception") (list (_.string ////synthesis/case.pattern_matching_error)))))))) (def: (gensym prefix) (-> Text (Operation Text)) (\ ///////phase.monad map (|>> %.nat (format prefix)) /////generation.next)) +(def: #export dependencies + (-> Path (List Var)) + (|>> ////synthesis/case.storage + (get@ #////synthesis/case.dependencies) + set.to_list + (list\map (function (_ variable) + (.case variable + (#///////variable.Local register) + (..register register) + + (#///////variable.Foreign register) + (..capture register)))))) + (def: #export (case generate archive [valueS pathP]) (Generator [Synthesis Path]) (do {! ///////phase.monad} [initG (generate archive valueS) - pattern_matching! (pattern_matching generate archive pathP) - @case (..gensym "case") - #let [@caseG (_.global @case) - @caseL (_.var @case)] - @init (\ ! map _.var (..gensym "init")) - #let [@dependencies+ (|> (////synthesis/case.storage pathP) - (get@ #////synthesis/case.dependencies) - set.to_list - (list\map (function (_ variable) - [false (.case variable - (#///////variable.Local register) - (..register register) - - (#///////variable.Foreign register) - (..capture register))])))] - #let [directive ($_ _.then - (<| _.; - (_.set @caseL) - (_.closure (list (_.reference @caseL)) (list& [#0 @init] - @dependencies+)) - ($_ _.then - (_.; (_.set @cursor (_.array/* (list @init)))) - (_.; (_.set @savepoint (_.array/* (list)))) - pattern_matching!)) - (_.; (_.set @caseG @caseL)))] + [[case_module case_artifact] pattern_matching!] (/////generation.with_new_context archive + (pattern_matching generate archive pathP)) + #let [@case (_.constant (///reference.artifact [case_module case_artifact])) + @dependencies+ (..dependencies (/////synthesis.path/seq (/////synthesis.path/then valueS) + pathP)) + directive (<| (_.define_function @case (list\map _.parameter @dependencies+)) + ($_ _.then + (_.; (_.set @cursor (_.array/* (list initG)))) + (_.; (_.set @savepoint (_.array/* (list)))) + pattern_matching!))] _ (/////generation.execute! directive) - _ (/////generation.save! @case directive)] - (wrap (_.apply/* (list& initG (list\map product.right @dependencies+)) - @caseG)))) + _ (/////generation.save! (%.nat case_artifact) directive)] + (wrap (_.apply/* @dependencies+ @case)))) diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/php/function.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/php/function.lux index 718ee1e79..66d9eb37d 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/php/function.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/php/function.lux @@ -33,7 +33,7 @@ (do {! ///////phase.monad} [functionG (expression archive functionS) argsG+ (monad.map ! (expression archive) argsS+)] - (wrap (_.apply/* argsG+ functionG)))) + (wrap (_.apply/*' argsG+ functionG)))) (def: capture (-> Register Var) @@ -69,7 +69,7 @@ (do ! [function_name (\ ! map ///reference.artifact (/////generation.context archive))] - (/////generation.with_anchor (_.var function_name) + (/////generation.with_anchor (_.global function_name) (expression archive bodyS)))) closureG+ (monad.map ! (expression archive) environment) #let [@curried (_.var "curried") @@ -86,10 +86,7 @@ (list.indices arity))] #let [[definition instantiation] (..with_closure closureG+ @selfG @selfL ($_ _.then - (_.echo (_.string "'ello, world! ")) (_.; (_.set @num_args (_.func_num_args/0 []))) - (_.echo @num_args) (_.echo (_.string " ~ ")) (_.echo arityG) - (_.echo (_.string text.new_line)) (_.; (_.set @curried (_.func_get_args/0 []))) (_.cond (list [(|> @num_args (_.= arityG)) ($_ _.then @@ -98,25 +95,13 @@ [(|> @num_args (_.> arityG)) (let [arity_inputs (_.array_slice/3 [@curried (_.int +0) arityG]) extra_inputs (_.array_slice/2 [@curried arityG]) - next (_.call_user_func_array/2 [@selfL arity_inputs]) - done (_.call_user_func_array/2 [next extra_inputs])] - ($_ _.then - (_.echo (_.string "STAGED ")) (_.echo (_.count/1 arity_inputs)) - (_.echo (_.string " + ")) (_.echo (_.count/1 extra_inputs)) - (_.echo (_.string text.new_line)) - (_.echo (_.string "@selfL ")) (_.echo @selfL) (_.echo (_.string text.new_line)) - (_.echo (_.string " next ")) (_.echo next) (_.echo (_.string text.new_line)) - (_.echo (_.string " done ")) (_.echo done) (_.echo (_.string text.new_line)) - (_.return done)))]) + next (_.call_user_func_array/2 [@selfL arity_inputs])] + (_.return (_.call_user_func_array/2 [next extra_inputs])))]) ## (|> @num_args (_.< arityG)) (let [@missing (_.var "missing")] (_.return (<| (_.closure (list (_.reference @selfL) (_.reference @curried)) (list)) ($_ _.then (_.; (_.set @missing (_.func_get_args/0 []))) - (_.echo (_.string "NEXT ")) (_.echo (_.count/1 @curried)) - (_.echo (_.string " ")) (_.echo (_.count/1 @missing)) - (_.echo (_.string " ")) (_.echo (_.count/1 (_.array_merge/+ @curried (list @missing)))) - (_.echo (_.string text.new_line)) (_.return (_.call_user_func_array/2 [@selfL (_.array_merge/+ @curried (list @missing))]))))))) ))] _ (/////generation.execute! definition) diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/php/loop.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/php/loop.lux index 1bc853e64..cdac65275 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/php/loop.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/php/loop.lux @@ -19,41 +19,69 @@ ["#." case] ["/#" // #_ ["#." reference] - ["//#" /// #_ - ["."synthesis (#+ Scope Synthesis)] - ["#." generation] - ["//#" /// #_ - ["#." phase] - [meta - [archive (#+ Archive)]] - [reference - [variable (#+ Register)]]]]]]) + ["/#" // #_ + [synthesis + ["." case]] + ["/#" // #_ + ["."synthesis (#+ Scope Synthesis)] + ["#." generation] + ["//#" /// #_ + ["#." phase] + [meta + [archive (#+ Archive)]] + [reference + [variable (#+ Register)]]]]]]]) -(def: #export (scope generate archive [start initsS+ bodyS]) +(def: #export (scope expression archive [start initsS+ bodyS]) (Generator (Scope Synthesis)) - (do {! ///////phase.monad} - [@loop (\ ! map (|>> %.nat (format "loop")) /////generation.next) - #let [@loopG (_.global @loop) - @loopL (_.var @loop)] - initsO+ (monad.map ! (generate archive) initsS+) - bodyO (/////generation.with_anchor @loopL - (generate archive bodyS)) - #let [directive ($_ _.then - (<| _.; - (_.set @loopL) - (_.closure (list (_.reference @loopL)) - (|> initsS+ - list.enumeration - (list\map (|>> product.left (n.+ start) //case.register [#0]))) - (_.return bodyO))) - (_.; (_.set @loopG @loopL)))] - _ (/////generation.execute! directive) - _ (/////generation.save! @loop directive)] - (wrap (_.apply/* initsO+ @loopG)))) + (case initsS+ + ## function/false/non-independent loop + #.Nil + (expression archive bodyS) + + ## true loop + _ + (do {! ///////phase.monad} + [initsO+ (monad.map ! (expression archive) initsS+) + [[loop_module loop_artifact] bodyO] (/////generation.with_new_context archive + (do ! + [loop_context (/////generation.context archive)] + (/////generation.with_anchor (_.var (///reference.artifact loop_context)) + (expression archive bodyS)))) + #let [locals (|> initsS+ + list.enumeration + (list\map (|>> product.left (n.+ start) //case.register _.parameter))) + [directive instantiation] (: [Statement Expression] + (case (|> (synthesis.path/then bodyS) + //case.dependencies + (set.from_list _.hash) + (set.difference (set.from_list _.hash (list\map product.right locals))) + set.to_list) + #.Nil + (let [@loop (_.var (///reference.artifact [loop_module loop_artifact]))] + [(_.; (_.set @loop + (_.closure (list (_.reference @loop)) + locals + (_.return bodyO)))) + @loop]) + + foreigns + (let [@loop (_.constant (///reference.artifact [loop_module loop_artifact]))] + [(<| (_.define_function @loop (list\map _.parameter foreigns)) + (let [@loop (_.var (///reference.artifact [loop_module loop_artifact]))] + (_.return (_.set @loop + (_.closure (list& (_.reference @loop) + (list\map _.reference foreigns)) + locals + (_.return bodyO)))))) + (_.apply/* foreigns @loop)])))] + _ (/////generation.execute! directive) + _ (/////generation.save! (%.nat loop_artifact) directive)] + (wrap (_.apply/* initsO+ instantiation))))) -(def: #export (recur generate archive argsS+) +(def: #export (recur expression archive argsS+) (Generator (List Synthesis)) (do {! ///////phase.monad} [@scope /////generation.anchor - argsO+ (monad.map ! (generate archive) argsS+)] + argsO+ (monad.map ! (expression archive) argsS+)] (wrap (_.apply/* argsO+ @scope)))) diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/php/runtime.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/php/runtime.lux index 3a50bba43..7b3e55481 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/php/runtime.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/php/runtime.lux @@ -38,7 +38,7 @@ (template [ ] [(type: #export - ( Var Expression Statement))] + ( Location Expression Statement))] [Operation /////generation.Operation] [Phase /////generation.Phase] @@ -67,38 +67,6 @@ ..unit _.null)) -(def: #export variant_tag_field "_lux_tag") -(def: #export variant_flag_field "_lux_flag") -(def: #export variant_value_field "_lux_value") - -(def: (variant' tag last? value) - (-> Expression Expression Expression Literal) - (_.array/** (list [(_.string ..variant_tag_field) tag] - [(_.string ..variant_flag_field) last?] - [(_.string ..variant_value_field) value]))) - -(def: #export (variant tag last? value) - (-> Nat Bit Expression Literal) - (variant' (_.int (.int tag)) - (..flag last?) - value)) - -(def: #export none - Literal - (..variant 0 #0 ..unit)) - -(def: #export some - (-> Expression Literal) - (..variant 1 #1)) - -(def: #export left - (-> Expression Literal) - (..variant 0 #0)) - -(def: #export right - (-> Expression Literal) - (..variant 1 #1)) - (def: (feature name definition) (-> Constant (-> Constant Statement) Statement) (definition name)) @@ -158,32 +126,7 @@ (..with_vars [(~+ inputsC)] (_.define_function (~ g!_) (list (~+ (list\map (|>> (~) [false] (`)) inputsC))) - (~ code)))))))))))))))) - -(runtime: (lux//try op) - (with_vars [value] - (_.try ($_ _.then - (_.; (_.set value (_.apply/1 [..unit] op))) - (_.return (..right value))) - (list (with_vars [error] - {#_.class (_.constant "Exception") - #_.exception error - #_.handler (_.return (..left (_.do "getMessage" (list) error)))}))))) - -(runtime: (lux//program_args inputs) - (with_vars [head tail] - ($_ _.then - (_.; (_.set tail ..none)) - (<| (_.for_each (_.array_reverse/1 inputs) head) - (_.; (_.set tail (..some (_.array/* (list head tail)))))) - (_.return tail)))) - -(def: runtime//lux - Statement - ($_ _.then - @lux//try - @lux//program_args - )) + (~ code)))))))))))))))) (runtime: (io//throw! message) ($_ _.then @@ -196,8 +139,11 @@ @io//throw! )) +(def: #export tuple_size_field + "_lux_size") + (def: tuple_size - _.count/1) + (_.nth (_.string ..tuple_size_field))) (def: last_index (|>> ..tuple_size (_.- (_.int +1)))) @@ -205,6 +151,11 @@ (with_expansions [ (as_is ($_ _.then (_.; (_.set lefts (_.- last_index_right lefts))) (_.; (_.set tuple (_.nth last_index_right tuple)))))] + (runtime: (tuple//make size values) + ($_ _.then + (_.; (_.set (..tuple_size values) size)) + (_.return values))) + (runtime: (tuple//left lefts tuple) (with_vars [last_index_right] (<| (_.while (_.bool true)) @@ -227,9 +178,42 @@ [(_.> last_index_right right_index) ## Needs recursion. ]) - (_.return (_.array_slice/2 [tuple right_index]))) + ($_ _.then + (_.echo (_.string (format "[tuple//right] _.array_slice/2" text.new_line))) + (_.return (_.array_slice/2 [tuple right_index])))) ))))) +(def: #export variant_tag_field "_lux_tag") +(def: #export variant_flag_field "_lux_flag") +(def: #export variant_value_field "_lux_value") + +(runtime: (sum//make tag last? value) + (_.return (_.array/** (list [(_.string ..variant_tag_field) tag] + [(_.string ..variant_flag_field) last?] + [(_.string ..variant_value_field) value])))) + +(def: #export (variant tag last? value) + (-> Nat Bit Expression Computation) + (sum//make (_.int (.int tag)) + (..flag last?) + value)) + +(def: #export none + Computation + (..variant 0 #0 ..unit)) + +(def: #export some + (-> Expression Computation) + (..variant 1 #1)) + +(def: #export left + (-> Expression Computation) + (..variant 0 #0)) + +(def: #export right + (-> Expression Computation) + (..variant 1 #1)) + (runtime: (sum//get sum wantsLast wantedTag) (let [no_match! (_.return _.null) sum_tag (_.nth (_.string ..variant_tag_field) sum) @@ -238,83 +222,178 @@ ## sum_flag (_.nth (_.int +1) sum) sum_value (_.nth (_.string ..variant_value_field) sum) ## sum_value (_.nth (_.int +2) sum) - is_last? (_.= (_.string "") sum_flag) + is_last? (_.= ..unit sum_flag) test_recursion! (_.if is_last? ## Must recurse. - (_.return (sum//get sum_value wantsLast (_.- sum_tag wantedTag))) + ($_ _.then + (_.; (_.set wantedTag (_.- sum_tag wantedTag))) + (_.; (_.set sum sum_value))) no_match!)] - ($_ _.then - (_.echo (_.string "sum//get ")) (_.echo (_.count/1 sum)) - (_.echo (_.string " ")) (_.echo (_.apply/1 [sum] (_.constant "gettype"))) - (_.echo (_.string " ")) (_.echo sum_tag) - (_.echo (_.string " ")) (_.echo wantedTag) - (_.echo (_.string text.new_line)) + (<| (_.while (_.bool true)) (_.cond (list [(_.= sum_tag wantedTag) (_.if (_.= wantsLast sum_flag) (_.return sum_value) test_recursion!)] - [(_.> sum_tag wantedTag) + [(_.< wantedTag sum_tag) test_recursion!] - [(_.and (_.< sum_tag wantedTag) - (_.= (_.string "") wantsLast)) - (_.return (variant' (_.- wantedTag sum_tag) sum_flag sum_value))]) - no_match!) - ))) + [(_.= ..unit wantsLast) + (_.return (sum//make (_.- wantedTag sum_tag) sum_flag sum_value))]) + no_match!)))) (def: runtime//adt Statement ($_ _.then + @tuple//make @tuple//left @tuple//right + @sum//make @sum//get )) -(runtime: (i64//logic_right_shift param subject) +(runtime: (lux//try op) + (with_vars [value] + (_.try ($_ _.then + (_.; (_.set value (_.apply/1 op [..unit]))) + (_.return (..right value))) + (list (with_vars [error] + {#_.class (_.constant "Exception") + #_.exception error + #_.handler (_.return (..left (_.do "getMessage" (list) error)))}))))) + +(runtime: (lux//program_args inputs) + (with_vars [head tail] + ($_ _.then + (_.; (_.set tail ..none)) + (<| (_.for_each (_.array_reverse/1 inputs) head) + (_.; (_.set tail (..some (_.array/* (list head tail)))))) + (_.return tail)))) + +(def: runtime//lux + Statement + ($_ _.then + @lux//try + @lux//program_args + )) + +(runtime: (i64//right_shift param subject) (let [mask (|> (_.int +1) (_.bit_shl (_.- param (_.int +64))) (_.- (_.int +1)))] (_.return (|> subject - (_.bit_shr param) - (_.bit_and mask))))) + (_.bit_and mask) + (_.bit_shr param))))) + +(def: jphp? + (_.= (_.string "5.6.99") (_.phpversion/0 []))) + +(runtime: (i64//char code) + (_.if ..jphp? + (_.return (_.chr/1 [code])) + (_.return (|> code + [(_.string "V")] + _.pack/2 + [(_.string "UTF-32LE") (_.string "UTF-8")] + _.iconv/3)))) (def: runtime//i64 Statement ($_ _.then - @i64//logic_right_shift + @i64//right_shift + @i64//char )) +(runtime: (text//size value) + (_.if ..jphp? + (_.return (_.strlen/1 [value])) + (_.return (_.iconv_strlen/1 [value])))) + (runtime: (text//index subject param start) (with_vars [idx] - ($_ _.then - (_.; (_.set idx (_.strpos/3 [subject param start]))) - (_.if (_.= (_.bool false) idx) - (_.return ..none) - (_.return (..some idx)))))) + (_.if ..jphp? + ($_ _.then + (_.; (_.set idx (_.strpos/3 [subject param start]))) + (_.if (_.= (_.bool false) idx) + (_.return ..none) + (_.return (..some idx)))) + ($_ _.then + (_.; (_.set idx (_.iconv_strpos/3 [subject param start]))) + (_.if (_.= (_.bool false) idx) + (_.return ..none) + (_.return (..some idx))))))) + +(def: (within? top value) + (-> Expression Expression Computation) + (_.and (|> value (_.>= (_.int +0))) + (|> value (_.< top)))) + +(runtime: (text//clip offset length text) + (_.if ..jphp? + (_.return (_.substr/3 [text offset length])) + (_.return (_.iconv_substr/3 [text offset length])))) + +(runtime: (text//char idx text) + (_.if (|> idx (within? (text//size text))) + (let [code_point (: (-> Expression Computation) + (|>> [(_.string "UTF-8") (_.string "UTF-32LE")] + _.iconv/3 + [(_.string "V")] + _.unpack/2 + (_.nth (_.int +1))))] + (_.if ..jphp? + (_.return (code_point (_.substr/3 [text idx (_.int +1)]))) + (_.return (code_point (_.iconv_substr/3 [text idx (_.int +1)]))))) + (_.throw (_.new (_.constant "Exception") (list (_.string "[Lux Error] Cannot get char from text.")))))) (def: runtime//text Statement ($_ _.then + @text//size @text//index + @text//clip + @text//char + )) + +(runtime: (f64//decode value) + (with_vars [output] + ($_ _.then + (_.; (_.set output (_.floatval/1 value))) + (_.if (_.= (_.float +0.0) output) + (_.if ($_ _.or + (_.= (_.string "0.0") output) + (_.= (_.string "+0.0") output) + (_.= (_.string "-0.0") output) + (_.= (_.string "0") output) + (_.= (_.string "+0") output) + (_.= (_.string "-0") output)) + (_.return (..some output)) + (_.return ..none)) + (_.return (..some output))) + ))) + +(def: runtime//f64 + Statement + ($_ _.then + @f64//decode )) (def: check_necessary_conditions! Statement - (let [condition (_.= (_.int +8) - (_.constant "PHP_INT_SIZE")) - error_message (_.string (format "Cannot run program!" text.new_line - "Lux/PHP programs require 64-bit PHP builds!"))] - (_.when (_.not condition) - (_.throw (_.new (_.constant "Exception") (list error_message)))))) + (let [i64_support? (_.= (_.int +8) (_.constant "PHP_INT_SIZE")) + i64_error (_.string (format "Cannot run program!" text.new_line + "Lux/PHP programs require 64-bit PHP builds!"))] + (_.when (_.not i64_support?) + (_.throw (_.new (_.constant "Exception") (list i64_error)))))) (def: runtime Statement ($_ _.then check_necessary_conditions! - runtime//lux runtime//adt + runtime//lux runtime//i64 + runtime//f64 runtime//text runtime//io )) diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/reference.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/reference.lux index 5f4d3fbd1..bd1db66bf 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/reference.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/reference.lux @@ -20,14 +20,17 @@ (for {## In the case of Lua, there is a limit of 200 locals in a function's scope. @.lua (not ("lua script universe")) ## Cannot make all definitions be local variables because of limitations with JRuby. - @.ruby (not ("ruby script universe"))} + @.ruby (not ("ruby script universe")) + ## Cannot make all definitions be local variables because of limitations with PHP itself. + @.php (not ("php script universe"))} #0)) (def: universe_label Text (with_expansions [