123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- #include "stdafx.h"
- #include "defs.h"
- // n is the total number of things on the stack. The first thing on the stack
- // is the object to be indexed, followed by the indices themselves.
- void
- index_function(int n)
- {
- int i, k, m, ndim, nelem, t;
- U **s;
- save();
- s = stack + tos - n;
- p1 = s[0];
- // index of scalar ok
- if (!istensor(p1)) {
- tos -= n;
- push(p1);
- restore();
- return;
- }
- ndim = p1->u.tensor->ndim;
- m = n - 1;
- if (m > ndim)
- stop("too many indices for tensor");
- k = 0;
- for (i = 0; i < m; i++) {
- push(s[i + 1]);
- t = pop_integer();
- if (t < 1 || t > p1->u.tensor->dim[i])
- stop("index out of range");
- k = k * p1->u.tensor->dim[i] + t - 1;
- }
- if (ndim == m) {
- tos -= n;
- push(p1->u.tensor->elem[k]);
- restore();
- return;
- }
- for (i = m; i < ndim; i++)
- k = k * p1->u.tensor->dim[i] + 0;
- nelem = 1;
- for (i = m; i < ndim; i++)
- nelem *= p1->u.tensor->dim[i];
- p2 = alloc_tensor(nelem);
- p2->u.tensor->ndim = ndim - m;
- for (i = m; i < ndim; i++)
- p2->u.tensor->dim[i - m] = p1->u.tensor->dim[i];
- for (i = 0; i < nelem; i++)
- p2->u.tensor->elem[i] = p1->u.tensor->elem[k + i];
- tos -= n;
- push(p2);
- restore();
- }
- //-----------------------------------------------------------------------------
- //
- // Input: n Number of args on stack
- //
- // tos-n Right-hand value
- //
- // tos-n+1 Left-hand value
- //
- // tos-n+2 First index
- //
- // .
- // .
- // .
- //
- // tos-1 Last index
- //
- // Output: Result on stack
- //
- //-----------------------------------------------------------------------------
- #define LVALUE p1
- #define RVALUE p2
- #define TMP p3
- void
- set_component(int n)
- {
- int i, k, m, ndim, t;
- U **s;
- save();
- if (n < 3)
- stop("error in indexed assign");
- s = stack + tos - n;
- RVALUE = s[0];
- LVALUE = s[1];
- if (!istensor(LVALUE))
- stop("error in indexed assign");
- ndim = LVALUE->u.tensor->ndim;
- m = n - 2;
- if (m > ndim)
- stop("error in indexed assign");
- k = 0;
- for (i = 0; i < m; i++) {
- push(s[i + 2]);
- t = pop_integer();
- if (t < 1 || t > LVALUE->u.tensor->dim[i])
- stop("error in indexed assign");
- k = k * p1->u.tensor->dim[i] + t - 1;
- }
- for (i = m; i < ndim; i++)
- k = k * p1->u.tensor->dim[i] + 0;
- // copy
- TMP = alloc_tensor(LVALUE->u.tensor->nelem);
- TMP->u.tensor->ndim = LVALUE->u.tensor->ndim;
- for (i = 0; i < p1->u.tensor->ndim; i++)
- TMP->u.tensor->dim[i] = LVALUE->u.tensor->dim[i];
- for (i = 0; i < p1->u.tensor->nelem; i++)
- TMP->u.tensor->elem[i] = LVALUE->u.tensor->elem[i];
- LVALUE = TMP;
- if (ndim == m) {
- if (istensor(RVALUE))
- stop("error in indexed assign");
- LVALUE->u.tensor->elem[k] = RVALUE;
- tos -= n;
- push(LVALUE);
- restore();
- return;
- }
- // see if the rvalue matches
- if (!istensor(RVALUE))
- stop("error in indexed assign");
- if (ndim - m != RVALUE->u.tensor->ndim)
- stop("error in indexed assign");
- for (i = 0; i < RVALUE->u.tensor->ndim; i++)
- if (LVALUE->u.tensor->dim[m + i] != RVALUE->u.tensor->dim[i])
- stop("error in indexed assign");
- // copy rvalue
- for (i = 0; i < RVALUE->u.tensor->nelem; i++)
- LVALUE->u.tensor->elem[k + i] = RVALUE->u.tensor->elem[i];
- tos -= n;
- push(LVALUE);
- restore();
- }
- #if SELFTEST
- static char *s[] = {
- "A=((A11,A12),(A21,A22))",
- "",
- "A[1,1]",
- "A11",
- "A[1,2]",
- "A12",
- "A[2,1]",
- "A21",
- "A[2,2]",
- "A22",
- "A[1]",
- "(A11,A12)",
- "A[2]",
- "(A21,A22)",
- "A[1]=(B11,B12)",
- "",
- "A",
- "((B11,B12),(A21,A22))",
- "A[2]=(B21,B22)",
- "",
- "A",
- "((B11,B12),(B21,B22))",
- "A=((0,0),(0,0))",
- "",
- "A[1,1]",
- "0",
- // index of scalar ok
- "1[2]",
- "1",
- };
- void
- test_index(void)
- {
- test(__FILE__, s, sizeof s / sizeof (char *));
- }
- #endif
|