Vasily Chekalkin wrote:
1. Refactor 'junction_comparision_helper' to 'get_bool' vtable.
2. Remove 'prefix:?' and 'prefix:!' overrides. Parrot DTRT without them.
3. Replace 'junction_comparision_helper' with 'infix_junction_helper'.
And again. After comments from Pm I remade 'get_bool' to short-circuit
version. Noting else changed from previous version.
--
Bacek
diff --git a/languages/perl6/src/classes/Junction.pir b/languages/perl6/src/classes/Junction.pir
index 9e5baca..d18b14e 100644
--- a/languages/perl6/src/classes/Junction.pir
+++ b/languages/perl6/src/classes/Junction.pir
@@ -154,6 +154,10 @@ Clone v-table method.
.end
+.sub 'get_string' :method :vtable
+ .return self.'perl'()
+.end
+
=item perl()
Returns a Perl representation of a junction.
@@ -208,6 +212,80 @@ Returns a Perl representation of a junction.
.return (res)
.end
+=item
+
+Override get_bool for Junction
+
+=cut
+
+.sub 'get_bool' :method :vtable
+ # We need to find how many values are equal.
+ .local pmc values
+ .local pmc it
+
+ # get values
+ values = self.'values'()
+ it = iter values
+
+ # Now go by juction type to short-circuited version.
+ .local int type
+ type = self.'!type'()
+ if type == JUNCTION_TYPE_ALL goto all
+ if type == JUNCTION_TYPE_ANY goto any
+ if type == JUNCTION_TYPE_ONE goto one
+ if type == JUNCTION_TYPE_NONE goto none
+
+ all:
+ # Check iter while prefix:? is True.
+ all_loop:
+ unless it goto ret_true
+ $P0 = shift it
+ $I0 = 'prefix:?'($P0)
+ if $I0 goto all_loop
+ goto ret_false
+
+ any:
+ # Check iter while prefix:? is False.
+ any_loop:
+ unless it goto ret_false
+ $P0 = shift it
+ $I0 = 'prefix:?'($P0)
+ unless $I0 goto any_loop
+ goto ret_true
+
+ one:
+ # Check iter while count of True less than one.
+ .local int count
+ count = 0
+ one_loop:
+ unless it goto check_count
+ $P0 = shift it
+ $I0 = 'prefix:?'($P0)
+ count += $I0
+ if count > 1 goto ret_false
+ goto one_loop
+
+ check_count:
+ if count == 1 goto ret_true
+ goto ret_false
+
+ none:
+ # Check iter while prefix:? is False.
+ none_loop:
+ unless it goto ret_true
+ $P0 = shift it
+ $I0 = 'prefix:?'($P0)
+ unless $I0 goto none_loop
+ goto ret_true
+
+
+ ret_true:
+ $P0 = get_hll_global ['Bool'], 'True'
+ .return($P0)
+ ret_false:
+ $P0 = get_hll_global ['Bool'], 'False'
+ .return($P0)
+.end
=back
@@ -457,8 +535,8 @@ Override not for junctions.
.sub 'prefix:!' :multi('Junction')
.param pmc j
- $P0 = find_global 'prefix:!'
- .return unary_junction_helper($P0, j)
+ $P0 = j.'get_bool'()
+ .return 'prefix:!'($P0)
.end
@@ -509,8 +587,8 @@ Override boolification for junctions.
.sub 'prefix:?' :multi('Junction')
.param pmc j
- $P0 = find_global 'prefix:?'
- .return unary_junction_helper($P0, j)
+ $P0 = j.'get_bool'()
+ .return ($P0)
.end
@@ -1080,21 +1158,21 @@ Override numerical equality for junctions.
.param pmc j1
.param pmc j2
$P0 = find_global "infix:=="
- .return junction_comparrison_helper($P0, j1, j2, 0)
+ .return infix_junction_helper($P0, j1, j2, 0)
.end
.sub 'infix:==' :multi('Junction',_)
.param pmc j
.param pmc x
$P0 = find_global "infix:=="
- .return junction_comparrison_helper($P0, j, x, 0)
+ .return infix_junction_helper($P0, j, x, 0)
.end
.sub 'infix:==' :multi(_,'Junction')
.param pmc x
.param pmc j
$P0 = find_global "infix:=="
- .return junction_comparrison_helper($P0, j, x, 1)
+ .return infix_junction_helper($P0, j, x, 1)
.end
@@ -1108,21 +1186,21 @@ Override numerical inequality for junctions.
.param pmc j1
.param pmc j2
$P0 = find_global "infix:!="
- .return junction_comparrison_helper($P0, j1, j2, 0)
+ .return infix_junction_helper($P0, j1, j2, 0)
.end
.sub 'infix:!=' :multi('Junction',_)
.param pmc j
.param pmc x
$P0 = find_global "infix:!="
- .return junction_comparrison_helper($P0, j, x, 0)
+ .return infix_junction_helper($P0, j, x, 0)
.end
.sub 'infix:!=' :multi(_,'Junction')
.param pmc x
.param pmc j
$P0 = find_global "infix:!="
- .return junction_comparrison_helper($P0, j, x, 1)
+ .return infix_junction_helper($P0, j, x, 1)
.end
@@ -1136,21 +1214,21 @@ Override numerical greater than for junctions.
.param pmc j1
.param pmc j2
$P0 = find_global "infix:>"
- .return junction_comparrison_helper($P0, j1, j2, 0)
+ .return infix_junction_helper($P0, j1, j2, 0)
.end
.sub 'infix:>' :multi('Junction',_)
.param pmc j
.param pmc x
$P0 = find_global "infix:>"
- .return junction_comparrison_helper($P0, j, x, 0)
+ .return infix_junction_helper($P0, j, x, 0)
.end
.sub 'infix:>' :multi(_,'Junction')
.param pmc x
.param pmc j
$P0 = find_global "infix:>"
- .return junction_comparrison_helper($P0, j, x, 1)
+ .return infix_junction_helper($P0, j, x, 1)
.end
@@ -1164,21 +1242,21 @@ Override numerical less than for junctions.
.param pmc j1
.param pmc j2
$P0 = find_global "infix:<"
- .return junction_comparrison_helper($P0, j1, j2, 0)
+ .return infix_junction_helper($P0, j1, j2, 0)
.end
.sub 'infix:<' :multi('Junction',_)
.param pmc j
.param pmc x
$P0 = find_global "infix:<"
- .return junction_comparrison_helper($P0, j, x, 0)
+ .return infix_junction_helper($P0, j, x, 0)
.end
.sub 'infix:<' :multi(_,'Junction')
.param pmc x
.param pmc j
$P0 = find_global "infix:<"
- .return junction_comparrison_helper($P0, j, x, 1)
+ .return infix_junction_helper($P0, j, x, 1)
.end
@@ -1192,21 +1270,21 @@ Override numerical greater than or equal to for junctions.
.param pmc j1
.param pmc j2
$P0 = find_global "infix:>="
- .return junction_comparrison_helper($P0, j1, j2, 0)
+ .return infix_junction_helper($P0, j1, j2, 0)
.end
.sub 'infix:>=' :multi('Junction',_)
.param pmc j
.param pmc x
$P0 = find_global "infix:>="
- .return junction_comparrison_helper($P0, j, x, 0)
+ .return infix_junction_helper($P0, j, x, 0)
.end
.sub 'infix:>=' :multi(_,'Junction')
.param pmc x
.param pmc j
$P0 = find_global "infix:>="
- .return junction_comparrison_helper($P0, j, x, 1)
+ .return infix_junction_helper($P0, j, x, 1)
.end
@@ -1220,21 +1298,21 @@ Override numerical less than or equal to for junctions.
.param pmc j1
.param pmc j2
$P0 = find_global "infix:<="
- .return junction_comparrison_helper($P0, j1, j2, 0)
+ .return infix_junction_helper($P0, j1, j2, 0)
.end
.sub 'infix:<=' :multi('Junction',_)
.param pmc j
.param pmc x
$P0 = find_global "infix:<="
- .return junction_comparrison_helper($P0, j, x, 0)
+ .return infix_junction_helper($P0, j, x, 0)
.end
.sub 'infix:<=' :multi(_,'Junction')
.param pmc x
.param pmc j
$P0 = find_global "infix:<="
- .return junction_comparrison_helper($P0, j, x, 1)
+ .return infix_junction_helper($P0, j, x, 1)
.end
@@ -1248,21 +1326,21 @@ Override string equality for junctions.
.param pmc j1
.param pmc j2
$P0 = find_global "infix:eq"
- .return junction_comparrison_helper($P0, j1, j2, 0)
+ .return infix_junction_helper($P0, j1, j2, 0)
.end
.sub 'infix:eq' :multi('Junction',_)
.param pmc j
.param pmc x
$P0 = find_global "infix:eq"
- .return junction_comparrison_helper($P0, j, x, 0)
+ .return infix_junction_helper($P0, j, x, 0)
.end
.sub 'infix:eq' :multi(_,'Junction')
.param pmc x
.param pmc j
$P0 = find_global "infix:eq"
- .return junction_comparrison_helper($P0, j, x, 1)
+ .return infix_junction_helper($P0, j, x, 1)
.end
@@ -1276,21 +1354,21 @@ Override string inequality for junctions.
.param pmc j1
.param pmc j2
$P0 = find_global "infix:ne"
- .return junction_comparrison_helper($P0, j1, j2, 0)
+ .return infix_junction_helper($P0, j1, j2, 0)
.end
.sub 'infix:ne' :multi('Junction',_)
.param pmc j
.param pmc x
$P0 = find_global "infix:ne"
- .return junction_comparrison_helper($P0, j, x, 0)
+ .return infix_junction_helper($P0, j, x, 0)
.end
.sub 'infix:ne' :multi(_,'Junction')
.param pmc x
.param pmc j
$P0 = find_global "infix:ne"
- .return junction_comparrison_helper($P0, j, x, 1)
+ .return infix_junction_helper($P0, j, x, 1)
.end
@@ -1304,21 +1382,21 @@ Override string less than for junctions.
.param pmc j1
.param pmc j2
$P0 = find_global "infix:lt"
- .return junction_comparrison_helper($P0, j1, j2, 0)
+ .return infix_junction_helper($P0, j1, j2, 0)
.end
.sub 'infix:lt' :multi('Junction',_)
.param pmc j
.param pmc x
$P0 = find_global "infix:lt"
- .return junction_comparrison_helper($P0, j, x, 0)
+ .return infix_junction_helper($P0, j, x, 0)
.end
.sub 'infix:lt' :multi(_,'Junction')
.param pmc x
.param pmc j
$P0 = find_global "infix:lt"
- .return junction_comparrison_helper($P0, j, x, 1)
+ .return infix_junction_helper($P0, j, x, 1)
.end
@@ -1332,21 +1410,21 @@ Override string greater than for junctions.
.param pmc j1
.param pmc j2
$P0 = find_global "infix:gt"
- .return junction_comparrison_helper($P0, j1, j2, 0)
+ .return infix_junction_helper($P0, j1, j2, 0)
.end
.sub 'infix:gt' :multi('Junction',_)
.param pmc j
.param pmc x
$P0 = find_global "infix:gt"
- .return junction_comparrison_helper($P0, j, x, 0)
+ .return infix_junction_helper($P0, j, x, 0)
.end
.sub 'infix:gt' :multi(_,'Junction')
.param pmc x
.param pmc j
$P0 = find_global "infix:gt"
- .return junction_comparrison_helper($P0, j, x, 1)
+ .return infix_junction_helper($P0, j, x, 1)
.end
@@ -1360,21 +1438,21 @@ Override string less than or equal for junctions.
.param pmc j1
.param pmc j2
$P0 = find_global "infix:le"
- .return junction_comparrison_helper($P0, j1, j2, 0)
+ .return infix_junction_helper($P0, j1, j2, 0)
.end
.sub 'infix:le' :multi('Junction',_)
.param pmc j
.param pmc x
$P0 = find_global "infix:le"
- .return junction_comparrison_helper($P0, j, x, 0)
+ .return infix_junction_helper($P0, j, x, 0)
.end
.sub 'infix:le' :multi(_,'Junction')
.param pmc x
.param pmc j
$P0 = find_global "infix:le"
- .return junction_comparrison_helper($P0, j, x, 1)
+ .return infix_junction_helper($P0, j, x, 1)
.end
@@ -1388,21 +1466,21 @@ Override string greater than or equal for junctions.
.param pmc j1
.param pmc j2
$P0 = find_global "infix:ge"
- .return junction_comparrison_helper($P0, j1, j2, 0)
+ .return infix_junction_helper($P0, j1, j2, 0)
.end
.sub 'infix:ge' :multi('Junction',_)
.param pmc j
.param pmc x
$P0 = find_global "infix:ge"
- .return junction_comparrison_helper($P0, j, x, 0)
+ .return infix_junction_helper($P0, j, x, 0)
.end
.sub 'infix:ge' :multi(_,'Junction')
.param pmc x
.param pmc j
$P0 = find_global "infix:ge"
- .return junction_comparrison_helper($P0, j, x, 1)
+ .return infix_junction_helper($P0, j, x, 1)
.end
@@ -1436,7 +1514,7 @@ loop:
sa:
$P0 = op_sub(x, cur_elem)
nsa:
- ResultHash[$P0] = 1
+ ResultHash[$P0] = $P0
inc i
goto loop
loop_end:
@@ -1456,6 +1534,7 @@ loop_end:
nv_loop:
unless iterator goto nv_loop_end
$P0 = shift iterator
+ $P0 = ResultHash[$P0]
push new_values, $P0
goto nv_loop
nv_loop_end:
@@ -1464,66 +1543,6 @@ nv_loop_end:
.return(new_junc)
.end
-# Helper sub for junction comparrisons.
-.sub junction_comparrison_helper :anon
- .param pmc op_func
- .param pmc j
- .param pmc x
- .param int second_arg
-
- # We need to find how many values are equal.
- .local pmc values
- .local int num_equal
- .local int count
- .local int i
- values = j.'values'()
- count = elements values
- i = 0
- num_equal = 0
-loop:
- if i >= count goto end_loop
- $P0 = values[i]
- if second_arg goto sa
- $I0 = op_func($P0, x)
- goto not_sa
-sa:
- $I0 = op_func(x, $P0)
-not_sa:
- num_equal += $I0
- inc i
- goto loop
-end_loop:
-
- # Now go by juction type.
- .local int type
- type = j.'!type'()
- if type == JUNCTION_TYPE_ALL goto all
- if type == JUNCTION_TYPE_ANY goto any
- if type == JUNCTION_TYPE_ONE goto one
- if type == JUNCTION_TYPE_NONE goto none
-
-all:
- if num_equal == count goto ret_true
- goto ret_false
-any:
- if num_equal > 0 goto ret_true
- goto ret_false
-one:
- if num_equal == 1 goto ret_true
- goto ret_false
-none:
- if num_equal == 0 goto ret_true
- goto ret_false
-
-ret_true:
- $P0 = get_hll_global ['Bool'], 'True'
- .return($P0)
-ret_false:
- $P0 = get_hll_global ['Bool'], 'False'
- .return($P0)
-.end
-
-
# Helper sub for implementing unary operators.
.sub unary_junction_helper :anon
.param pmc op_sub
@@ -1548,7 +1567,7 @@ loop:
if i >= count goto loop_end
cur_elem = values[i]
$P0 = op_sub(cur_elem)
- ResultHash[$P0] = 1
+ ResultHash[$P0] = $P0
inc i
goto loop
loop_end:
@@ -1568,6 +1587,7 @@ loop_end:
nv_loop:
unless iterator goto nv_loop_end
$P0 = shift iterator
+ $P0 = ResultHash[$P0]
push new_values, $P0
goto nv_loop
nv_loop_end:
@@ -1576,7 +1596,7 @@ nv_loop_end:
.return(new_junc)
.end
-
+
=back
=cut