Permalink
Browse files

add preliminary cell support

  • Loading branch information...
Whiteknight committed Nov 17, 2009
1 parent 6591db1 commit ce63abc2eba2f1463649d80d08668ebde0d692c2
Showing with 129 additions and 44 deletions.
  1. +88 −40 src/internals/aggregates.pir
  2. +25 −1 src/parser/actions.pm
  3. +16 −3 src/parser/grammar.pg
@@ -11,13 +11,101 @@
.return(ary)
.end
+.sub '!matrix_from_rows'
+ .param pmc ary :slurpy
+ .local pmc lengths
+ .local int has_numbers
+ .local int has_strings
+ .local int has_complex
+
+ # If there are no rows, just return an empty matrix
+ $I0 = ary
+ unless $I0 == 0 goto construct_the_matrix
+ $P0 = new ['NumMatrix2D']
+ .return($P0)
+
+ construct_the_matrix:
+ (lengths, has_numbers, has_strings, has_complex) = '!_get_rows_info'(ary)
+ unless has_numbers goto dont_check_length
+ '!_verify_array_lengths_equal'(lengths)
+
+ dont_check_length:
+ if has_complex goto build_complex_matrix
+ if has_strings goto build_string_matrix
+ .tailcall '!_build_numerical_matrix'(ary)
+ build_string_matrix:
+ .tailcall '!_build_string_matrix'(ary)
+ build_complex_matrix:
+ if has_strings goto cant_have_both
+ .tailcall '!_build_complex_matrix'(ary)
+ cant_have_both:
+ _error_all("Cannot have both complex and string values in one matrix")
+.end
+
+.sub '!matrix'
+ .param int x
+ .param int y
+ .param pmc args :slurpy
+ $P0 = new ['NumMatrix2D']
+ $P0.'initialize_from_array'(x, y, args)
+ .return($P0)
+.end
+
+
.sub '!matrix_row'
.param pmc args :slurpy
$P0 = new ['matrix_row']
$P0.'build_row'(args)
.return($P0)
.end
+.sub '!cell_from_rows'
+ .param pmc rows :slurpy
+ .local pmc cell
+ .local pmc row
+ .local int length
+ cell = new ['PMCMatrix2D']
+ $I0 = rows
+ if $I0 == 0 goto new_empty_cell
+ myiter = iter rows
+ row = shift myiter
+ length = row
+ $I0 = 0
+ loop_top:
+ '!_insert_cell_row'(cell, row, $I0)
+ unless myiter goto loop_bottom
+ row = shift myiter
+ $I1 = row
+ if $I1 != length goto lengths_not_equal
+ goto loop_top
+ loop_bottom:
+ new_empty_cell:
+ .return(cell)
+ lengths_not_equal:
+ _error_all("Row lengths must be equal ", $I1, " != ", length)
+.end
+
+.sub '!_insert_cell_row'
+ .param pmc cell
+ .param pmc row
+ .param int idx
+ .local int length
+ length = row
+ dec length
+ loop_top:
+ $P0 = row[length]
+ cell[idx;length] = $P0
+ if length == 0 goto loop_bottom
+ dec length
+ goto loop_top
+ loop_bottom:
+.end
+
+.sub '!cell_row'
+ .param pmc args :slurpy
+ .return(args)
+.end
+
.sub '!_get_rows_info'
.param pmc ary
@@ -138,46 +226,6 @@
.return(matrix)
.end
-.sub '!matrix_from_rows'
- .param pmc ary :slurpy
- .local pmc lengths
- .local int has_numbers
- .local int has_strings
- .local int has_complex
-
- # If there are no rows, just return an empty matrix
- $I0 = ary
- unless $I0 == 0 goto construct_the_matrix
- $P0 = new ['NumMatrix2D']
- .return($P0)
-
- construct_the_matrix:
- (lengths, has_numbers, has_strings, has_complex) = '!_get_rows_info'(ary)
- unless has_numbers goto dont_check_length
- '!_verify_array_lengths_equal'(lengths)
-
- dont_check_length:
- if has_complex goto build_complex_matrix
- if has_strings goto build_string_matrix
- .tailcall '!_build_numerical_matrix'(ary)
- build_string_matrix:
- .tailcall '!_build_string_matrix'(ary)
- build_complex_matrix:
- if has_strings goto cant_have_both
- .tailcall '!_build_complex_matrix'(ary)
- cant_have_both:
- _error_all("Cannot have both complex and string values in one matrix")
-.end
-
-.sub '!matrix'
- .param int x
- .param int y
- .param pmc args :slurpy
- $P0 = new ['NumMatrix2D']
- $P0.'initialize_from_array'(x, y, args)
- .return($P0)
-.end
-
# used in the parser
.sub '_new_empty_array'
$P0 = new ['ResizablePMCArray']
View
@@ -661,7 +661,7 @@ method named_field($/) {
make $past;
}
-method array_constructor($/, $key) {
+method array_constructor($/) {
my $past := PAST::Op.new(
:name('!matrix_from_rows'),
:pasttype('call'),
@@ -685,6 +685,30 @@ method array_row($/) {
make $past;
}
+method cell_constructor($/) {
+ my $past := PAST::Op.new(
+ :name('!cell_from_rows'),
+ :pasttype('call'),
+ :node($/)
+ );
+ for $<cell_row> {
+ $past.push($($_));
+ }
+ make $past;
+}
+
+method cell_row($/) {
+ my $past := PAST::Op.new(
+ :name('!cell_row'),
+ :pasttype('call'),
+ :node($/)
+ );
+ for $<expression> {
+ $past.push($($_));
+ }
+ make $past;
+}
+
method range_constructor($/, $key) {
my $past := PAST::Op.new(
:name('!range_constructor_' ~ $key),
View
@@ -153,6 +153,7 @@ rule term {
| <string_constant> {*} #= string_constant
| <hash_constructor> {*} #= hash_constructor
| <array_constructor> {*} #= array_constructor
+ | <cell_constructor> {*} #= cell_constructor
| <function_handle> {*} #= function_handle
| <anon_func_constructor> {*} #= anon_func_constructor
| <sub_or_var> {*} #= sub_or_var
@@ -279,16 +280,28 @@ rule named_field {
# TODO: Should probably be renamed "matrix_constructor", but that's nitpickery
rule array_constructor {
'['
- {*} #= open
- [ <array_row> [<terminator> <array_row>]* ]? ']'
- {*} #= close
+ [ <array_row> [<terminator> <array_row>]* ]?
+ ']'
+ {*}
}
rule array_row {
<expression> [','? <expression>]*
{*}
}
+rule cell_constructor {
+ '{'
+ [ <cell_row> [<terminator> <cell_row>]* ]?
+ '}'
+ {*}
+}
+
+rule cell_row {
+ <expression> [','? <expression>]*
+ {*}
+}
+
rule range_constructor {
<subexpression> ':' <subexpression> ':' <subexpression> {*} #= three
| <subexpression> ':' <subexpression> {*} #= two

0 comments on commit ce63abc

Please sign in to comment.