Skip to content

Commit

Permalink
ivy: make Vector an opaque type instead of a slice (#171)
Browse files Browse the repository at this point in the history
This requires a very large number of mostly mechanical changes,
but now the code does not know that Vector is a slice, which
will allow optimizations like a copy-on-write implementation.

There is more work to do, but this is a large enough change
to be a reasonable checkpoint.
  • Loading branch information
rsc authored Dec 17, 2024
1 parent 9cb9db1 commit bb6d32a
Show file tree
Hide file tree
Showing 23 changed files with 619 additions and 591 deletions.
4 changes: 2 additions & 2 deletions exec/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func (c *Context) Local(i int) value.Value {
// AssignLocal assigns the local variable with the given index the value.
func (c *Context) AssignLocal(i int, val value.Value) {
switch v := val.(type) {
case value.Vector:
case *value.Vector:
val = v.Copy()
case *value.Matrix:
val = v.Copy()
Expand All @@ -89,7 +89,7 @@ func (c *Context) AssignLocal(i int, val value.Value) {
// Inside a function, new variables become locals.
func (c *Context) AssignGlobal(name string, val value.Value) {
switch v := val.(type) {
case value.Vector:
case *value.Vector:
val = v.Copy()
case *value.Matrix:
val = v.Copy()
Expand Down
4 changes: 2 additions & 2 deletions order_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,12 @@ var (
matrix12_44 = value.NewMatrix([]int{2, 2}, newMatrixData(1, 2, 4, 4))
)

func newMatrixData(data ...int) []value.Value {
func newMatrixData(data ...int) *value.Vector {
v := make([]value.Value, len(data))
for i := range data {
v[i] = value.Int(data[i])
}
return v
return value.NewVector(v)
}

func TestOrderedCompare(t *testing.T) {
Expand Down
10 changes: 5 additions & 5 deletions parse/assign.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,16 @@ func assignment(context value.Context, b *binary) value.Value {
}
case sliceExpr:
// Simultaneous assignment requires evaluation of RHS before assignment.
rhs, ok := b.right.Eval(context).Inner().(value.Vector)
rhs, ok := b.right.Eval(context).Inner().(*value.Vector)
if !ok {
value.Errorf("rhs of assignment to (%s) not a vector", lhs.ProgString())
}
if len(lhs) != len(rhs) {
if len(lhs) != rhs.Len() {
value.Errorf("length mismatch in assignment to (%s)", lhs.ProgString())
}
values := make([]value.Value, len(rhs))
for i := len(rhs) - 1; i >= 0; i-- {
values[i] = rhs[i].Eval(context).Inner()
values := make([]value.Value, rhs.Len())
for i := rhs.Len() - 1; i >= 0; i-- {
values[i] = rhs.At(i).Eval(context).Inner()
}
for i, v := range lhs {
vbl := v.(*variableExpr) // Guaranteed to be only a variable on LHS.
Expand Down
2 changes: 1 addition & 1 deletion parse/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ func walk(expr value.Expr, assign bool, f func(value.Expr, bool)) {
case value.BigRat:
case value.BigFloat:
case value.Complex:
case value.Vector:
case *value.Vector:
case *value.Matrix:
default:
fmt.Printf("unknown %T in references\n", e)
Expand Down
2 changes: 1 addition & 1 deletion parse/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ func (e *variableExpr) ProgString() string {
// may require parentheses around it when printed to maintain correct evaluation order.
func isCompound(x interface{}) bool {
switch x := x.(type) {
case value.Char, value.Int, value.BigInt, value.BigRat, value.BigFloat, value.Complex, value.Vector, value.Matrix:
case value.Char, value.Int, value.BigInt, value.BigRat, value.BigFloat, value.Complex, *value.Vector, *value.Matrix:
return false
case sliceExpr, *variableExpr:
return false
Expand Down
4 changes: 2 additions & 2 deletions parse/save.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,12 +185,12 @@ func put(conf *config.Config, out io.Writer, val value.Value, withParens bool) {
put(conf, out, real, false)
fmt.Fprintf(out, "j")
put(conf, out, imag, false)
case value.Vector:
case *value.Vector:
if val.AllChars() {
fmt.Fprintf(out, "%q", val.Sprint(conf))
return
}
for i, v := range val {
for i, v := range val.All() {
if i > 0 {
fmt.Fprint(out, " ")
}
Expand Down
2 changes: 1 addition & 1 deletion testdata/debug.ivy
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ op a base b = ((ceil b log a) rho b) encode a
c

1 2 3
value.Vector
*value.Vector
1 2 3

sqrt 2
Expand Down
2 changes: 1 addition & 1 deletion value/bigfloat.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ func (f BigFloat) toType(op string, conf *config.Config, which valueType) Value
case vectorType:
return oneElemVector(f)
case matrixType:
return NewMatrix([]int{1}, []Value{f})
return NewMatrix([]int{1}, NewVector([]Value{f}))
}
Errorf("%s: cannot convert float to %s", op, which)
return nil
Expand Down
2 changes: 1 addition & 1 deletion value/bigint.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ func (i BigInt) toType(op string, conf *config.Config, which valueType) Value {
case vectorType:
return oneElemVector(i)
case matrixType:
return NewMatrix([]int{1}, []Value{i})
return NewMatrix([]int{1}, NewVector([]Value{i}))
}
Errorf("%s: cannot convert big int to %s", op, which)
return nil
Expand Down
2 changes: 1 addition & 1 deletion value/bigrat.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ func (r BigRat) toType(op string, conf *config.Config, which valueType) Value {
case vectorType:
return oneElemVector(r)
case matrixType:
return NewMatrix([]int{1, 1}, []Value{r})
return NewMatrix([]int{1, 1}, NewVector([]Value{r}))
}
Errorf("%s: cannot convert rational to %s", op, which)
return nil
Expand Down
Loading

0 comments on commit bb6d32a

Please sign in to comment.