From 69edb6de2ecf62881bcde1b8013c98450a6a52bc Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Fri, 26 Feb 2021 02:34:17 -0400 Subject: Got JRuby to cooperate. --- compilers.md | 5 +- .../src/lux/compiler/jvm/proc/host.clj | 6 +- lux-ruby/source/program.lux | 410 ++++++++++++--------- stdlib/source/lux/host.old.lux | 2 +- stdlib/source/lux/target/ruby.lux | 86 ++++- .../lux/phase/extension/generation/ruby/common.lux | 18 +- .../language/lux/phase/generation/js/runtime.lux | 3 +- .../language/lux/phase/generation/lua/runtime.lux | 3 +- .../lux/phase/generation/python/runtime.lux | 28 +- .../language/lux/phase/generation/reference.lux | 10 +- .../language/lux/phase/generation/ruby/case.lux | 42 ++- .../lux/phase/generation/ruby/function.lux | 94 ++--- .../language/lux/phase/generation/ruby/loop.lux | 56 ++- .../language/lux/phase/generation/ruby/runtime.lux | 86 ++--- 14 files changed, 531 insertions(+), 318 deletions(-) diff --git a/compilers.md b/compilers.md index 5aabf4445..0bea1a06c 100644 --- a/compilers.md +++ b/compilers.md @@ -260,7 +260,10 @@ cd ~/lux/lux-ruby/ \ ## Try ``` -cd ~/lux/lux-ruby/ && java -jar target/program.jar build --source ~/lux/stdlib/source --target ~/lux/stdlib/target --module test/lux +## Compile Lux's Standard Library's tests using a JVM-based compiler. +cd ~/lux/stdlib/ \ +&& lein clean \ +&& time java -jar ~/lux/lux-ruby/jvm_based_compiler.jar build --source ~/lux/stdlib/source --target ~/lux/stdlib/target --module test/lux ``` --- diff --git a/lux-bootstrapper/src/lux/compiler/jvm/proc/host.clj b/lux-bootstrapper/src/lux/compiler/jvm/proc/host.clj index ec934ae7b..034d503a7 100644 --- a/lux-bootstrapper/src/lux/compiler/jvm/proc/host.clj +++ b/lux-bootstrapper/src/lux/compiler/jvm/proc/host.clj @@ -412,7 +412,9 @@ (defn ^:private add-anon-class- [^ClassWriter class-writer compile class-name super-class env ctor-args] (|let [[super-class-name super-class-params] super-class - init-types (->> ctor-args (&/|map (comp &host-generics/->type-signature &/|first)) (&/fold str ""))] + init-types (->> ctor-args + (&/|map (comp &host-generics/gclass->signature &/|first)) + (&/fold str ""))] (&/with-writer (.visitMethod class-writer Opcodes/ACC_PUBLIC init-method (anon-class--signature env) nil nil) (|do [^MethodVisitor =method &/get-writer :let [_ (doto =method @@ -421,7 +423,7 @@ _ (&/map% (fn [type+term] (|let [[type term] type+term] (|do [_ (compile term) - :let [_ (prepare-ctor-arg =method type)]] + :let [_ (prepare-ctor-arg =method (&host-generics/gclass->class-name type))]] (return nil)))) ctor-args) :let [_ (doto =method diff --git a/lux-ruby/source/program.lux b/lux-ruby/source/program.lux index e373e20b5..044e97923 100644 --- a/lux-ruby/source/program.lux +++ b/lux-ruby/source/program.lux @@ -1,6 +1,7 @@ (.module: [lux #* [program (#+ program:)] + ["." debug] ["." host (#+ import:)] ["." meta] [abstract @@ -76,12 +77,28 @@ (toString [] java/lang/String) (getClass [] (java/lang/Class java/lang/Object))]) -(import: java/lang/Integer) +(import: java/lang/Integer + ["#::." + (longValue [] java/lang/Long)]) (import: java/lang/Long ["#::." (intValue [] java/lang/Integer)]) +(import: org/jruby/RubyString + ["#::." + (#static newInternalFromJavaExternal [org/jruby/Ruby java/lang/String] org/jruby/RubyString) + (asJavaString [] java/lang/String)]) + +(import: org/jruby/runtime/builtin/IRubyObject) + +(import: org/jruby/Ruby + ["#::." + (getCurrentContext [] org/jruby/runtime/ThreadContext) + (getNil [] org/jruby/runtime/builtin/IRubyObject)]) + +(import: org/jruby/RubyClass) + (import: org/jruby/RubyArray ["#::." (getLength [] int) @@ -91,12 +108,6 @@ ["#::." (get [java/lang/Object] #? java/lang/Object)]) -(import: org/jruby/Ruby - ["#::." - (getCurrentContext [] org/jruby/runtime/ThreadContext)]) - -(import: org/jruby/runtime/builtin/IRubyObject) - (import: org/jruby/runtime/ThreadContext) (template [] @@ -123,140 +134,64 @@ (import: org/jruby/runtime/builtin/InstanceVariables) (import: org/jruby/runtime/builtin/InternalVariables) -(def: (lux_structure value) - (-> (Array java/lang/Object) org/jruby/runtime/builtin/IRubyObject) - (with_expansions [ (template [] - [[ [] boolean]] - - [isNil] [isTaint] [isClass] [isFrozen] - [isImmediate] [isModule] [isSpecialConst] [isTrue] - [isUntrusted] [hasVariables]) - (template [] - [[ [boolean] void]] - - [setFrozen] [setTaint] [setUntrusted]) - (template [] - [[ [] org/jruby/runtime/builtin/IRubyObject]] - - [dup] [checkArrayType] [inspect] [checkStringType] - [checkStringType19] [id] [rbClone] [anyToString]) - (template [] - [[ [] org/jruby/RubyClass]] - - [getMetaClass] [getType] [getSingletonClass]) - (template [] - [[callMethod - org/jruby/runtime/builtin/IRubyObject]] - - [[org/jruby/runtime/ThreadContext int java/lang/String]] - [[org/jruby/runtime/ThreadContext int java/lang/String org/jruby/runtime/builtin/IRubyObject]] - [[org/jruby/runtime/ThreadContext java/lang/String]] - [[org/jruby/runtime/ThreadContext java/lang/String org/jruby/runtime/builtin/IRubyObject]] - ## [[org/jruby/runtime/ThreadContext java/lang/String [org/jruby/runtime/builtin/IRubyObject]]] - [[org/jruby/runtime/ThreadContext java/lang/String [org/jruby/runtime/builtin/IRubyObject] org/jruby/runtime/Block]] - ) - (template [ ] - [(org/jruby/runtime/builtin/IRubyObject - ( self (~~ (method_inputs ))) - - (error! (template.text ["UNIMPLEMENTED METHOD: " ])))] - - [getRuntime [] org/jruby/Ruby] - [copySpecialInstanceVariables [org/jruby/runtime/builtin/IRubyObject] void] - [syncVariables [org/jruby/runtime/builtin/IRubyObject] void] - [syncVariables [(java/util/List (org/jruby/runtime/builtin/Variable java/lang/Object))] void] - [dataWrapStruct [java/lang/Object] void] - [addFinalizer [org/jruby/runtime/builtin/IRubyObject] void] - [removeFinalizers [] void] - [getVariable [int] java/lang/Object] - [setVariable [int java/lang/Object] void] - [getVariableList [] (java/util/List (org/jruby/runtime/builtin/Variable java/lang/Object))] - [getVariableNameList [] (java/util/List java/lang/String)] - [getVariableCount [] int] - [getJavaClass [] (java/lang/Class java/lang/Object)] - [asJavaString [] java/lang/String] - [getInstanceVariables [] org/jruby/runtime/builtin/InstanceVariables] - [getInternalVariables [] org/jruby/runtime/builtin/InternalVariables] - [convertToInteger [] org/jruby/RubyInteger] - [convertToInteger [java/lang/String] org/jruby/RubyInteger] - [convertToInteger [int java/lang/String] org/jruby/RubyInteger] - [convertToArray [] org/jruby/RubyArray] - [convertToHash [] org/jruby/RubyHash] - [convertToFloat [] org/jruby/RubyFloat] - [convertToString [] org/jruby/RubyString] - [asString [] org/jruby/RubyString] - [respondsTo [java/lang/String] boolean] - [respondsToMissing [java/lang/String] boolean] - [respondsToMissing [java/lang/String boolean] boolean] - [dataGetStruct [] java/lang/Object] - [dataGetStructChecked [] java/lang/Object] - [infectBy [org/jruby/runtime/builtin/IRubyObject] org/jruby/runtime/builtin/IRubyObject] - [eql [org/jruby/runtime/builtin/IRubyObject] boolean] - [toJava [(java/lang/Class java/lang/Object)] java/lang/Object] - - [op_eqq - [org/jruby/runtime/ThreadContext - org/jruby/runtime/builtin/IRubyObject] - org/jruby/runtime/builtin/IRubyObject] - - [op_equal - [org/jruby/runtime/ThreadContext - org/jruby/runtime/builtin/IRubyObject] - org/jruby/runtime/builtin/IRubyObject] - - [callSuper - [org/jruby/runtime/ThreadContext - [org/jruby/runtime/builtin/IRubyObject] - org/jruby/runtime/Block] - org/jruby/runtime/builtin/IRubyObject] - - [checkCallMethod - [org/jruby/runtime/ThreadContext - java/lang/String] - org/jruby/runtime/builtin/IRubyObject] - - [checkCallMethod - [org/jruby/runtime/ThreadContext - org/jruby/runtime/JavaSites$CheckedSites] - org/jruby/runtime/builtin/IRubyObject] - - - - - - - )] - (`` (host.object [] [program/StructureValue - org/jruby/runtime/builtin/IRubyObject] - [] - ## Methods - (program/StructureValue - [] (getValue self) - java/lang/Object - (:coerce (Array java/lang/Object) value)) - - (org/jruby/runtime/builtin/IRubyObject - [] (callMethod self - {thread_context org/jruby/runtime/ThreadContext} - {member java/lang/String} - {inputs [org/jruby/runtime/builtin/IRubyObject]}) - org/jruby/runtime/builtin/IRubyObject - (exec - ("lux io log" (format "Was called: " (%.text member))) - (error! "OOPS!"))) - - - )))) +(import: org/jruby/embed/internal/LocalContextProvider + ["#::." + (getRuntime [] org/jruby/Ruby)]) + +(import: org/jruby/embed/ScriptingContainer + ["#::." + (new []) + (runScriptlet [java/lang/String] #try #? java/lang/Object) + (getProvider [] org/jruby/embed/internal/LocalContextProvider)]) + +## TODO; Figure out a way to not need "interpreter" to be a global variable. +(def: interpreter + (org/jruby/embed/ScriptingContainer::new)) + +(template: (!ruby_runtime) + (|> ..interpreter + org/jruby/embed/ScriptingContainer::getProvider + org/jruby/embed/internal/LocalContextProvider::getRuntime)) + +(template: (!ruby_thread_context) + (|> (!ruby_runtime) + org/jruby/Ruby::getCurrentContext)) + +(def: initial_ruby_runtime + (!ruby_runtime)) + +(import: org/jruby/java/proxies/JavaProxy + ["#::." + (new [org/jruby/Ruby org/jruby/RubyClass java/lang/Object])]) + +(import: org/jruby/internal/runtime/methods/DynamicMethod) + +(import: org/jruby/runtime/callsite/CacheEntry + ["#::." + (new [org/jruby/internal/runtime/methods/DynamicMethod int])]) + +(import: org/jruby/RubyFixnum + ["#::." + (new [org/jruby/Ruby long]) + (getLongValue [] long)]) + +(import: org/jruby/RubyFloat + ["#::." + (new [org/jruby/Ruby double])]) + +(import: org/jruby/RubyBoolean + ["#::." + (#static newBoolean [org/jruby/Ruby boolean] org/jruby/RubyBoolean)]) + +(import: org/jruby/RubyNil + ["#::." + (new [org/jruby/Ruby])]) (import: org/jruby/RubyProc ["#::." (call [org/jruby/runtime/ThreadContext [org/jruby/runtime/builtin/IRubyObject]] #try org/jruby/runtime/builtin/IRubyObject)]) -(import: org/jruby/javasupport/JavaArray - ["#::." - (new [org/jruby/Ruby java/lang/Object])]) - (type: Translator (-> java/lang/Object (Try Any))) @@ -321,6 +256,7 @@ [java/lang/Long #try.Success] [java/lang/Double #try.Success] [java/lang/String #try.Success] + [[java/lang/Object] #try.Success] [org/jruby/RubyArray (read_tuple read)] [org/jruby/RubyHash (read_variant read)] [org/jruby/RubySymbol #try.Success] @@ -329,42 +265,191 @@ (exception.throw ..unknown_kind_of_object host_object) ))) -(exception: (cannot_apply_a_non_function {object java/lang/Object}) +(def: ruby_nil + org/jruby/runtime/builtin/IRubyObject + (org/jruby/Ruby::getNil ..initial_ruby_runtime)) + +(def: lux_unit + org/jruby/RubyString + (org/jruby/RubyString::newInternalFromJavaExternal ..initial_ruby_runtime "")) + +(def: (wrapped_lux_value lux_structure value) + (-> (-> (Array java/lang/Object) org/jruby/runtime/builtin/IRubyObject) + (-> java/lang/Object org/jruby/runtime/builtin/IRubyObject)) + (<| (case (host.check [java/lang/Object] value) + (#.Some value) + (|> value (:coerce (Array java/lang/Object)) lux_structure) + + #.None) + (case (host.check java/lang/Boolean value) + (#.Some value) + (org/jruby/RubyBoolean::newBoolean ..initial_ruby_runtime value) + + #.None) + (case (host.check java/lang/Long value) + (#.Some value) + (org/jruby/RubyFixnum::new ..initial_ruby_runtime value) + + #.None) + (case (host.check java/lang/Double value) + (#.Some value) + (org/jruby/RubyFloat::new ..initial_ruby_runtime value) + + #.None) + (case (host.check java/lang/String value) + (#.Some value) + (org/jruby/RubyString::newInternalFromJavaExternal ..initial_ruby_runtime value) + + #.None) + (:coerce org/jruby/runtime/builtin/IRubyObject value))) + +(exception: (invalid_variant_access {field Text}) (exception.report - ["Non-function" (java/lang/Object::toString object)])) + ["Field" (%.text field)])) -(import: org/jruby/embed/internal/LocalContextProvider - ["#::." - (getRuntime [] org/jruby/Ruby)]) +(exception: (invalid_tuple_access {index Nat}) + (exception.report + ["Index" (%.nat index)])) + +(def: (lux_wrapper_access lux_structure value) + (-> (-> (Array java/lang/Object) org/jruby/runtime/builtin/IRubyObject) + (-> (Array java/lang/Object) org/jruby/internal/runtime/methods/DynamicMethod)) + (host.object [] org/jruby/internal/runtime/methods/DynamicMethod [] + [{java/lang/String "[]"}] + + (org/jruby/internal/runtime/methods/DynamicMethod + [] (call self + {thread_context org/jruby/runtime/ThreadContext} + {self org/jruby/runtime/builtin/IRubyObject} + {module org/jruby/RubyModule} + {method java/lang/String} + {args [org/jruby/runtime/builtin/IRubyObject]} + {block org/jruby/runtime/Block}) + org/jruby/runtime/builtin/IRubyObject + (let [member (host.array_read 0 args)] + (case (host.check org/jruby/RubyFixnum member) + (#.Some member) + (case (array.read (org/jruby/RubyFixnum::getLongValue member) value) + (#.Some value) + (wrapped_lux_value lux_structure value) + + #.None + (error! (exception.construct ..invalid_tuple_access [(org/jruby/RubyFixnum::getLongValue member)]))) + + #.None + (case (host.check org/jruby/RubyString member) + (#.Some member) + (case (:coerce Text (org/jruby/RubyString::asJavaString member)) + (^ (static runtime.variant_tag_field)) + (|> value + (array.read 0) + maybe.assume + (:coerce java/lang/Integer) + java/lang/Integer::longValue + (org/jruby/RubyFixnum::new ..initial_ruby_runtime)) + + (^ (static runtime.variant_flag_field)) + (case (array.read 1 value) + #.None + ..ruby_nil + + (#.Some flag) + ..lux_unit) + + (^ (static runtime.variant_value_field)) + (case (array.read 2 value) + (#.Some value) + (wrapped_lux_value lux_structure value) + + #.None + (error! (exception.construct ..nil_has_no_lux_representation []))) + + field + (error! (exception.construct ..invalid_variant_access [field]))) + + #.None + (error! (format "lux_wrapper_access INVALID INDEX")))))))) + +(def: (lux_wrapper_equality value) + (-> (Array java/lang/Object) org/jruby/internal/runtime/methods/DynamicMethod) + (host.object [] org/jruby/internal/runtime/methods/DynamicMethod [] + [{java/lang/String "=="}] + + (org/jruby/internal/runtime/methods/DynamicMethod + [] (call self + {thread_context org/jruby/runtime/ThreadContext} + {self org/jruby/runtime/builtin/IRubyObject} + {module org/jruby/RubyModule} + {method java/lang/String} + {args [org/jruby/runtime/builtin/IRubyObject]} + {block org/jruby/runtime/Block}) + org/jruby/runtime/builtin/IRubyObject + (let [reference (host.array_read 0 args)] + (case (..read (:coerce java/lang/Object reference)) + (#try.Success reference) + (org/jruby/RubyBoolean::newBoolean ..initial_ruby_runtime (is? (: Any reference) (: Any value))) + + (#try.Failure error) + (org/jruby/RubyBoolean::newBoolean ..initial_ruby_runtime false)))))) + +(def: (lux_wrapper_length value) + (-> (Array java/lang/Object) org/jruby/internal/runtime/methods/DynamicMethod) + (host.object [] org/jruby/internal/runtime/methods/DynamicMethod [] + [{java/lang/String "length"}] + + (org/jruby/internal/runtime/methods/DynamicMethod + [] (call self + {thread_context org/jruby/runtime/ThreadContext} + {self org/jruby/runtime/builtin/IRubyObject} + {module org/jruby/RubyModule} + {method java/lang/String} + {args [org/jruby/runtime/builtin/IRubyObject]} + {block org/jruby/runtime/Block}) + org/jruby/runtime/builtin/IRubyObject + (|> value + array.size + (org/jruby/RubyFixnum::new ..initial_ruby_runtime))))) + +(exception: (unknown_method {method Text}) + (exception.report + ["Method" (%.text method)])) -(import: org/jruby/embed/ScriptingContainer - ["#::." - (new []) - (runScriptlet [java/lang/String] #try #? java/lang/Object) - (getProvider [] org/jruby/embed/internal/LocalContextProvider)]) +(def: (lux_structure value) + (-> (Array java/lang/Object) org/jruby/runtime/builtin/IRubyObject) + (let [meta_class (host.object [] org/jruby/RubyClass [] + [{org/jruby/Ruby + ..initial_ruby_runtime}] -## TODO; Figure out a way to not need "interpreter" to be a global variable. -(def: interpreter (org/jruby/embed/ScriptingContainer::new)) + (org/jruby/RubyClass + [] (searchWithCache self + {method java/lang/String}) + org/jruby/runtime/callsite/CacheEntry + (case (:coerce Text method) + "[]" + (org/jruby/runtime/callsite/CacheEntry::new (..lux_wrapper_access lux_structure value) 0) + + "==" + (org/jruby/runtime/callsite/CacheEntry::new (..lux_wrapper_equality value) 1) + + "length" + (org/jruby/runtime/callsite/CacheEntry::new (..lux_wrapper_length value) 2) + + _ + (error! (exception.construct ..unknown_method [(:coerce Text method)])))))] + (org/jruby/java/proxies/JavaProxy::new ..initial_ruby_runtime meta_class (:coerce java/lang/Object value)))) + +(exception: (cannot_apply_a_non_function {object java/lang/Object}) + (exception.report + ["Non-function" (java/lang/Object::toString object)])) (def: ensure_macro (-> Macro (Maybe org/jruby/RubyProc)) (|>> (:coerce java/lang/Object) (host.check org/jruby/RubyProc))) -(template: (!ruby_runtime) - (|> ..interpreter - org/jruby/embed/ScriptingContainer::getProvider - org/jruby/embed/internal/LocalContextProvider::getRuntime)) - -(template: (!ruby_thread_context) - (|> (!ruby_runtime) - org/jruby/Ruby::getCurrentContext)) - (def: to_host (-> Any org/jruby/runtime/builtin/IRubyObject) (|>> (:coerce (Array java/lang/Object)) - ..lux_structure - ## (org/jruby/javasupport/JavaArray::new (!ruby_runtime)) - )) + ..lux_structure)) (def: (call_macro inputs lux macro) (-> (List Code) Lux org/jruby/RubyProc (Try (Try [Lux (List Code)]))) @@ -416,8 +501,7 @@ @global (_.global global)] (do try.monad [#let [definition (_.set (list @global) input)] - _ (run! definition) - value (run! @global)] + value (run! definition)] (wrap [global value definition])))) (def: (ingest context content) @@ -450,10 +534,6 @@ _.nil) program))) -(import: org/jruby/RubyString - ["#::." - (#static newInternalFromJavaExternal [org/jruby/Ruby java/lang/String] org/jruby/RubyString)]) - (def: extender Extender ## TODO: Stop relying on coercions ASAP. diff --git a/stdlib/source/lux/host.old.lux b/stdlib/source/lux/host.old.lux index cc7fe53e4..3a69f2464 100644 --- a/stdlib/source/lux/host.old.lux +++ b/stdlib/source/lux/host.old.lux @@ -1322,7 +1322,7 @@ {unchecked (p.maybe s.any)}) {#.doc (doc "Checks whether an object is an instance of a particular class." "Caveat emptor: Cannot check for polymorphism, so avoid using parameterized classes." - (case (check String "YOLO") + (case (check java/lang/String "YOLO") (#.Some value_as_string) #.None))} (with_gensyms [g!_ g!unchecked] diff --git a/stdlib/source/lux/target/ruby.lux b/stdlib/source/lux/target/ruby.lux index c170f3504..e884d6c70 100644 --- a/stdlib/source/lux/target/ruby.lux +++ b/stdlib/source/lux/target/ruby.lux @@ -2,17 +2,26 @@ [lux (#- Location Code static int if cond function or and not comment) ["@" 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]]) @@ -39,6 +48,18 @@ (abstract: #export (Code brand) Text + (structure: #export code_equivalence + (All [brand] (Equivalence (Code brand))) + + (def: (= reference subject) + (\ text.equivalence = (:representation reference) (:representation subject)))) + + (structure: #export code_hash + (All [brand] (Hash (Code brand))) + + (def: &equivalence ..code_equivalence) + (def: hash (|>> :representation (\ text.hash hash)))) + (def: #export manual (-> Text Code) (|>> :abstraction)) @@ -201,6 +222,15 @@ (format (:representation func)) :abstraction)) + (def: #export (apply_lambda/* args lambda) + (-> (List Expression) Expression Computation) + (|> args + (list\map (|>> :representation)) + (text.join_with ..input_separator) + (text.enclose ["[" "]"]) + (format (:representation lambda)) + :abstraction)) + (def: #export (the field object) (-> Text Expression Access) (:abstraction (format (:representation object) "." field))) @@ -251,9 +281,9 @@ (<| :abstraction ..block (format "if " (:representation test) - text.new_line (..nest (:representation then!)) + (..nest (:representation then!)) text.new_line "else" - text.new_line (..nest (:representation else!))))) + (..nest (:representation else!))))) (template [ ] [(def: #export ( test then!) @@ -261,7 +291,7 @@ (<| :abstraction ..block (format " " (:representation test) - text.new_line (..nest (:representation then!)))))] + (..nest (:representation then!)))))] [when "if"] [while "while"] @@ -274,7 +304,7 @@ (format "for " (:representation var) " in " (:representation array) " do " - text.new_line (..nest (:representation iteration!))))) + (..nest (:representation iteration!))))) (type: #export Rescue {#classes (List Text) @@ -285,13 +315,12 @@ (-> Statement (List Rescue) Statement) (<| :abstraction ..block - (format "begin" - text.new_line (:representation body!) + (format "begin" (..nest (:representation body!)) (|> rescues (list\map (.function (_ [classes exception rescue]) (format text.new_line "rescue " (text.join_with ..input_separator classes) " => " (:representation exception) - text.new_line (..nest (:representation rescue))))) + (..nest (:representation rescue))))) (text.join_with text.new_line))))) (def: #export (return value) @@ -315,7 +344,7 @@ ) (def: #export (function name args body!) - (-> LVar (List Var) Statement Statement) + (-> LVar (List LVar) Statement Statement) (<| :abstraction ..block (format "def " (:representation name) @@ -323,7 +352,7 @@ (list\map (|>> :representation)) (text.join_with ..input_separator) (text.enclose ["(" ")"])) - text.new_line (:representation body!)))) + (..nest (:representation body!))))) (def: #export (lambda name args body!) (-> (Maybe LVar) (List Var) Statement Literal) @@ -392,3 +421,38 @@ (..if test then! next!)) else! (list.reverse clauses))) + +(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 [ "/" ])) + ( (..local ))))] + + ))] + + [1 + [["print"]]] + + [2 + []] + + [3 + []] + ) 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 d43f3833a..9f04b35d2 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 @@ -71,22 +71,17 @@ (/.install "=" (binary (product.uncurry _.=))) (/.install "+" (binary (..keep_i64 (product.uncurry _.+)))) (/.install "-" (binary (..keep_i64 (product.uncurry _.-)))) - ))) - -(def: int_procs - Bundle - (<| (/.prefix "int") - (|> /.empty (/.install "<" (binary (product.uncurry _.<))) (/.install "*" (binary (..keep_i64 (product.uncurry _.*)))) (/.install "/" (binary (product.uncurry _./))) (/.install "%" (binary (product.uncurry _.%))) - (/.install "frac" (unary (_./ (_.float +1.0)))) - (/.install "char" (unary (_.do "chr" (list))))))) + (/.install "f64" (unary (_./ (_.float +1.0)))) + (/.install "char" (unary (_.do "chr" (list (_.string "UTF-8"))))) + ))) -(def: frac_procs +(def: f64_procs Bundle - (<| (/.prefix "frac") + (<| (/.prefix "f64") (|> /.empty (/.install "+" (binary (product.uncurry _.+))) (/.install "-" (binary (product.uncurry _.-))) @@ -155,8 +150,7 @@ (<| (/.prefix "lux") (|> lux_procs (dictionary.merge ..i64_procs) - (dictionary.merge ..int_procs) - (dictionary.merge ..frac_procs) + (dictionary.merge ..f64_procs) (dictionary.merge ..text_procs) (dictionary.merge ..io_procs) ))) diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/js/runtime.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/js/runtime.lux index 53213d3f1..f434e9dbd 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/js/runtime.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/js/runtime.lux @@ -213,8 +213,7 @@ test_recursion!)] [(_.< wanted_tag sum_tag) test_recursion!] - [(_.and (_.> wanted_tag sum_tag) - (_.= ..unit wants_last)) + [(_.= ..unit wants_last) extrac_sub_variant!]) no_match!)))) diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/lua/runtime.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/lua/runtime.lux index 20d825912..fd1cfa2b4 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/lua/runtime.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/lua/runtime.lux @@ -220,8 +220,7 @@ test_recursion!)] [(_.< wanted_tag sum_tag) test_recursion!] - [(_.and (_.> wanted_tag sum_tag) - (_.= ..unit wants_last)) + [(_.= ..unit wants_last) extrac_sub_variant!]) no_match!)))) diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/python/runtime.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/python/runtime.lux index 22234bcc4..933bcf6b0 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/python/runtime.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/python/runtime.lux @@ -66,7 +66,7 @@ (def: (flag value) (-> Bit Literal) (if value - (_.unicode "") + ..unit _.none)) (def: (variant' tag last? value) @@ -243,24 +243,26 @@ sum_tag (_.nth (_.int +0) sum) sum_flag (_.nth (_.int +1) sum) sum_value (_.nth (_.int +2) sum) - is_last? (_.= (_.unicode "") 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 (list sum) sum_value) + (_.set (list wantedTag) (_.- sum_tag wantedTag))) no_match!)] - (_.cond (list [(_.= sum_tag wantedTag) - (_.if (_.= wantsLast sum_flag) - (_.return sum_value) - test_recursion!)] + (<| (_.while (_.bool true)) + (_.cond (list [(_.= wantedTag sum_tag) + (_.if (_.= wantsLast sum_flag) + (_.return sum_value) + test_recursion!)] - [(_.> sum_tag wantedTag) - test_recursion!] + [(_.< wantedTag sum_tag) + test_recursion!] - [(_.and (_.< sum_tag wantedTag) - (_.= (_.unicode "") wantsLast)) - (_.return (variant' (_.- wantedTag sum_tag) sum_flag sum_value))]) + [(_.= ..unit wantsLast) + (_.return (variant' (_.- wantedTag sum_tag) sum_flag sum_value))]) - no_match!))) + no_match!)))) (def: runtime//adt (Statement Any) 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 6bfd7182e..5f4d3fbd1 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 @@ -18,13 +18,17 @@ ## into the local variables of some scoping function. (def: #export universe (for {## In the case of Lua, there is a limit of 200 locals in a function's scope. - @.lua (not ("lua script universe"))} + @.lua (not ("lua script universe")) + ## Cannot make all definitions be local variables because of limitations with JRuby. + @.ruby (not ("ruby script universe"))} #0)) (def: universe_label Text - (for {@.lua (format "u" (%.nat (if ..universe 1 0)))} - "")) + (with_expansions [