static int ary_correl(strm_stream* strm, int argc, strm_value* args, strm_value* ret) { strm_value* v; int i, len; double sx, sy, sxx, syy, sxy; strm_get_args(strm, argc, args, "a", &v, &len); sx = sy = sxx = syy = sxy = 0; for (i=0; i<len; i++) { strm_value data = v[i]; strm_value* dv; double dx, dy; if (!strm_array_p(data) || strm_ary_len(data) != 2) { /* skip invalid data */ continue; } dv = strm_ary_ptr(data); dx = strm_value_flt(dv[0]) - sx; sx += dx / (i+1); dy = strm_value_flt(dv[1]) - sy; sy += dy / (i+1); sxx += i * dx * dx / (i+1); syy += i * dy * dy / (i+1); sxy += i * dx * dy / (i+1); } sxx = sqrt(sxx / (len-1)); syy = sqrt(syy / (len-1)); sxy /= (len-1) * sxx * syy; *ret = strm_flt_value(sxy); return STRM_OK; }
static int exec_call(strm_stream* strm, strm_state* state, strm_string name, int argc, strm_value* argv, strm_value* ret) { int n = STRM_NG; strm_value m; if (argc > 0) { strm_state* ns = strm_value_ns(argv[0]); if (ns) { n = strm_var_get(ns, name, &m); } else if (argc == 1 && strm_array_p(argv[0])) { m = strm_str_value(name); n = ary_get(strm, argv[0], 1, &m, ret); if (n == STRM_OK) return STRM_OK; } } if (n == STRM_NG) { n = strm_var_get(state, name, &m); } if (n == STRM_OK) { return strm_funcall(strm, m, argc, argv, ret); } strm_raise(strm, "function not found"); return STRM_NG; }
static int iter_correl(strm_stream* strm, strm_value data) { struct correl_data* d = strm->data; strm_value *v; double dx, dy; if (!strm_array_p(data) || strm_ary_len(data) != 2) { strm_raise(strm, "invalid data"); return STRM_NG; } v = strm_ary_ptr(data); if (!strm_number_p(v[0]) || !strm_number_p(v[1])) { strm_raise(strm, "correl() requires [num, num]"); return STRM_NG; } d->n++; dx = strm_value_flt(v[0]) - d->sx; d->sx += dx / d->n; dy = strm_value_flt(v[1]) - d->sy; d->sy += dy / d->n; d->sxx += (d->n-1) * dx * dx / d->n; d->syy += (d->n-1) * dy * dy / d->n; d->sxy += (d->n-1) * dx * dy / d->n; return STRM_OK; }
static int iter_rbk(strm_stream* strm, strm_value data) { struct rbk_data *d = strm->data; strm_value k, v; khiter_t i; int r; if (!strm_array_p(data) || strm_ary_len(data) != 2) { strm_raise(strm, "reduce_by_key element must be a key-value pair"); return STRM_NG; } k = strm_ary_ptr(data)[0]; v = strm_ary_ptr(data)[1]; i = kh_put(rbk, d->tbl, k, &r); if (r < 0) { /* r<0 operation failed */ return STRM_NG; } if (r != 0) { /* key does not exist */ kh_value(d->tbl, i) = v; } else { strm_value args[3]; args[0] = k; args[1] = kh_value(d->tbl, i); args[2] = v; if (strm_funcall(strm, d->func, 3, args, &v) == STRM_NG) { return STRM_NG; } kh_value(d->tbl, i) = v; } return STRM_OK; }
strm_state* strm_value_ns(strm_value val) { if (strm_array_p(val)) return strm_ary_ns(val); if (strm_value_tag(val) == STRM_TAG_PTR) { struct strm_misc* p = strm_ptr(val); if (strm_ptr_type(p) == STRM_PTR_MISC) { return p->ns; } } return NULL; }
strm_string strm_inspect(strm_value v) { if (strm_string_p(v)) { strm_string str = strm_value_str(v); return str_dump(str, str_dump_len(str)); } else if (strm_array_p(v)) { char *buf = malloc(32); strm_int i, bi = 0, capa = 32; strm_array a = strm_value_ary(v); for (i=0; i<strm_ary_len(a); i++) { strm_string str = strm_inspect(strm_ary_ptr(a)[i]); strm_string key = (strm_ary_headers(a) && strm_string_p(strm_ary_ptr(strm_ary_headers(a))[i])) ? strm_value_str(strm_ary_ptr(strm_ary_headers(a))[i]) : strm_str_null; strm_int slen = (key ? (strm_str_len(key)+1) : 0) + strm_str_len(str) + 3; if (bi+slen > capa) { capa *= 2; buf = realloc(buf, capa); } if (bi == 0) { buf[bi++] = '['; } else { buf[bi++] = ','; buf[bi++] = ' '; } if (key) { if (!str_symbol_p(key)) { key = str_dump(key, str_dump_len(key)); } memcpy(buf+bi, strm_str_ptr(key), strm_str_len(key)); bi += strm_str_len(key); buf[bi++] = ':'; } memcpy(buf+bi, strm_str_ptr(str), strm_str_len(str)); bi += strm_str_len(str); } buf[bi++] = ']'; return strm_str_new(buf, bi); } else { return strm_to_str(v); } }
static int flatmap_len(strm_array ary) { strm_value* v = strm_ary_ptr(ary); strm_int i, len, n = 0; len = strm_ary_len(ary); for (i=0; i<len; i++) { if (strm_array_p(v[i])) { n += flatmap_len(v[i]); } else { n++; } } return n; }
static int flatmap_push(strm_stream* strm, strm_array ary, strm_value func, strm_value** p) { strm_value* v = strm_ary_ptr(ary); strm_int i, len; len = strm_ary_len(ary); for (i=0; i<len; i++) { if (strm_array_p(v[i])) { if (flatmap_push(strm, v[i], func, p) == STRM_NG) { return STRM_NG; } } else { if (strm_funcall(strm, func, 1, &v[i], *p) == STRM_NG) { return STRM_NG; } *p += 1; } } return STRM_OK; }
static int iter_flatmap(strm_stream* strm, strm_value data) { struct map_data* d = strm->data; strm_value val; strm_int i, len; strm_value* e; if (strm_funcall(strm, d->func, 1, &data, &val) == STRM_NG) { return STRM_NG; } if (!strm_array_p(val)) { strm_raise(strm, "no array given for flatmap"); return STRM_NG; } len = strm_ary_len(val); e = strm_ary_ptr(val); for (i=0; i<len; i++){ strm_emit(strm, e[i], NULL); } return STRM_OK; }
strm_state* strm_value_ns(strm_value val) { if (strm_array_p(val)) { strm_state* ns = strm_ary_ns(val); if (ns) return ns; return strm_ns_array; } if (strm_string_p(val)) { return strm_ns_string; } if (strm_number_p(val)) { return strm_ns_number; } if (strm_value_tag(val) == STRM_TAG_PTR) { struct strm_misc* p = strm_ptr(val); if (!p) return NULL; if (strm_ptr_type(p) == STRM_PTR_AUX) { return p->ns; } } return NULL; }
static int exec_bar(strm_stream* strm, int argc, strm_value* args, strm_value* ret) { strm_value lhs, rhs; assert(argc == 2); /* int x int */ if (strm_int_p(args[0]) && strm_int_p(args[1])) { *ret = strm_int_value(strm_value_int(args[0])|strm_value_int(args[1])); return STRM_OK; } lhs = args[0]; /* lhs: io */ if (strm_io_p(lhs)) { lhs = strm_stream_value(strm_io_stream(lhs, STRM_IO_READ)); } /* lhs: lambda */ else if (strm_lambda_p(lhs)) { strm_lambda lmbd = strm_value_lambda(lhs); lhs = strm_stream_value(strm_stream_new(strm_filter, blk_exec, NULL, (void*)lmbd)); } /* lhs: array */ else if (strm_array_p(lhs)) { struct array_data *arrd = malloc(sizeof(struct array_data)); arrd->arr = strm_value_ary(lhs); arrd->n = 0; lhs = strm_stream_value(strm_stream_new(strm_producer, arr_exec, NULL, (void*)arrd)); } /* lhs: should be stream */ rhs = args[1]; /* rhs: io */ if (strm_io_p(rhs)) { rhs = strm_stream_value(strm_io_stream(rhs, STRM_IO_WRITE)); } /* rhs: lambda */ else if (strm_lambda_p(rhs)) { strm_lambda lmbd = strm_value_lambda(rhs); rhs = strm_stream_value(strm_stream_new(strm_filter, blk_exec, NULL, (void*)lmbd)); } /* rhs: cfunc */ else if (strm_cfunc_p(rhs)) { strm_cfunc func = strm_value_cfunc(rhs); rhs = strm_stream_value(strm_stream_new(strm_filter, cfunc_exec, NULL, func)); } /* stream x stream */ if (strm_stream_p(lhs) && strm_stream_p(rhs)) { strm_stream* lstrm = strm_value_stream(lhs); strm_stream* rstrm = strm_value_stream(rhs); if (lstrm == NULL || rstrm == NULL || lstrm->mode == strm_consumer || rstrm->mode == strm_producer) { strm_raise(strm, "stream error"); return STRM_NG; } strm_stream_connect(strm_value_stream(lhs), strm_value_stream(rhs)); *ret = rhs; return STRM_OK; } strm_raise(strm, "type error"); return STRM_NG; }
static int exec_bar(strm_state* state, int argc, strm_value* args, strm_value* ret) { strm_value lhs, rhs; assert(argc == 2); /* int x int */ if (strm_int_p(args[0]) && strm_int_p(args[1])) { *ret = strm_int_value(strm_value_int(args[0])|strm_value_int(args[1])); return STRM_OK; } lhs = args[0]; /* lhs: io */ if (strm_io_p(lhs)) { strm_io *io = strm_value_io(lhs); lhs = strm_task_value(strm_io_open(io, STRM_IO_READ)); } /* lhs: lambda */ else if (strm_lambda_p(lhs)) { strm_lambda *lmbd = strm_value_lambda(lhs) lhs = strm_task_value(strm_task_new(strm_task_filt, blk_exec, NULL, (void*)lmbd)); } /* lhs: array */ else if (strm_array_p(lhs)) { struct array_data *arrd = malloc(sizeof(struct array_data)); arrd->arr = strm_value_array(lhs); arrd->n = 0; lhs = strm_task_value(strm_task_new(strm_task_prod, arr_exec, arr_finish, (void*)arrd)); } /* lhs: should be task */ rhs = args[1]; /* rhs: io */ if (strm_io_p(rhs)) { strm_io *io = strm_value_io(rhs); rhs = strm_task_value(strm_io_open(io, STRM_IO_WRITE)); } /* rhs: lambda */ else if (strm_lambda_p(rhs)) { strm_lambda *lmbd = strm_value_lambda(rhs); rhs = strm_task_value(strm_task_new(strm_task_filt, blk_exec, NULL, (void*)lmbd)); } /* rhs: cfunc */ else if (strm_cfunc_p(rhs)) { void *func = rhs.val.p; rhs = strm_task_value(strm_task_new(strm_task_filt, cfunc_exec, NULL, func)); } /* task x task */ if (strm_task_p(lhs) && strm_task_p(rhs)) { if (lhs.val.p == NULL || rhs.val.p == NULL) { node_raise(state, "task error"); return STRM_NG; } strm_task_connect(strm_value_task(lhs), strm_value_task(rhs)); *ret = rhs; return STRM_OK; } node_raise(state, "type error"); return STRM_NG; }