diff options
author | Eduardo Julian | 2019-12-28 22:27:09 -0400 |
---|---|---|
committer | Eduardo Julian | 2019-12-28 22:27:09 -0400 |
commit | 84ea12c2960cc7460de81087a6e53bcc6d37a3d6 (patch) | |
tree | 2a2b93dad3b4cb44aa641a0197211afb694ff7fc /new-luxc/source/luxc/lang | |
parent | ecb53b05a226d8d3d8e612f949cb3ad6ac0600ce (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.lux | 100 |
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)) |