`f:arity' now considers partial applications

master
Mike Gerwitz 2014-11-29 01:16:59 -05:00
parent f62e6a8e33
commit c64cefe931
3 changed files with 55 additions and 32 deletions

View File

@ -28,21 +28,28 @@
<!-- <!--
Attempt to retrieve arity of dynamic function Attempt to retrieve arity of dynamic function @var{fnref}
The input must be a function reference. Partially applied function @var{fnref} must be a dynamic function reference satisfying
references will have an arity equivalent to the remaining parameters @code{f:is-ref}. Partially applied function references will have an
in the original function. arity equivalent to the free parameters in the target function.
If the arity cannot be determined, -1 is returned.
--> -->
<function name="f:arity" as="xs:decimal"> <function name="f:arity" as="xs:integer">
<param name="fnref" as="element(f:ref)" /> <param name="fnref" as="item()+" />
<sequence select="if ( $fnref/@arity ) then <variable name="ref" as="element( f:ref )"
$fnref/@arity select="$fnref[ 1 ]" />
<variable name="arity" as="xs:integer"
select="$ref/@arity" />
<variable name="partial" as="xs:integer"
select="if ( $ref/@partial ) then
$ref/@partial
else else
-1" /> 0" />
<sequence select="$arity - $partial" />
</function> </function>
</stylesheet> </stylesheet>

View File

@ -71,12 +71,15 @@
<sequence select="$args" /> <sequence select="$args" />
</variable> </variable>
<variable name="argn" as="xs:decimal" <!-- note that, if FNREF is partially applied, then this arity
select="count( $argout )" /> represents the arity of the partially applied function, _not_
the target function -->
<variable name="arity" as="xs:decimal" <variable name="arity" as="xs:integer"
select="f:arity( $ref )" /> select="f:arity( $ref )" />
<variable name="argn" as="xs:integer"
select="count( $args )" />
<choose> <choose>
<when test="$argn eq $arity"> <when test="$argn eq $arity">
<sequence select="_f:apply-partial( $ref, $argout )" /> <sequence select="_f:apply-partial( $ref, $argout )" />
@ -87,7 +90,7 @@
select="$ref"> select="$ref">
<with-param name="args" select="$argout" /> <with-param name="args" select="$argout" />
<with-param name="arity" select="$arity" /> <with-param name="arity" select="$arity" />
<with-param name="argn" select="$argn" /> <with-param name="argn" select="count( $argout )" />
</apply-templates> </apply-templates>
</when> </when>
@ -96,7 +99,7 @@
<sequence select="$ref/@*" /> <sequence select="$ref/@*" />
<attribute name="partial" <attribute name="partial"
select="count( $args )" /> select="count( $argout )" />
<sequence select="$ref/*" /> <sequence select="$ref/*" />
</f:ref> </f:ref>

View File

@ -31,6 +31,13 @@
select="namespace-uri-for-prefix( select="namespace-uri-for-prefix(
'foo', root(.)/element() )" /> 'foo', root(.)/element() )" />
<variable name="test-arity"
select="5" />
<variable name="test-fn"
select="f:make-ref( QName( $foo-uri, 'foo:bar' ),
$test-arity )" />
<scenario label="f:arity"> <scenario label="f:arity">
<scenario label="given a proper function reference"> <scenario label="given a proper function reference">
@ -39,32 +46,38 @@
<!-- test our format directly; do not rely on the <!-- test our format directly; do not rely on the
apply-gen code --> apply-gen code -->
<variable name="fnref"
select="f:make-ref( QName( $foo-uri, 'foo:bar' ),
$test-arity )" />
<call function="f:arity"> <call function="f:arity">
<param name="fnref" <param name="fnref" select="$test-fn" />
select="$fnref" />
</call> </call>
<expect label="provides function arity" <expect label="provides function arity"
test="$x:result = $test-arity" /> select="$test-arity" />
</scenario> </scenario>
<scenario label="given a function reference with no defined arity"> <scenario label="given a partially applied function reference">
<variable name="fnref">
<f:ref><foo:bar /></f:ref>
</variable>
<call function="f:arity"> <call function="f:arity">
<param name="fnref" <param name="fnref"
select="$fnref" /> select="f:apply( $test-fn, 1, 2 )" />
</call> </call>
<expect label="returns -1" <expect label="provides arity of the target function minus the
test="$x:result = -1" /> number of bound parameters"
select="$test-arity - 2" />
</scenario>
<scenario label="given a multiply-partially-applied function reference">
<call function="f:arity">
<param name="fnref"
select="f:apply(
f:apply( $test-fn, 1, 2 ),
3 )" />
</call>
<expect label="provides arity of the target function minus the
number of bound parameters"
select="$test-arity - 3" />
</scenario> </scenario>
</scenario> </scenario>
</description> </description>