compiler: Correct handling of TRUE matches
There was a bug whereby TRUE matches would keep whatever value was being matched on, even if it was not a boolean. That was an oversight from the proof-of-concept code, and this fixes it; that's why this is behind a flag! This also adjusts the class aliasing optimization so that it doesn't check for a `TRUE` symbol name, which was a bad idea to begin with. This change also ends up expanding `lv:match[@value="TRUE"]` into the long form, where it didn't previously; this will result in slightly larger xmlo files in some cases, but it's nothing significant, and it does not impact compilation times.main
parent
37977a8816
commit
2ad0d1425a
|
@ -20,6 +20,14 @@ Compiler
|
||||||
--------
|
--------
|
||||||
- Make Summary Page less chatty.
|
- Make Summary Page less chatty.
|
||||||
- Fix incorrect package name for generated worksheet packages.
|
- Fix incorrect package name for generated worksheet packages.
|
||||||
|
- Restrict `TRUE`-match optimization to classification matches (class
|
||||||
|
composition).
|
||||||
|
- This was mistakenly not considering the domain of the match, and
|
||||||
|
therefore was applying the optimization in situations where it should
|
||||||
|
not. Results of previous classifications are currently the only place
|
||||||
|
we guarantee a boolean value.
|
||||||
|
- Apply classification alias optimization to any `1`-valued constant match.
|
||||||
|
- Previously applied only to `TRUE`.
|
||||||
|
|
||||||
Summary Page
|
Summary Page
|
||||||
------------
|
------------
|
||||||
|
|
|
@ -541,7 +541,6 @@
|
||||||
-->
|
-->
|
||||||
<template mode="compile" priority="7"
|
<template mode="compile" priority="7"
|
||||||
match="lv:classify[ count( lv:match ) = 1
|
match="lv:classify[ count( lv:match ) = 1
|
||||||
and lv:match/@value='TRUE'
|
|
||||||
and not( lv:match/@preproc:inline ) ]">
|
and not( lv:match/@preproc:inline ) ]">
|
||||||
<param name="symtable-map" as="map(*)" tunnel="yes" />
|
<param name="symtable-map" as="map(*)" tunnel="yes" />
|
||||||
|
|
||||||
|
@ -550,9 +549,18 @@
|
||||||
<variable name="src-sym" as="element( preproc:sym )"
|
<variable name="src-sym" as="element( preproc:sym )"
|
||||||
select="$symtable-map( $src )" />
|
select="$symtable-map( $src )" />
|
||||||
|
|
||||||
|
<variable name="c" as="element()?"
|
||||||
|
select="lv:match/c:*" />
|
||||||
|
|
||||||
|
<variable name="cmpval" as="xs:float?"
|
||||||
|
select="if ( exists( $c/c:value-of ) ) then
|
||||||
|
$symtable-map( $c/c:value-of/@name )/@value
|
||||||
|
else
|
||||||
|
$c/c:const/@value" />
|
||||||
|
|
||||||
<choose>
|
<choose>
|
||||||
<!-- we only handle aliasing of other classifications -->
|
<!-- we only handle aliasing of other classifications -->
|
||||||
<when test="$src-sym/@type = 'cgen'">
|
<when test="$src-sym/@type = 'cgen' and $cmpval = 1">
|
||||||
<sequence select="$compiler:nl" />
|
<sequence select="$compiler:nl" />
|
||||||
|
|
||||||
<!-- simply alias the @yields -->
|
<!-- simply alias the @yields -->
|
||||||
|
@ -850,8 +858,10 @@
|
||||||
<param name="symtable-map" as="map(*)" />
|
<param name="symtable-map" as="map(*)" />
|
||||||
<param name="match" as="element( lv:match )" />
|
<param name="match" as="element( lv:match )" />
|
||||||
|
|
||||||
<variable name="dim" as="xs:integer"
|
<variable name="sym" as="element( preproc:sym )"
|
||||||
select="$symtable-map( $match/@on )/@dim" />
|
select="$symtable-map( $match/@on )" />
|
||||||
|
<variable name="dim" as="xs:integer" select="$sym/@dim" />
|
||||||
|
<variable name="type" as="xs:string" select="$sym/@type" />
|
||||||
|
|
||||||
<variable name="inner" as="xs:string"
|
<variable name="inner" as="xs:string"
|
||||||
select="compiler:match-name-on( $symtable-map, $match )" />
|
select="compiler:match-name-on( $symtable-map, $match )" />
|
||||||
|
@ -862,11 +872,6 @@
|
||||||
select="if ( $dim = 2 ) then 'NN' else 'N'" />
|
select="if ( $dim = 2 ) then 'NN' else 'N'" />
|
||||||
|
|
||||||
<choose>
|
<choose>
|
||||||
<!-- only basic TRUE equality can be used verbatim -->
|
|
||||||
<when test="$match/@value = 'TRUE'">
|
|
||||||
<sequence select="$inner" />
|
|
||||||
</when>
|
|
||||||
|
|
||||||
<when test="$match/@anyOf">
|
<when test="$match/@anyOf">
|
||||||
<variable name="anyof" as="xs:string"
|
<variable name="anyof" as="xs:string"
|
||||||
select="compiler:compile-anyof( $symtable-map, $match )" />
|
select="compiler:compile-anyof( $symtable-map, $match )" />
|
||||||
|
@ -924,11 +929,28 @@
|
||||||
$match/parent::lv/classify/@as, '''' )" />
|
$match/parent::lv/classify/@as, '''' )" />
|
||||||
</if>
|
</if>
|
||||||
|
|
||||||
|
<!-- Note: we currently only check for cgen, that's that's the only
|
||||||
|
type we can guarantee to be boolean; params can have any value
|
||||||
|
passed in and we are not necessarily validating the
|
||||||
|
domain. Until that is in place, it's too dangerous. We also
|
||||||
|
need more information in the symbol table. -->
|
||||||
|
<variable name="boolmatch" as="xs:boolean"
|
||||||
|
select="$type = 'cgen'" />
|
||||||
|
|
||||||
<choose>
|
<choose>
|
||||||
|
<!-- Boolean-TRUE matches need no translation; their values can be
|
||||||
|
used without modification. This allows primarily for
|
||||||
|
lower-cost class composition However, it's important that we do
|
||||||
|
this only when working with a boolean domain, otherwise we may
|
||||||
|
yield a value that is not in the domain {0,1}. -->
|
||||||
|
<when test="$boolmatch and $match/c:eq and $cval = 1">
|
||||||
|
<sequence select="$inner" />
|
||||||
|
</when>
|
||||||
|
|
||||||
<when test="$dim > 0">
|
<when test="$dim > 0">
|
||||||
<choose>
|
<choose>
|
||||||
<!-- negation, very common, so save some bytes -->
|
<!-- negation, very common, so save some bytes -->
|
||||||
<when test="$match/c:eq and $cval = 0">
|
<when test="$boolmatch and $match/c:eq and $cval = 0">
|
||||||
<sequence select="concat( $nf, '(', $inner, ')' )" />
|
<sequence select="concat( $nf, '(', $inner, ')' )" />
|
||||||
</when>
|
</when>
|
||||||
|
|
||||||
|
@ -942,7 +964,7 @@
|
||||||
<otherwise>
|
<otherwise>
|
||||||
<choose>
|
<choose>
|
||||||
<!-- negation, very common, so save some bytes -->
|
<!-- negation, very common, so save some bytes -->
|
||||||
<when test="$match/c:eq and $cval = 0">
|
<when test="$boolmatch and $match/c:eq and $cval = 0">
|
||||||
<sequence select="concat( 'n(', $inner, ')' )" />
|
<sequence select="concat( 'n(', $inner, ')' )" />
|
||||||
</when>
|
</when>
|
||||||
|
|
||||||
|
|
|
@ -596,9 +596,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<!-- expand lv:match/@value != 'TRUE' into a c:* expression to simpliy
|
<!-- expand lv:match/@value into a c:* expression to simplify static
|
||||||
optimizations -->
|
analysis -->
|
||||||
<template match="lv:match[ @value and @value != 'TRUE' ]"
|
<template match="lv:match[ @value ]"
|
||||||
mode="preproc:expand" priority="7">
|
mode="preproc:expand" priority="7">
|
||||||
|
|
||||||
<copy>
|
<copy>
|
||||||
|
|
Loading…
Reference in New Issue