Пример #1
0
int luaC_array__newindex(lua_State *L)
{
  struct Array *A = lunum_checkarray1(L, 1);
  const int m = _get_index(L, A);

  const enum ArrayType T = A->dtype;

  void *val = lunum_tovalue(L, T);
  memcpy((char*)A->data + array_sizeof(T)*m, val, array_sizeof(T));
  free(val);

  return 0;
}
Пример #2
0
static int luaC_array__newindex(lua_State *L)
{
  Array *A = lunum_checkarray1(L, 1);

  int success;
  const size_t m = _get_index(L, A, &success);

  if (success) {
    const ArrayType T = A->dtype;
    ArrayAllNum val;

    lunum_tovalue(L, T, &val);
    memcpy((char*)A->data + array_sizeof(T)*m, &val, array_sizeof(T));
  }

  return 0;
}
Пример #3
0
int lunum_upcast(lua_State *L, int pos, enum ArrayType T, int N)
// -----------------------------------------------------------------------------
// If the object at position 'pos' is already an array of dtype 'T', then push
// nothing and return 0. If the dtype is not 'T', then return 1 and push a copy
// of that array with dtype 'T' onto the stack. If it is a table, then push an
// array of dtype 'T' having the length of the table. If it is a number or
// complex, then push an array of dtype float or complex respectively having
// length 'N'.
// -----------------------------------------------------------------------------
{
  if (array_typename(T) == NULL) {
    luaL_error(L, "invalid array type");
  }

  // Deal with lunum.array
  // ---------------------------------------------------------------------------
  if (lunum_hasmetatable(L, pos, "array")) {

    struct Array *A = lunum_checkarray1(L, pos);

    if (A->dtype == T) {
      return 0;
    }

    else {

      struct Array A_ = array_new_copy(A, T);
      lunum_pusharray1(L, &A_);
      return 1;
    }
  }

  // Deal with Lua table
  // ---------------------------------------------------------------------------
  else if (lua_istable(L, pos)) {

    struct Array A = array_new_zeros(lua_rawlen(L, pos), T);

    for (int i=0; i<A.size; ++i) {

      lua_pushnumber(L, i+1);
      lua_gettable(L, pos);

      void *val = lunum_tovalue(L, T);
      memcpy((char*)A.data + array_sizeof(T)*i, val, array_sizeof(T));
      free(val);

      lua_pop(L, 1);
    }
    lunum_pusharray1(L, &A);

    return 1;
  }

  // Deal with Lua bool
  // ---------------------------------------------------------------------------
  else if (lua_isboolean(L, pos)) {
    const Bool x = lua_toboolean(L, pos);
    struct Array A = array_new_zeros(N, ARRAY_TYPE_BOOL);
    array_assign_from_scalar(&A, &x);
    lunum_pusharray1(L, &A);
    return 1;
  }

  // Deal with Lua numbers
  // ---------------------------------------------------------------------------
  else if (lua_isnumber(L, pos)) {
    const double x = lua_tonumber(L, pos);
    struct Array A = array_new_zeros(N, ARRAY_TYPE_DOUBLE);
    array_assign_from_scalar(&A, &x);
    struct Array B = array_new_copy(&A, T);
    array_del(&A);
    lunum_pusharray1(L, &B);
    return 1;
  }

  // Deal with lunum.complex
  // ---------------------------------------------------------------------------
  else if (lunum_hasmetatable(L, pos, "complex")) {

    const Complex z = *((Complex*) lua_touserdata(L, pos));
    struct Array A = array_new_zeros(N, ARRAY_TYPE_COMPLEX);
    array_assign_from_scalar(&A, &z);
    lunum_pusharray1(L, &A);
    return 1;
  }

  // Throw an error
  // ---------------------------------------------------------------------------
  else {
    luaL_error(L, "cannot cast to array from object of dtype %s\n",
               lua_typename(L, lua_type(L, pos)));
    return 0;
  }
}