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; }
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; }
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; } }