aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/meta/compiler/language
diff options
context:
space:
mode:
authorEduardo Julian2022-11-06 20:52:21 -0400
committerEduardo Julian2022-11-06 20:52:21 -0400
commitae4c0a4746d59b552ebeba166a43ce756dd265af (patch)
tree8548fb3e4a77bd986d459a639ee31cf2455fe20e /stdlib/source/library/lux/meta/compiler/language
parentfd8ea1e1b9cae781abe42aeadda2e0ef149994d6 (diff)
More efficient code-generation for text composition.
Diffstat (limited to 'stdlib/source/library/lux/meta/compiler/language')
-rw-r--r--stdlib/source/library/lux/meta/compiler/language/lux/phase/extension/analysis/lux.lux13
-rw-r--r--stdlib/source/library/lux/meta/compiler/language/lux/phase/extension/generation/jvm/common.lux79
2 files changed, 81 insertions, 11 deletions
diff --git a/stdlib/source/library/lux/meta/compiler/language/lux/phase/extension/analysis/lux.lux b/stdlib/source/library/lux/meta/compiler/language/lux/phase/extension/analysis/lux.lux
index 3daa22bc1..3dab02980 100644
--- a/stdlib/source/library/lux/meta/compiler/language/lux/phase/extension/analysis/lux.lux
+++ b/stdlib/source/library/lux/meta/compiler/language/lux/phase/extension/analysis/lux.lux
@@ -97,6 +97,17 @@
(-> Type Type Type Type (-> Text Handler))
(simple (list subjectT param0T param1T) outputT))
+(def .public (variadic input output extension_name)
+ (-> Type Type (-> Text Handler))
+ (function (_ analyse archive args)
+ (do [! phase.monad]
+ [_ (typeA.inference output)
+ argsA (monad.each !
+ (|>> (analyse archive)
+ (typeA.expecting input))
+ args)]
+ (in {analysis.#Extension [.prelude (format extension_name "|generation")] argsA}))))
+
... TODO: Get rid of this ASAP
(these
(exception.def .public (char_text_must_be_size_1 text)
@@ -342,7 +353,7 @@
(-> Bundle Bundle)
(|>> (install "text_=#" (binary Text Text Bit))
(install "text_<#" (binary Text Text Bit))
- (install "text_composite#" (binary Text Text Text))
+ (install "text_composite#" (variadic Text Text))
(install "text_index#" (trinary Nat Text Text (type_literal (Maybe Nat))))
(install "text_size#" (unary Text Nat))
(install "text_char#" (binary Nat Text Nat))
diff --git a/stdlib/source/library/lux/meta/compiler/language/lux/phase/extension/generation/jvm/common.lux b/stdlib/source/library/lux/meta/compiler/language/lux/phase/extension/generation/jvm/common.lux
index 5f17ba7cc..4d8a17afa 100644
--- a/stdlib/source/library/lux/meta/compiler/language/lux/phase/extension/generation/jvm/common.lux
+++ b/stdlib/source/library/lux/meta/compiler/language/lux/phase/extension/generation/jvm/common.lux
@@ -4,8 +4,10 @@
[abstract
["[0]" monad (.only do)]]
[control
+ ["|" pipe]
["<>" parser]
- ["[0]" try]]
+ ["[0]" try]
+ ["[0]" function]]
[data
["[0]" product]
[collection
@@ -295,15 +297,20 @@
(dictionary.has "f64_encoded#|generation" (unary ..f64::encode))
(dictionary.has "f64_decoded#|generation" (unary ..f64::decode))))
+(def $String::length
+ (_.invokevirtual ..$String "length" (type.method [(list) (list) type.int (list)])))
+
(def (text::size inputG)
(Unary (Bytecode Any))
(all _.composite
inputG
(_.checkcast $String)
- (_.invokevirtual ..$String "length" (type.method [(list) (list) type.int (list)]))
+ $String::length
..lux_int))
-(def no_op (Bytecode Any) (_#in []))
+(def no_op
+ (Bytecode Any)
+ (_#in []))
(with_template [<name> <pre_subject> <pre_param> <op> <post>]
[(def (<name> [paramG subjectG])
@@ -324,12 +331,64 @@
..lux_int]
)
-(def (text::concat [leftG rightG])
- (Binary (Bytecode Any))
- (all _.composite
- leftG (_.checkcast $String)
- rightG (_.checkcast $String)
- (_.invokevirtual ..$String "concat" (type.method [(list) (list ..$String) ..$String (list)]))))
+(def text::composite
+ (Variadic (Bytecode Any))
+ (let [$StringBuilder (type.class "java.lang.StringBuilder" (list))
+ add_part! (is (-> (Bytecode Any)
+ (Bytecode Any))
+ (function (_ it)
+ (all _.composite
+ it
+ (_.checkcast $String)
+ )))
+ update_size! (is (Bytecode Any)
+ (all _.composite
+ _.dup
+ $String::length
+ _.dup2_x1
+ _.pop2
+ _.iadd
+ ))
+ new_StringBuilder (is (Bytecode Any)
+ (all _.composite
+ (_.new $StringBuilder)
+ _.dup_x1
+ _.swap
+ (_.invokespecial $StringBuilder "<init>" (type.method [(list) (list type.int) type.void (list)]))
+ ))
+ compose_part! (is (Bytecode Any)
+ (all _.composite
+ _.swap
+ (_.invokevirtual $StringBuilder "append" (type.method [(list) (list ..$String) $StringBuilder (list)]))
+ ))]
+ (|>> (|.when (list)
+ (_.string "")
+
+ (list single)
+ single
+
+ (list left right)
+ (all _.composite
+ left (_.checkcast $String)
+ right (_.checkcast $String)
+ (_.invokevirtual ..$String "concat" (type.method [(list) (list ..$String) ..$String (list)])))
+
+ parts
+ (do [! _.monad]
+ [_ (_.int (.i64 +0))
+ _ (monad.each ! (is (-> (Bytecode Any)
+ (Bytecode Any))
+ (function (_ it)
+ (all _.composite
+ (add_part! it)
+ update_size!
+ )))
+ (list.reversed parts))
+ _ new_StringBuilder
+ _ (monad.each ! (function.constant compose_part!)
+ parts)]
+ (_.invokevirtual $StringBuilder "toString" (type.method [(list) (list) ..$String (list)])))
+ ))))
(def (text::clip [offset! length! subject!])
(Trinary (Bytecode Any))
@@ -367,7 +426,7 @@
(-> Bundle Bundle)
(|>> (dictionary.has "text_=#|generation" (binary ..text::=))
(dictionary.has "text_<#|generation" (binary ..text::<))
- (dictionary.has "text_composite#|generation" (binary ..text::concat))
+ (dictionary.has "text_composite#|generation" (variadic ..text::composite))
(dictionary.has "text_index#|generation" (trinary ..text::index))
(dictionary.has "text_size#|generation" (unary ..text::size))
(dictionary.has "text_char#|generation" (binary ..text::char))