aboutsummaryrefslogtreecommitdiff
path: root/new-luxc/source/luxc/lang
diff options
context:
space:
mode:
authorEduardo Julian2019-12-28 22:27:09 -0400
committerEduardo Julian2019-12-28 22:27:09 -0400
commit84ea12c2960cc7460de81087a6e53bcc6d37a3d6 (patch)
tree2a2b93dad3b4cb44aa641a0197211afb694ff7fc /new-luxc/source/luxc/lang
parentecb53b05a226d8d3d8e612f949cb3ad6ac0600ce (diff)
Optimized pattern-matching against variants.
Diffstat (limited to 'new-luxc/source/luxc/lang')
-rw-r--r--new-luxc/source/luxc/lang/translation/jvm/runtime.lux100
1 files changed, 54 insertions, 46 deletions
diff --git a/new-luxc/source/luxc/lang/translation/jvm/runtime.lux b/new-luxc/source/luxc/lang/translation/jvm/runtime.lux
index 78467022e..87a5d535c 100644
--- a/new-luxc/source/luxc/lang/translation/jvm/runtime.lux
+++ b/new-luxc/source/luxc/lang/translation/jvm/runtime.lux
@@ -169,56 +169,64 @@
_.ARETURN))
($d.method #$.Public $.staticM "pm_variant" (type.method [(list //.$Variant $Tag $Flag) $Value (list)])
(<| _.with-label (function (_ @loop))
- _.with-label (function (_ @just-return))
- _.with-label (function (_ @then))
- _.with-label (function (_ @further))
- _.with-label (function (_ @shorten))
- _.with-label (function (_ @wrong))
- (let [variant-partI (: (-> Nat Inst)
+ _.with-label (function (_ @perfect-match!))
+ _.with-label (function (_ @tags-match!))
+ _.with-label (function (_ @maybe-nested))
+ _.with-label (function (_ @mismatch!))
+ (let [$variant (_.ALOAD 0)
+ $tag (_.ILOAD 1)
+ $last? (_.ALOAD 2)
+
+ variant-partI (: (-> Nat Inst)
(function (_ idx)
(|>> (_.int (.int idx)) _.AALOAD)))
- tagI (: Inst
- (|>> (variant-partI 0) (_.unwrap type.int)))
- flagI (variant-partI 1)
- datumI (variant-partI 2)
- shortenI (|>> (_.ALOAD 0) tagI ## Get tag
- (_.ILOAD 1) _.ISUB ## Shorten tag
- (_.ALOAD 0) flagI ## Get flag
- (_.ALOAD 0) datumI ## Get value
- variantI ## Build sum
- _.ARETURN)
- update-tagI (|>> _.ISUB (_.ISTORE 1))
- update-variantI (|>> (_.ALOAD 0) datumI (_.CHECKCAST //.$Variant) (_.ASTORE 0))
- failureI (|>> _.NULL _.ARETURN)
- return-datumI (|>> (_.ALOAD 0) datumI _.ARETURN)])
- (|>> (_.label @loop)
- (_.ILOAD 1) ## tag
- (_.ALOAD 0) tagI ## tag, sumT
- _.DUP2 (_.IF_ICMPEQ @then)
- _.DUP2 (_.IF_ICMPGT @further)
- _.DUP2 (_.IF_ICMPLT @shorten)
- ## _.POP2
- failureI
- (_.label @then) ## tag, sumT
- (_.ALOAD 2) ## tag, sumT, wants-last?
- (_.ALOAD 0) flagI ## tag, sumT, wants-last?, is-last?
- (_.IF_ACMPEQ @just-return) ## tag, sumT
- (_.label @further) ## tag, sumT
- (_.ALOAD 0) flagI ## tag, sumT, last?
- (_.IFNULL @wrong) ## tag, sumT
- update-tagI
- update-variantI
- (_.GOTO @loop)
- (_.label @just-return) ## tag, sumT
- ## _.POP2
- return-datumI
- (_.label @shorten) ## tag, sumT
- (_.ALOAD 2) (_.IFNULL @wrong)
+ ::tag (: Inst
+ (|>> (variant-partI 0) (_.unwrap type.int)))
+ ::last? (variant-partI 1)
+ ::value (variant-partI 2)
+
+ super-nested-tag (|>> _.SWAP ## variant::tag, tag
+ _.ISUB)
+ super-nested (|>> super-nested-tag ## super-tag
+ $variant ::last? ## super-tag, super-last
+ $variant ::value ## super-tag, super-last, super-value
+ ..variantI)
+
+ update-$tag _.ISUB
+ update-$variant (|>> $variant ::value
+ (_.CHECKCAST //.$Variant)
+ (_.ASTORE 0))
+ iterate! (: (-> Label Inst)
+ (function (_ @loop)
+ (|>> update-$variant
+ update-$tag
+ (_.GOTO @loop))))
+
+ not-found _.NULL])
+ (|>> $tag ## tag
+ (_.label @loop)
+ $variant ::tag ## tag, variant::tag
+ _.DUP2 (_.IF_ICMPEQ @tags-match!) ## tag, variant::tag
+ _.DUP2 (_.IF_ICMPGT @maybe-nested) ## tag, variant::tag
+ $last? (_.IFNULL @mismatch!) ## tag, variant::tag
+ super-nested ## super-variant
+ _.ARETURN
+ (_.label @tags-match!) ## tag, variant::tag
+ $last? ## tag, variant::tag, last?
+ $variant ::last? ## tag, variant::tag, last?, variant::last?
+ (_.IF_ACMPEQ @perfect-match!) ## tag, variant::tag
+ (_.label @maybe-nested) ## tag, variant::tag
+ $variant ::last? ## tag, variant::tag, variant::last?
+ (_.IFNULL @mismatch!) ## tag, variant::tag
+ (iterate! @loop)
+ (_.label @perfect-match!) ## tag, variant::tag
## _.POP2
- shortenI
- (_.label @wrong) ## tag, sumT
+ $variant ::value
+ _.ARETURN
+ (_.label @mismatch!) ## tag, variant::tag
## _.POP2
- failureI)))
+ not-found
+ _.ARETURN)))
($d.method #$.Public $.staticM "tuple_left" (type.method [(list //.$Tuple $Index) $Value (list)])
(<| _.with-label (function (_ @loop))
_.with-label (function (_ @recursive))