diff options
author | Eduardo Julian | 2021-02-26 02:34:17 -0400 |
---|---|---|
committer | Eduardo Julian | 2021-02-26 02:34:17 -0400 |
commit | 69edb6de2ecf62881bcde1b8013c98450a6a52bc (patch) | |
tree | 3442a0abf0b5f95fa33adc586e470d150d2deece | |
parent | 47b320b854a6f28621c5d5d118cac31db27e7c50 (diff) |
Got JRuby to cooperate.
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-<init> [^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-<init>-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 [<name>] @@ -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 [<checkers> (template [<name>] - [[<name> [] boolean]] - - [isNil] [isTaint] [isClass] [isFrozen] - [isImmediate] [isModule] [isSpecialConst] [isTrue] - [isUntrusted] [hasVariables]) - <markers> (template [<name>] - [[<name> [boolean] void]] - - [setFrozen] [setTaint] [setUntrusted]) - <nullaries> (template [<name>] - [[<name> [] org/jruby/runtime/builtin/IRubyObject]] - - [dup] [checkArrayType] [inspect] [checkStringType] - [checkStringType19] [id] [rbClone] [anyToString]) - <class> (template [<name>] - [[<name> [] org/jruby/RubyClass]] - - [getMetaClass] [getType] [getSingletonClass]) - <call> (template [<inputs>] - [[callMethod <inputs> - 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]] - ) - <placeholders> (template [<name> <inputs> <output>] - [(org/jruby/runtime/builtin/IRubyObject - (<name> self (~~ (method_inputs <inputs>))) - <output> - (error! (template.text ["UNIMPLEMENTED METHOD: " <name>])))] - - [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] - - <checkers> - <markers> - <nullaries> - <class> - <call> - )] - (`` (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!"))) - - <placeholders> - )))) +(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 [<name> <block>] [(def: #export (<name> test then!) @@ -261,7 +291,7 @@ (<| :abstraction ..block (format <block> " " (: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 <code>.nat}) + (wrap (case arity + 0 (.list) + _ (|> (dec arity) + (enum.range n.enum 0) + (list\map (|>> %.nat code.local_identifier)))))) + +(syntax: (arity_types {arity <code>.nat}) + (wrap (list.repeat arity (` ..Expression)))) + +(template [<arity> <function>+] + [(with_expansions [<apply> (template.identifier ["apply/" <arity>]) + <inputs> (arity_inputs <arity>) + <types> (arity_types <arity>) + <definitions> (template.splice <function>+)] + (def: #export (<apply> function <inputs>) + (-> Expression <types> Computation) + (..apply/* (.list <inputs>) function)) + + (template [<function>] + [(`` (def: #export (~~ (template.identifier [<function> "/" <arity>])) + (<apply> (..local <function>))))] + + <definitions>))] + + [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 [<label> (format "u" (%.nat (if ..universe 1 0)))] + (for {@.lua <label> + @.ruby <label>} + ""))) (def: #export (artifact [module artifact]) (-> Context Text) diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/case.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/case.lux index fd9916a9b..428ac6279 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/case.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/case.lux @@ -52,7 +52,7 @@ (wrap (|> bodyO _.return (_.lambda #.None (list (..register register))) - (_.do "call" (list valueO)))))) + (_.apply_lambda/* (list valueO)))))) (def: #export (if expression archive [testS thenS elseS]) (Generator [Synthesis Synthesis Synthesis]) @@ -239,14 +239,40 @@ pattern_matching!) (_.statement (_.raise (_.string case.pattern_matching_error))))))) +(def: #export dependencies + (-> Path (List LVar)) + (|>> case.storage + (get@ #case.dependencies) + set.to_list + (list\map (function (_ variable) + (.case variable + (#///////variable.Local register) + (..register register) + + (#///////variable.Foreign register) + (..capture register)))))) + (def: #export (case expression archive [valueS pathP]) (Generator [Synthesis Path]) (do ///////phase.monad [initG (expression archive valueS) - pattern_matching! (pattern_matching expression archive pathP)] - (wrap (|> ($_ _.then - (_.set (list @cursor) (_.array (list initG))) - (_.set (list @savepoint) (_.array (list))) - pattern_matching!) - (_.lambda #.None (list)) - (_.do "call" (list)))))) + [[case_module case_artifact] pattern_matching!] (/////generation.with_new_context archive + (pattern_matching expression archive pathP)) + #let [## @case (_.local (///reference.artifact [case_module case_artifact])) + ## @dependencies+ (..dependencies (/////synthesis.path/seq (/////synthesis.path/then valueS) + ## pathP)) + ## directive (_.function @case @dependencies+ + ## ($_ _.then + ## (_.set (list @cursor) (_.array (list initG))) + ## (_.set (list @savepoint) (_.array (list))) + ## pattern_matching!)) + directive (_.lambda #.None (list) + ($_ _.then + (_.set (list @cursor) (_.array (list initG))) + (_.set (list @savepoint) (_.array (list))) + pattern_matching!))] + ## _ (/////generation.execute! directive) + ## _ (/////generation.save! (%.nat case_artifact) directive) + ] + ## (wrap (_.apply/* @dependencies+ @case)) + (wrap (_.apply_lambda/* (list) directive)))) diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/function.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/function.lux index d153670b7..e2ace391d 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/function.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/function.lux @@ -9,7 +9,7 @@ [collection ["." list ("#\." functor fold)]]] [target - ["_" ruby (#+ LVar Expression Statement)]]] + ["_" ruby (#+ LVar GVar Expression Statement)]]] ["." // #_ [runtime (#+ Operation Phase Generator Phase! Generator!)] ["#." reference] @@ -35,25 +35,29 @@ (do {! ///////phase.monad} [functionO (expression archive functionS) argsO+ (monad.map ! (expression archive) argsS+)] - (wrap (_.do "call" argsO+ functionO)))) + (wrap (_.apply_lambda/* argsO+ functionO)))) (def: #export capture (-> Register LVar) (|>> (///reference.foreign //reference.system) :assume)) -(def: (with_closure inits function_definition) - (-> (List Expression) Expression Expression) +(def: (with_closure inits self function_definition) + (-> (List Expression) Text Expression [Statement Expression]) (case inits #.Nil - function_definition + (let [@self (_.global self)] + [(_.set (list @self) function_definition) + @self]) _ - (|> function_definition - _.return - (_.lambda #.None - (|> (list.enumeration inits) - (list\map (|>> product.left ..capture)))) - (_.do "call" inits)))) + (let [@self (_.local self)] + [(_.function @self + (|> (list.enumeration inits) + (list\map (|>> product.left ..capture))) + ($_ _.then + (_.set (list @self) function_definition) + (_.return @self))) + (_.apply/* inits @self)]))) (def: input (|>> inc //case.register)) @@ -61,14 +65,14 @@ (def: #export (function expression archive [environment arity bodyS]) (Generator (Abstraction Synthesis)) (do {! ///////phase.monad} - [[function_name bodyO] (/////generation.with_new_context archive - (do ! - [function_name (\ ! map ///reference.artifact - (/////generation.context archive))] - (/////generation.with_anchor (_.local function_name) - (expression archive bodyS)))) + [[[function_module function_artifact] bodyO] (/////generation.with_new_context archive + (do ! + [function_name (\ ! map ///reference.artifact + (/////generation.context archive))] + (/////generation.with_anchor (_.local function_name) + (expression archive bodyS)))) closureO+ (monad.map ! (expression archive) environment) - #let [function_name (///reference.artifact function_name) + #let [function_name (///reference.artifact [function_module function_artifact]) @curried (_.local "curried") arityO (|> arity .int _.int) limitO (|> arity dec .int _.int) @@ -80,29 +84,31 @@ pre! (_.set (list (..input post)) (_.nth (|> post .int _.int) @curried)))) initialize_self! - (list.indices arity))]] - (wrap (with_closure closureO+ - (_.lambda (#.Some @self) (list (_.variadic @curried)) - ($_ _.then - (_.set (list @num_args) (_.the "length" @curried)) - (_.cond (list [(|> @num_args (_.= arityO)) - ($_ _.then - initialize! - (_.return bodyO))] - [(|> @num_args (_.> arityO)) - (let [slice (.function (_ from to) - (_.array_range from to @curried)) - arity_args (_.splat (slice (_.int +0) limitO)) - output_func_args (_.splat (slice arityO @num_args))] - (_.return (|> @self - (_.do "call" (list arity_args)) - (_.do "call" (list output_func_args)))))]) - ## (|> @num_args (_.< arityO)) - (let [@missing (_.local "missing")] - (_.return (_.lambda #.None (list (_.variadic @missing)) - (_.return (|> @self - (_.do "call" (list (_.splat (|> (_.array (list)) - (_.do "concat" (list @curried)) - (_.do "concat" (list @missing)))))))))))) - )))) - )) + (list.indices arity)) + [declaration instatiation] (with_closure closureO+ function_name + (_.lambda (#.Some @self) (list (_.variadic @curried)) + ($_ _.then + (_.set (list @num_args) (_.the "length" @curried)) + (_.cond (list [(|> @num_args (_.= arityO)) + ($_ _.then + initialize! + (_.return bodyO))] + [(|> @num_args (_.> arityO)) + (let [slice (.function (_ from to) + (_.array_range from to @curried)) + arity_args (_.splat (slice (_.int +0) limitO)) + output_func_args (_.splat (slice arityO @num_args))] + (_.return (|> @self + (_.apply_lambda/* (list arity_args)) + (_.apply_lambda/* (list output_func_args)))))]) + ## (|> @num_args (_.< arityO)) + (let [@missing (_.local "missing")] + (_.return (_.lambda #.None (list (_.variadic @missing)) + (_.return (|> @self + (_.apply_lambda/* (list (_.splat (|> (_.array (list)) + (_.do "concat" (list @curried)) + (_.do "concat" (list @missing)))))))))))) + )))] + _ (/////generation.execute! declaration) + _ (/////generation.save! (%.nat function_artifact) declaration)] + (wrap instatiation))) diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/loop.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/loop.lux index 3a6152337..4bdf1bc55 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/loop.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/loop.lux @@ -36,21 +36,53 @@ (def: #export (scope expression archive [start initsS+ bodyS]) (Generator (Scope Synthesis)) - (do {! ///////phase.monad} - [@loop (\ ! map ..loop_name /////generation.next) - initsO+ (monad.map ! (expression archive) initsS+) - bodyO (/////generation.with_anchor @loop - (expression archive bodyS))] - (wrap (|> (_.return bodyO) - (_.lambda (#.Some @loop) - (|> initsS+ - list.enumeration - (list\map (|>> product.left (n.+ start) //case.register)))) - (_.apply/* initsO+))))) + (case initsS+ + ## function/false/non-independent loop + #.Nil + (expression archive bodyS) + + ## true loop + _ + (do {! ///////phase.monad} + [@loop (\ ! map ..loop_name /////generation.next) + initsO+ (monad.map ! (expression archive) initsS+) + [[loop_module loop_artifact] bodyO] (/////generation.with_new_context archive + (do ! + [@loop (\ ! map (|>> ///reference.artifact _.local) + (/////generation.context archive))] + (/////generation.with_anchor @loop + (expression archive bodyS)))) + #let [@loop (|> [loop_module loop_artifact] ///reference.artifact _.local) + locals (|> initsS+ + list.enumeration + (list\map (|>> product.left (n.+ start) //case.register))) + actual_loop (_.statement + (_.lambda (#.Some @loop) locals + (_.return bodyO))) + [directive instantiation] (: [Statement Expression] + (case (|> (synthesis.path/then bodyS) + //case.dependencies + (set.from_list _.code_hash) + (set.difference (set.from_list _.code_hash locals)) + set.to_list) + #.Nil + [actual_loop + @loop] + + foreigns + [(_.statement + (_.lambda (#.Some @loop) foreigns + ($_ _.then + actual_loop + (_.return @loop)))) + (_.apply_lambda/* foreigns @loop)]))] + _ (/////generation.execute! directive) + _ (/////generation.save! (%.nat loop_artifact) directive)] + (wrap (_.apply_lambda/* initsO+ instantiation))))) (def: #export (recur expression archive argsS+) (Generator (List Synthesis)) (do {! ///////phase.monad} [@scope /////generation.anchor argsO+ (monad.map ! (expression archive) argsS+)] - (wrap (_.apply/* argsO+ @scope)))) + (wrap (_.apply_lambda/* argsO+ @scope)))) diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/runtime.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/runtime.lux index 76460e39a..d74915164 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/runtime.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/runtime.lux @@ -67,36 +67,6 @@ ..unit _.nil)) -(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) - (_.hash (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) (-> LVar (-> LVar Statement) Statement) (definition name)) @@ -188,6 +158,35 @@ (_.return (_.array_range right_index (..tuple_size tuple) tuple))) ))))) +(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 (_.hash (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 _.nil) sum_tag (_.nth (_.string ..variant_tag_field) sum) @@ -196,34 +195,37 @@ 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 [(_.= sum_tag wantedTag) + (_.if (_.= wantsLast sum_flag) + (_.return sum_value) + test_recursion!)] - [(_.> sum_tag wantedTag) - test_recursion!] + [(_.< wantedTag sum_tag) + test_recursion!] - [(_.and (_.< sum_tag wantedTag) - (_.= ..unit wantsLast)) - (_.return (variant' (_.- wantedTag sum_tag) sum_flag sum_value))]) + [(_.= ..unit wantsLast) + (_.return (sum//make (_.- wantedTag sum_tag) sum_flag sum_value))]) - no_match!))) + no_match!)))) (def: runtime//adt Statement ($_ _.then @tuple//left @tuple//right + @sum//make @sum//get )) (runtime: (lux//try risky) (with_vars [error value] (_.begin ($_ _.then - (_.set (list value) (_.do "call" (list ..unit) risky)) + (_.set (list value) (_.apply_lambda/* (list ..unit) risky)) (_.return (..right value))) (list [(list) error (_.return (..left (_.the "message" error)))])))) |