K gnk(I n, ...) { K z = gtn(0, n); va_list v; va_start(v, n); DO(n, z->k[i] = va_arg(v, K)); va_end(v); R z; }
static PyObject* _arraytok(PyObject* self, PyObject* a) { K kobj = 0; if (!PyArray_Check(a)) { return PyErr_Format(PyExc_TypeError, "argument is not a numeric array"); } PyArrayObject* arr = (PyArrayObject*)a; if (!PyArray_ISCONTIGUOUS(arr)) { return PyErr_Format(PyExc_TypeError, "cannot handle non-contiguous arrays"); } int n = PyArray_SIZE(arr); int t = ktype(arr->descr->type_num); if (t > 0) { kobj = gtn(-t,n); memcpy(kobj->k, arr->data, PyArray_NBYTES(arr)); } else if (arr->descr->type_num == PyArray_OBJECT) { /* special handling for arrays of strings */ char** strings = malloc(n*sizeof(char*)); PyObject** objects = (PyObject**)arr->data; int i; for (i = 0; i < n; ++i) { char* str = PyString_AsString(objects[i]); if (str) { strings[i] = str; } else { free(strings); /* XXX should we raise our own exception here * * XXX or keep the one which came from "AsString"? */ return NULL; } } kobj = gtn(-4, n); for (i = 0; i < n; ++i) { KS(kobj)[i] = sp(strings[i]); } } return PyK_mk_K(kobj); }
static PyObject* _gtn(PyObject* self, PyObject* args) { int type, count; if (PyArg_ParseTuple(args, "ii", &type, &count)) { _K* k; K kobj = gtn(type, count); if (!kobj) { PyErr_SetString(PyExc_RuntimeError, "gtn"); return NULL; } k = (_K*)_KType.tp_alloc(&_KType, 0); if (!k) { PyErr_SetString(PyExc_MemoryError, "_K"); return NULL; } k->kobj = kobj; return (PyObject*)k; } PyErr_BadArgument(); return NULL; }
/* XXX unfortunately API function gnk of which pyk.gk is based is a vararg function and therefore cannot be portably exported to Python. It would be better if libk20 supplied a function gnk_(I, K*) in addition to gnk(I,...) which would take an array of K objects as the second argument */ static PyObject* _gk(PyObject* self, PyObject* args) { int n = PyTuple_Size(args); if (!n) { return _mk_K(gtn(0,0)); } int i, type = INT_MAX; K* ks = (K*)malloc(n*sizeof(K)); K kobj; for(i = 0; i < n; i++) { K ki; int t; PyObject* argi = PyTuple_GET_ITEM(args, i); if (!IS_K(argi)) { goto fail; } ks[i] = ki = ((_K*)argi)->kobj; t = ki->t; if (INT_MAX == type) { type = t; } else if (t > 4 || t < 1 || t != type) { type = 0; } } kobj = gtn((type>0 && type<5)?-type:0, n); if (!kobj) { free(ks); return PyErr_Format(PyExc_TypeError, "gtn(%d,%d) returned null", -type, n); } switch (type) { case 1: for (i = 0; i < n; i++) { KI(kobj)[i] = Ki(ks[i]); } break; case 2: for (i = 0; i < n; i++) { KF(kobj)[i] = Kf(ks[i]); } break; case 3: for (i = 0; i < n; i++) { KC(kobj)[i] = Kc(ks[i]); } break; case 4: for (i = 0; i < n; i++) { KS(kobj)[i] = Ks(ks[i]); } break; default: memcpy(KK(kobj), ks, n*sizeof(K)); for (i = 0; i < n; i++) { ci(ks[i]); } break; } free(ks); return _mk_K(kobj); fail: free(ks); PyErr_BadArgument(); return NULL; }
Z K gpn_(S s, I i) {K z=gtn(-3,i); memcpy(KC(z),s,i); R z; }
int main(int argc, char** argv) { F pi = atan(1.0)*4; K a = gi(2); K b = gi(3); K c = gi(4); K* v; cd(ksk("",0)); tst(Ki(a)==2); tst(Ki(b) + 1 == Ki(c)); cd(a); cd(b); cd(c); b = gf(1.0); c = gf(2); tst(Kf(b) + 1 == Kf(c)); cd(b); cd(c); a = gs(sp("foo")); b = ksk("`foo", 0); tst(Ks(a) == Ks(b)); cd(a); cd(b); a = ksk("2 + 3", 0); tst(Ki(a) == 5); cd(a); a = ksk("_ci 65", 0); tst(Kc(a) == 'A'); // XXX this should return type 1 uniform vector a=gnk(3,gi(11),gi(22),gi(33)); tst(a->t == 0); v = (K*)a->k; tst(Ki(v[0])+Ki(v[1])==Ki(v[2])); cd(a); { b = gsk("pi",gf(pi)); kap(&KTREE, &b); a = X(".pi"); tst(Kf(a) == pi); cd(a); } { K dir = gtn(5,0); K t; t = gsk("x",gi(1)); kap(&dir, &t); t = gsk("y",gi(2)); kap(&dir, &t); t = gsk("z",dir); kap(&KTREE, &t); a = X(".z.x"); tst(Ki(a) == 1); cd(a); a = X(".z.y"); tst(Ki(a) == 2); cd(a); } { I i; K d = gtn(5,0); K c0 = gtn(0,0); K c1 = gtn(-1,0); K t0, t1, e; t0 = gsk("a", c0); kap(&d,&t0); t1 = gsk("b", c1); kap(&d,&t1); e = gp("hello1"); kap(&c0,&e); e = gp("hello2"); kap(&c0,&e); KK(KK(d)[0])[1] = c0; i = 1; kap(&KK(KK(d)[1])[1], &i); i = 2; kap(&KK(KK(d)[1])[1], &i); //i = 1; kap(&c1, &i); //i = 2; kap(&c1, &i); //KK(KK(d)[1])[1] = c1; show(d); } //b = ksk("+/", a); //tst(Ki(b) == 66); //argc--;argv++; //DO(i, argc, {a=ksk(argv[i], 0); //ksk("`0:,/$!10;`0:,\"\n\"", 0); fprintf(stderr, "Pass:%4d, fail:%4d\n", pass, fail); if (argc > 1 && strcmp(argv[1], "-i") == 0) { boilerplate(); attend(); } }