Permalink
Browse files

Merge branch 'master' of git@github.com:Whiteknight/matrixy

  • Loading branch information...
2 parents ef9b28f + d3bf9ad commit 8a7ba1399dce9e0d535b3f236566b15bad9f40b2 @Whiteknight committed Jan 27, 2010
Showing with 446 additions and 246 deletions.
  1. +4 −1 matrixy.pir
  2. +23 −0 src/internals/aggregates.pir
  3. +116 −20 src/internals/dispatch.pir
  4. +239 −159 src/parser/actions.pm
  5. +30 −43 src/parser/grammar.pg
  6. +1 −18 t/2-function.t
  7. +2 −2 t/functions/cell.t
  8. +6 −0 t/functions/columns.t
  9. +6 −0 t/functions/rows.t
  10. +16 −0 t/syntax/cell.t
  11. +3 −3 t/syntax/varargin.t
View
@@ -73,6 +73,9 @@ object.
$P0 = box 0
set_hll_global ['Matrixy';'Grammar';'Actions'], '$?MATRIXSQUARE', $P0
+ $P0 = box 0
+ set_hll_global ['Matrixy';'Grammar';'Actions'], '$?LVALUECELL', $P0
+
# list of functions that we've compiled. We cache them to prevent needing
# to recompile.
# TODO: This isn't part of the parser, find a better namespace to hold this
@@ -132,7 +135,7 @@ to the Matrixy compiler.
# TODO: We might want to add this sequence as a method on the compiler
# object, so we can call it from a library load too.
# load start up file
-
+
errorsoff .PARROT_ERRORS_PARAM_COUNT_FLAG
errorsoff .PARROT_ERRORS_RESULT_COUNT_FLAG
$P0 = null
@@ -11,6 +11,11 @@
.return(ary)
.end
+.sub '!cell'
+ $P0 = new ['PMCMatrix2D']
+ .return($P0)
+.end
+
.sub '!matrix_from_rows'
.param pmc ary :slurpy
.local pmc lengths
@@ -78,6 +83,7 @@
row = shift myiter
$I1 = row
if $I1 != length goto lengths_not_equal
+ inc $I0
goto loop_top
loop_bottom:
new_empty_cell:
@@ -233,3 +239,20 @@
.return($P0)
.end
+.sub '_is_defined'
+ .param pmc item
+ if null item goto not_defined
+ $S0 = typeof item
+ if $S0 == "Undef" goto not_defined
+ .return(1)
+ not_defined:
+ .return(0)
+.end
+
+.sub '_integer_copy'
+ .param int i
+ $P0 = new 'Integer'
+ $P0 = i
+ .return($P0)
+.end
+
View
@@ -18,10 +18,21 @@ C<(5)>.
retrieve a value using the following syntax:
- foo = bar(1, 2)
+ bar
+ bar ...
+ bar(...)
+ bar{...}
+
+These are r-values only, not l-value assignment forms. bar could be
+a matrix, a cell array, a func handle, or a subroutine call. We will take
+the name of the variable and it's current value. Some rules:
+
+1) functions are stored in the Matrixy::builtins namespace and "var" will
+ be null here. Look up the function in the namespace and dispatch it
+2) matrices and cells will have non-null values here. They must be vivified
+ somewhere else.
+
-bar could be either a matrix or a subroutine. Handles all the idiosyncratic
-rules for these kinds of things in M.
=cut
@@ -39,14 +50,14 @@ rules for these kinds of things in M.
if null var goto not_a_var
.tailcall '!index_variable'(var, nargout, nargin, parens, args)
- # if it's not a variable, treat it like a sub and look that up.
+ # if it's not a pre-existing variable, see if we have a function
not_a_var:
sub_obj = '!lookup_function'(name)
- unless null sub_obj goto found_sub
- _error_all("'", name, "' undefined")
-
- found_sub:
+ if null sub_obj goto error_var_undefined
.tailcall sub_obj(nargout, nargin, args :flat)
+
+ error_var_undefined:
+ _error_all("'", name, "' undefined")
.end
=item !lookup_function(name)
@@ -68,7 +79,8 @@ found, null otherwise.
if $I0 goto _dispatch_found_sub
# Second, look for a locally-defined function
- sub_obj = get_hll_global ["Matrixy::functions"], name
+ # TODO: Fix this to be "Matrixy";"functions" instead
+ sub_obj = get_hll_global ["Matrixy";"functions"], name
$I0 = defined sub_obj
if $I0 goto _dispatch_found_sub
@@ -108,7 +120,13 @@ Handles equations of the following types:
a = var(b, ...)
-Returns the value
+Returns the value. Matrices can be indexed with foo(...) style, which returns
+the scalar item at that position. Cells can be indexed with foo{...} to return
+the item, or with foo(...) to return another cell containing those items.
+
+ foo parens == 0
+ foo(...) parens == 1
+ foo{...} parens == 2
=cut
@@ -119,24 +137,69 @@ Returns the value
.param int parens
.param pmc args
+ # TODO: We don't handle slices yet.
+
+ # Figure out which type it is, to determine where to go
$S0 = typeof var
- # If it's a function handle variable, dispatch it.
- unless $S0 == 'Sub' goto its_a_variable
- if parens == 1 goto execute_sub_handle
+ if $S0 == 'Sub' goto have_func_handle
+ if $S0 == 'PMCMatrix2D' goto have_cell_array
+ $I0 = does var, "matrix"
+ if $I0 == 1 goto have_matrix_type
+ $I0 = args
+ if $I0 != 0 goto error_index_scalar
.return(var)
- execute_sub_handle:
+
+ # For Subs, if we have parens execute it. Otherwise it's an error. If we
+ # want a sub reference, need to use the @ operator
+ have_func_handle:
+ if parens == 0 goto assign_func_handle
+ if parens == 2 goto error_func_not_cell
.tailcall var(nargout, nargin, args :flat)
+ assign_func_handle:
+ .return(var)
- # If it's an ordinary variable, do the indexing
- its_a_variable:
+ # For cell arrays the indexing is different depending on which brackets
+ # we use.
+ have_cell_array:
+ if parens == 1 goto index_cell_as_cell
+ if parens == 2 goto index_cell_as_matrix
+ .return(var)
+ index_cell_as_matrix:
+ .tailcall '!scalar_indexing'(var, args)
+ index_cell_as_cell:
+ # TODO: Do this right!
+ $P0 = '!scalar_indexing'(var, args)
+ $P1 = new ['PMCMatrix2D']
+ $P1[0;0] = $P0
+ .return($P1)
+
+ # Matrices can be indexed by () but not {}.
+ have_matrix_type:
+ if parens == 1 goto index_matrix_as_matrix
+ if parens == 2 goto error_matrix_not_cell
+ .return(var)
+ index_matrix_as_matrix:
+ .tailcall '!scalar_indexing'(var, args)
+
+ error_index_scalar:
+ _error_all("Cannot index a scalar")
+ error_func_not_cell:
+ _error_all("Cannot index function with {}")
+ error_matrix_not_cell:
+ _error_all("Cannot index matrix with {}")
+.end
+.sub '!scalar_indexing'
+ .param pmc var
+ .param pmc args
+
# If we only have a 1-ary index, we need to use a separate vector indexing
# algorithm instead of the nested matrix indexing.
$I0 = args
if $I0 == 0 goto non_indexing
if $I0 == 1 goto vector_indexing
if $I0 == 2 goto matrix_indexing
- _error_all("Only 0, 1, 2 indexes are supported")
+ _error_all("Only 0, 1, 2 indexes are currently supported")
non_indexing:
.return(var)
@@ -153,8 +216,6 @@ Returns the value
dec $I1
$P0 = var[$I0;$I1]
.return($P0)
- negative_index_attempt:
- _error_all("invalid index")
.end
=item !is_scalar
@@ -186,12 +247,42 @@ Returns the modified variable.
=cut
+# TODO: What is the difference between foo() and foo{}, besides the later
+# not working for non-cells? At the moment we do basic type checking and
+# Then redirect to normal indexed assignment.
+# TODO: We can refactor these two assignment functions to both call a common
+# indexing kernel, I think
+.sub '!indexed_assign_cell'
+ .param pmc var
+ .param pmc value
+ .param pmc indices :slurpy
+
+ if null var goto autovivify_cell
+ $S0 = typeof var
+ if $S0 != "PMCMatrix2D" goto error_not_a_cell
+ .tailcall '!indexed_assign'(var, value, indices :flat)
+
+ autovivify_cell:
+ var = new ['PMCMatrix2D']
+ .tailcall '!indexed_assign'(var, value, indices :flat)
+
+ error_not_a_cell:
+ _error_all("Cannot use {} indexing on a ", $S0)
+.end
+
.sub '!indexed_assign'
.param pmc var
.param pmc value
+ .param int idx
+ .param int array_assign
.param pmc indices :slurpy
- # TODO: Handle block assignments for matrices.
+ # If array_assign == 1, value is a regular scalar value. Otherwise, it's an
+ # aggregate and idx is the index of the value
+ if array_assign == 0 goto have_final_value
+ if null value goto have_final_value
+ value = value[idx]
+ have_final_value:
$I0 = elements indices
if $I0 == 0 goto assign_scalar
@@ -357,6 +448,11 @@ file.
.return(sub_obj)
.end
+.sub '!unpack_return_array'
+ .param pmc args
+ .return(args :flat)
+.end
+
.namespace []
Oops, something went wrong.

0 comments on commit 8a7ba13

Please sign in to comment.