aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEduardo Julian2021-02-26 02:34:17 -0400
committerEduardo Julian2021-02-26 02:34:17 -0400
commit69edb6de2ecf62881bcde1b8013c98450a6a52bc (patch)
tree3442a0abf0b5f95fa33adc586e470d150d2deece
parent47b320b854a6f28621c5d5d118cac31db27e7c50 (diff)
Got JRuby to cooperate.
-rw-r--r--compilers.md5
-rw-r--r--lux-bootstrapper/src/lux/compiler/jvm/proc/host.clj6
-rw-r--r--lux-ruby/source/program.lux410
-rw-r--r--stdlib/source/lux/host.old.lux2
-rw-r--r--stdlib/source/lux/target/ruby.lux86
-rw-r--r--stdlib/source/lux/tool/compiler/language/lux/phase/extension/generation/ruby/common.lux18
-rw-r--r--stdlib/source/lux/tool/compiler/language/lux/phase/generation/js/runtime.lux3
-rw-r--r--stdlib/source/lux/tool/compiler/language/lux/phase/generation/lua/runtime.lux3
-rw-r--r--stdlib/source/lux/tool/compiler/language/lux/phase/generation/python/runtime.lux28
-rw-r--r--stdlib/source/lux/tool/compiler/language/lux/phase/generation/reference.lux10
-rw-r--r--stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/case.lux42
-rw-r--r--stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/function.lux94
-rw-r--r--stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/loop.lux56
-rw-r--r--stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/runtime.lux86
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)))]))))