static int iter_consec(strm_stream* strm, strm_value data) { struct slice_data* d = strm->data; strm_int n = d->n; if (d->i < n) { d->buf[d->i++] = data; if (d->i == n) { strm_array ary = strm_ary_new(d->buf, n); strm_emit(strm, strm_ary_value(ary), NULL); } return STRM_OK; } else { strm_array ary; strm_int i; strm_int len = n-1; for (i=0; i<len; i++) { d->buf[i] = d->buf[i+1]; } d->buf[len] = data; ary = strm_ary_new(d->buf, n); strm_emit(strm, strm_ary_value(ary), NULL); } return STRM_OK; }
static int str_chars(strm_stream* strm, int argc, strm_value* args, strm_value* ret) { const char* str; const char* s; const char* prev = NULL; strm_int slen; strm_array ary; strm_int n = 0; strm_value* sps; strm_int i = 0; strm_get_args(strm, argc, args, "s", &str, &slen); s = str; while (*s) { s += utf8len(s, s + slen); n++; } ary = strm_ary_new(NULL, n); sps = strm_ary_ptr(ary); s = str; while (*s) { prev = s; s += utf8len(s, s + slen); sps[i++] = strm_str_new(prev, s - prev); } *ret = strm_ary_value(ary); return STRM_OK; }
static strm_array ary_headers(node_string* headers, strm_int len) { strm_array ary = strm_ary_new(NULL, len); strm_value* p = strm_ary_ptr(ary); strm_int i; for (i=0; i<len; i++) { p[i] = node_to_sym(headers[i]); } return ary; }
static int finish_slice(strm_stream* strm, strm_value data) { struct slice_data* d = strm->data; if (d->i > 0) { strm_array ary = strm_ary_new(d->buf, d->i); strm_emit(strm, strm_ary_value(ary), NULL); } free(d->buf); free(d); return STRM_OK; }
static int iter_slice(strm_stream* strm, strm_value data) { struct slice_data* d = strm->data; strm_int n = d->n; d->buf[d->i++] = data; if (d->i == n) { strm_array ary = strm_ary_new(d->buf, n); d->i = 0; strm_emit(strm, strm_ary_value(ary), NULL); } return STRM_OK; }
static int rbk_finish(strm_stream* strm, strm_value data) { struct rbk_data *d = strm->data; khiter_t i; for (i=kh_begin(d->tbl); i!=kh_end(d->tbl); i++) { if (kh_exist(d->tbl, i)) { strm_value values[2]; values[0] = kh_key(d->tbl, i); values[1] = kh_value(d->tbl, i); strm_emit(strm, strm_ary_new(values, 2), NULL); } } return STRM_OK; }
static int ary_flatmap(strm_stream* strm, int argc, strm_value* args, strm_value* ret) { strm_array ary; strm_value func; strm_array a2; strm_value* v2; strm_get_args(strm, argc, args, "Av", &ary, &func); a2 = strm_ary_new(NULL, flatmap_len(ary)); v2 = strm_ary_ptr(a2); if (flatmap_push(strm, ary, func, &v2) == STRM_NG) { return STRM_NG; } *ret = strm_ary_value(a2); return STRM_OK; }
static int ary_map(strm_stream* strm, int argc, strm_value* args, strm_value* ret) { strm_value* v; strm_int len; strm_value func; strm_int i; strm_array a2; strm_value* v2; strm_get_args(strm, argc, args, "av", &v, &len, &func); a2 = strm_ary_new(NULL, len); v2 = strm_ary_ptr(a2); for (i=0; i<len; i++) { if (strm_funcall(strm, func, 1, &v[i], &v2[i]) == STRM_NG) { return STRM_NG; } } *ret = strm_ary_value(a2); return STRM_OK; }
strm_list* strm_list_cons(strm_value car, strm_value cdr) { if (cdr.type == STRM_VALUE_PTR) { if (!cdr.val.p) { return strm_list_new(car, NULL); } else { struct strm_object *obj = cdr.val.p; enum strm_obj_type type = obj->type; if (type == STRM_OBJ_LIST || type == STRM_OBJ_ARRAY) { return strm_list_new(car, strm_value_list(cdr)); } } } { strm_value buf[2]; buf[0] = car; buf[1] = cdr; return (strm_list*)strm_ary_new(buf, 2); } }
node* node_array_headers(node* np) { int i; node_values* v; strm_array *headers = NULL; strm_value *p = NULL; node_map* map = malloc(sizeof(node_map)); map->type = NODE_MAP; map->headers = NULL; if (np == NULL) np = node_array_new(); v = (node_values*)np; map->len = v->len; map->max = v->max; map->data = v->data; free(v); for (i = 0; i < map->len; i++) { node_pair* npair = (node_pair*)map->data[i]; if (npair->type == NODE_PAIR) { if (!headers) { headers = strm_ary_new(NULL, map->len); p = (strm_value*)headers->ptr; } p[i] = strm_ptr_value(npair->key); v->data[i] = npair->value; } } map->headers = headers; return (node*)map; }
static int exec_expr(strm_stream* strm, strm_state* state, node* np, strm_value* val) { int n; if (np == NULL) { return STRM_NG; } switch (np->type) { /* case NODE_ARGS: break; */ case NODE_NS: { node_ns* ns = (node_ns*)np; strm_state* s = strm_ns_find(state, node_to_sym(ns->name)); if (!s) { strm_raise(strm, "failed to create namespace"); return STRM_NG; } return exec_expr(strm, s, ns->body, val); } case NODE_IMPORT: { node_import *ns = (node_import*)np; strm_state* s = strm_ns_get(node_to_sym(ns->name)); if (!s) { strm_raise(strm, "no such namespace"); return STRM_NG; } n = strm_env_copy(state, s); if (n) { strm_raise(strm, "failed to import"); return n; } return STRM_OK; } break; case NODE_SKIP: strm_set_exc(strm, NODE_ERROR_SKIP, strm_nil_value()); return STRM_OK; case NODE_EMIT: { int i, n; node_array* v0; v0 = (node_array*)((node_emit*)np)->emit; if (!v0) { strm_emit(strm, strm_nil_value(), NULL); } else { for (i = 0; i < v0->len; i++) { n = exec_expr(strm, state, v0->data[i], val); if (n) return n; strm_emit(strm, *val, NULL); } } return STRM_OK; } break; case NODE_LET: { node_let *nlet = (node_let*)np; n = exec_expr(strm, state, nlet->rhs, val); if (n) { strm_raise(strm, "failed to assign"); return n; } return strm_var_set(state, node_to_sym(nlet->lhs), *val); } case NODE_ARRAY: { node_array* v0 = (node_array*)np; strm_array arr = strm_ary_new(NULL, v0->len); strm_value *ptr = (strm_value*)strm_ary_ptr(arr); int i=0; for (i = 0; i < v0->len; i++, ptr++) { n = exec_expr(strm, state, v0->data[i], ptr); if (n) return n; } if (v0->headers) { strm_ary_headers(arr) = ary_headers(v0->headers, v0->len); } if (v0->ns) { strm_ary_ns(arr) = strm_ns_get(node_to_sym(v0->ns)); } else { strm_ary_ns(arr) = strm_str_null; } *val = strm_ary_value(arr); return STRM_OK; } case NODE_IDENT: { node_ident* ni = (node_ident*)np; n = strm_var_get(state, node_to_sym(ni->name), val); if (n) { strm_raise(strm, "failed to reference variable"); } return n; } case NODE_IF: { strm_value v; node_if* nif = (node_if*)np; n = exec_expr(strm, state, nif->cond, &v); if (n) return n; if (strm_bool_p(v) && strm_value_bool(v)) { return exec_expr(strm, state, nif->then, val); } else if (nif->opt_else != NULL) { return exec_expr(strm, state, nif->opt_else, val); } else { *val = strm_nil_value(); return STRM_OK; } } break; case NODE_OP: { node_op* nop = (node_op*)np; strm_value args[2]; int i=0; if (nop->lhs) { n = exec_expr(strm, state, nop->lhs, &args[i++]); if (n) return n; } if (nop->rhs) { n = exec_expr(strm, state, nop->rhs, &args[i++]); if (n) return n; } return exec_call(strm, state, node_to_sym(nop->op), i, args, val); } break; case NODE_LAMBDA: { strm_lambda lambda = malloc(sizeof(struct strm_lambda)); if (!lambda) return STRM_NG; lambda->type = STRM_PTR_LAMBDA; lambda->body = (node_lambda*)np; lambda->state = state; *val = strm_ptr_value(lambda); return STRM_OK; } break; case NODE_CALL: { /* TODO: wip code of ident */ node_call* ncall = (node_call*)np; int i; node_nodes* v0 = (node_nodes*)ncall->args; strm_value *args = malloc(sizeof(strm_value)*v0->len); for (i = 0; i < v0->len; i++) { n = exec_expr(strm, state, v0->data[i], &args[i]); if (n) return n; } return exec_call(strm, state, node_to_sym(ncall->ident), i, args, val); } break; case NODE_RETURN: { node_return* nreturn = (node_return*)np; node_nodes* args = (node_nodes*)nreturn->rv; strm_value arg; if (!args) { arg = strm_nil_value(); } else { switch (args->len) { case 0: arg = strm_nil_value(); break; case 1: n = exec_expr(strm, state, args->data[0], &arg); if (n) return n; break; default: { strm_array ary = strm_ary_new(NULL, args->len); strm_int i; for (i=0; i<args->len; i++) { n = exec_expr(strm, state, args->data[i], (strm_value*)&strm_ary_ptr(ary)[i]); if (n) return n; } } break; } } strm_set_exc(strm, NODE_ERROR_RETURN, arg); return STRM_OK; } break; case NODE_NODES: { int i; node_nodes* v = (node_nodes*)np; for (i = 0; i < v->len; i++) { n = exec_expr(strm, state, v->data[i], val); if (n) { if (strm) { node_error* exc = strm->exc; if (exc != NULL) { node* n = v->data[i]; exc->fname = n->fname; exc->lineno = n->lineno; } } return n; } } } return STRM_OK; case NODE_INT: *val = strm_int_value(((node_int*)np)->value); return STRM_OK; case NODE_FLOAT: *val = strm_int_value(((node_float*)np)->value); return STRM_OK; case NODE_BOOL: *val = strm_bool_value(((node_bool*)np)->value); return STRM_OK; case NODE_NIL: *val = strm_nil_value(); return STRM_OK; case NODE_STR: *val = strm_str_value(node_to_str(((node_str*)np)->value)); return STRM_OK; default: break; } return STRM_NG; }
static int exec_expr(strm_state* state, node* np, strm_value* val) { int n; if (np == NULL) { return STRM_NG; } switch (np->type) { /* case NODE_ARGS: break; */ case NODE_SKIP: { state->exc = malloc(sizeof(node_error)); state->exc->type = NODE_ERROR_SKIP; state->exc->arg = strm_nil_value(); return STRM_OK; } case NODE_EMIT: { int i, n; node_values* v0; if (!state->task) { node_raise(state, "failed to emit"); } v0 = (node_values*)np->value.v.p; for (i = 0; i < v0->len; i++) { n = exec_expr(state, v0->data[i], val); if (n) return n; strm_emit(state->task, *val, NULL); } return STRM_OK; } break; case NODE_LET: { node_let *nlet = (node_let*)np; n = exec_expr(state, nlet->rhs, val); if (n) { node_raise(state, "failed to assign"); return n; } return strm_var_set(state, nlet->lhs, *val); } case NODE_ARRAY: { node_values* v0 = (node_values*)np; strm_array *arr = strm_ary_new(NULL, v0->len); strm_value *ptr = (strm_value*)arr->ptr; int i=0; for (i = 0; i < v0->len; i++, ptr++) { n = exec_expr(state, v0->data[i], ptr); if (n) return n; } *val = strm_ptr_value(arr); return STRM_OK; } case NODE_MAP: { node_map* v0 = (node_map*)np; strm_value nmap; strm_array* ary; n = exec_expr(state, v0->values, &nmap); if (n) return n; ary = strm_value_ary(nmap); ary->headers = v0->headers; *val = nmap; return STRM_OK; } case NODE_IDENT: n = strm_var_get(state, np->value.v.s, val); if (n) { node_raise(state, "failed to reference variable"); } return n; case NODE_IF: { strm_value v; node_if* nif = (node_if*)np; n = exec_expr(state, nif->cond, &v); if (n) return n; if (strm_value_bool(v) && v.val.i) { return exec_expr(state, nif->then, val); } else if (nif->opt_else != NULL) { return exec_expr(state, nif->opt_else, val); } else { *val = strm_nil_value(); return STRM_OK; } } break; case NODE_OP: { node_op* nop = (node_op*)np; strm_value args[2]; int i=0; if (nop->lhs) { n = exec_expr(state, nop->lhs, &args[i++]); if (n) return n; } if (nop->rhs) { n = exec_expr(state, nop->rhs, &args[i++]); if (n) return n; } return exec_call(state, nop->op, i, args, val); } break; case NODE_LAMBDA: { struct strm_lambda* lambda = malloc(sizeof(strm_lambda)); if (!lambda) return STRM_NG; lambda->type = STRM_OBJ_LAMBDA; lambda->body = (node_lambda*)np; lambda->state = state; *val = strm_ptr_value(lambda); return STRM_OK; } break; case NODE_CALL: { /* TODO: wip code of ident */ node_call* ncall = (node_call*)np; int i; node_values* v0 = (node_values*)ncall->args; strm_value *args = malloc(sizeof(strm_value)*v0->len); for (i = 0; i < v0->len; i++) { n = exec_expr(state, v0->data[i], &args[i]); if (n) return n; } return exec_call(state, ncall->ident, i, args, val); } break; case NODE_RETURN: { node_return* nreturn = (node_return*)np; node_values* args = (node_values*)nreturn->rv; state->exc = malloc(sizeof(node_error)); state->exc->type = NODE_ERROR_RETURN; switch (args->len) { case 0: state->exc->arg = strm_nil_value(); break; case 1: n = exec_expr(state, args->data[0], &state->exc->arg); if (n) return n; break; default: { strm_array* ary = strm_ary_new(NULL, args->len); size_t i; for (i=0; i<args->len; i++) { n = exec_expr(state, args->data[i], (strm_value*)&ary->ptr[i]); if (n) return n; } } break; } return STRM_NG; } break; case NODE_STMTS: { int i; node_values* v = (node_values*)np; for (i = 0; i < v->len; i++) { n = exec_expr(state, v->data[i], val); if (state->exc != NULL) return STRM_NG; if (n) return n; } } return STRM_OK; case NODE_VALUE: switch (np->value.t) { case NODE_VALUE_BOOL: *val = strm_bool_value(np->value.v.b); return STRM_OK; case NODE_VALUE_NIL: *val = strm_nil_value(); return STRM_OK; case NODE_VALUE_STRING: case NODE_VALUE_IDENT: *val = strm_ptr_value(np->value.v.s); return STRM_OK; case NODE_VALUE_DOUBLE: *val = strm_flt_value(np->value.v.d); return STRM_OK; case NODE_VALUE_INT: *val = strm_int_value(np->value.v.i); return STRM_OK; /* following type should not be evaluated */ case NODE_VALUE_ERROR: case NODE_VALUE_USER: default: return STRM_NG; } default: break; } return STRM_NG; }
static int str_split(strm_stream* strm, int argc, strm_value* args, strm_value* ret) { const char* s; strm_int slen; const char* b; const char* t; const char* p; strm_int plen; const char* pend; char c; strm_int n = 0; strm_array ary; strm_value* sps; strm_int i; strm_get_args(strm, argc, args, "s|s", &p, &plen, &s, &slen); if (argc == 1) { s = " "; slen = 1; } /* count number of split strings */ c = s[0]; b = t = p; pend = p + plen - slen; n = 0; while (p<pend) { if (*p == c) { if (memcmp(p, s, slen) == 0) { if (!(slen == 1 && c == ' ' && (p-t) == 0)) { n++; } t = p + slen; } } p++; } n++; /* actual split */ ary = strm_ary_new(NULL, n); sps = strm_ary_ptr(ary); c = s[0]; p = t = b; i = 0; while (p<pend) { if (*p == c) { if (memcmp(p, s, slen) == 0) { if (!(slen == 1 && c == ' ' && (p-t) == 0)) { sps[i++] = strm_str_new(t, p-t); } t = p + slen; } } p++; } pend = b + plen; sps[i++] = strm_str_new(t, pend-t); *ret = strm_ary_value(ary); return STRM_OK; }
static int str_split(strm_stream* strm, int argc, strm_value* args, strm_value* ret) { strm_string str; strm_string sep; const char* s; strm_int slen; const char* t; const char* p; const char* pend; char c; strm_int n = 0; strm_array ary; strm_value* sps; strm_int i; switch (argc) { case 1: str = args[0]; sep = strm_str_lit(" "); break; case 2: str = args[0]; if (!strm_string_p(args[1])) { strm_raise(strm, "need string separator"); return STRM_NG; } sep = strm_value_str(args[1]); break; default: strm_raise(strm, "wrong number of arguments"); return STRM_NG; } /* count number of split strings */ s = strm_str_ptr(sep); slen = strm_str_len(sep); c = s[0]; t = p = strm_str_ptr(str); pend = p + strm_str_len(str) - slen; n = 0; while (p<pend) { if (*p == c) { if (memcmp(p, s, slen) == 0) { if (!(slen == 1 && c == ' ' && (p-t) == 0)) { n++; } t = p + slen; } } p++; } n++; /* actual split */ ary = strm_ary_new(NULL, n); sps = strm_ary_ptr(ary); s = strm_str_ptr(sep); slen = strm_str_len(sep); c = s[0]; t = p = strm_str_ptr(str); pend = p + strm_str_len(str) - slen; i = 0; while (p<pend) { if (*p == c) { if (memcmp(p, s, slen) == 0) { if (!(slen == 1 && c == ' ' && (p-t) == 0)) { sps[i++] = strm_str_new(t, p-t); } t = p + slen; } } p++; } pend = strm_str_ptr(str) + strm_str_len(str); sps[i++] = strm_str_new(t, pend-t); *ret = strm_ary_value(ary); return STRM_OK; }
static int csv_accept(strm_stream* strm, strm_value data) { strm_array ary; strm_string line = strm_value_str(data); strm_value *bp; const char *fbeg; const char *ptr; const char *pend; int fieldcnt; int in_quote = 0, all_str = 1; int i = 0; enum csv_type ftype; enum csv_type* types; struct csv_data *cd = strm->data; if (cd->prev) { strm_int len = strm_str_len(cd->prev)+strm_str_len(line)+1; char* tmp = malloc(len); memcpy(tmp, strm_str_ptr(cd->prev), strm_str_len(cd->prev)); *(tmp+strm_str_len(cd->prev)) = '\n'; memcpy(tmp+strm_str_len(cd->prev)+1, strm_str_ptr(line), strm_str_len(line)); line = strm_str_new(tmp, len); free(tmp); cd->prev = strm_str_null; } fieldcnt = count_fields(line); if (fieldcnt == -1) { cd->prev = line; return STRM_NG; } if (cd->n > 0 && fieldcnt != cd->n) return STRM_NG; ptr = strm_str_ptr(line); pend = ptr + strm_str_len(line); ary = strm_ary_new(NULL, fieldcnt); if (!ary) return STRM_NG; bp = (strm_value*)strm_ary_ptr(ary); types = cd->types; ftype = types ? types[0] : TYPE_UNSPC; for (fbeg=ptr; ptr<pend; ptr++) { if (in_quote) { if (*ptr == '\"') { if (ptr[1] == '\"') { ptr++; ftype = TYPE_ESC; continue; } in_quote = 0; } continue; } switch(*ptr) { case '\"': in_quote = 1; if (ptr == fbeg) { ftype = TYPE_STR; fbeg = ptr+1; } else { ftype = TYPE_ESC; } continue; case ',': *bp = csv_value(fbeg, ptr-fbeg, ftype); if (!strm_string_p(*bp)) all_str = 0; bp++; fbeg = ptr+1; i++; ftype = types ? types[i] : TYPE_UNSPC; break; default: continue; } } /* trim newline at the end */ if (ptr[-1] == '\n') { ptr--; } /* trim carriage return at the end */ if (ptr[-1] == '\r') { ptr--; } *bp = csv_value(fbeg, ptr-fbeg, ftype); if (!strm_string_p(*bp)) all_str = 0; /* check headers */ if (!cd->headers && !cd->types) { if (all_str) { cd->headers = ary; ary = strm_ary_null; } cd->n = fieldcnt; } if (ary) { /* set headers if any */ if (cd->headers) strm_ary_headers(ary) = cd->headers; if (!cd->types) { /* first data line (after optinal header line) */ if (cd->headers) { if (all_str) { /* data line is all string; emit header line */ strm_emit(strm, strm_ary_value(cd->headers), NULL); cd->headers = strm_ary_null; } else { /* intern header strings */ strm_array h = cd->headers; strm_value *p = strm_ary_ptr(h); int i; for (i=0; i<strm_ary_len(h); i++) { strm_string str = strm_value_str(p[i]); p[i] = strm_str_value(strm_str_intern_str(str)); } } } /* initialize types (determined by first data line) */ cd->types = malloc(sizeof(enum csv_type)*fieldcnt); if (!cd->types) return STRM_NG; for (i=0; i<fieldcnt; i++) { cd->types[i] = csv_type(strm_ary_ptr(ary)[i]); } } else { /* type check */ for (i=0; i<fieldcnt; i++) { if (cd->types[i] != csv_type(strm_ary_ptr(ary)[i])) { /* type mismatch (error); skip this line */ strm_raise(strm, "csv type mismatch"); return STRM_NG; } } } strm_emit(strm, strm_str_value(ary), NULL); } return STRM_OK; }
static void csv_accept(strm_task* task, strm_value data) { strm_array *ary; strm_string *line = strm_value_str(data); strm_value *bp; char *tmp, *tptr; const char *ptr; const char *pend; int fieldcnt, len; int in_quote = 0, quoted = 0, all_str = 1;; struct csv_data *cd = task->data; if (cd->prev) { strm_string *str = strm_str_new(NULL, cd->prev->len+line->len+1); tmp = (char*)str->ptr; memcpy(tmp, cd->prev->ptr, cd->prev->len); *(tmp+cd->prev->len) = '\n'; memcpy(tmp+cd->prev->len+1, line->ptr, line->len); line = str; cd->prev = NULL; } fieldcnt = count_fields(line); if (fieldcnt == -1) { cd->prev = line; return; } if (cd->n > 0 && fieldcnt != cd->n) return; ptr = line->ptr; pend = ptr + line->len; ary = strm_ary_new(NULL, fieldcnt); if (!ary) return; bp = (strm_value*)ary->ptr; len = line->len; tmp = malloc(len+1); if (!tmp) return; *tmp='\0'; ptr=line->ptr; tptr=tmp; for (;ptr<pend; ptr++) { if (in_quote) { if (*ptr == '\"') { if (ptr[1] == '\"') { *tptr++ = '\"'; ptr++; continue; } in_quote = 0; } else *tptr++ = *ptr; continue; } switch(*ptr) { case '\"': in_quote = 1; quoted = 1; continue; case ',': if (quoted) { *bp = strm_str_value(tmp, tptr-tmp); } else { *bp = csv_value(tmp, tptr-tmp); } if (!strm_str_p(*bp)) all_str = 0; bp++; tptr = tmp; quoted = 0; break; default: *tptr++ = *ptr; continue; } } /* trim newline at the end */ if (tptr > tmp && tptr[-1] == '\n') { tptr--; } /* trim carriage return at the end */ if (tptr > tmp && tptr[-1] == '\r') { tptr--; } *bp = csv_value(tmp, tptr-tmp); if (!strm_str_p(*bp)) all_str = 0; free(tmp); /* check headers */ if (!cd->headers && !cd->types) { if (all_str) { cd->headers = ary; ary = NULL; } cd->n = fieldcnt; } if (ary) { int i; /* set headers if any */ if (cd->headers) ary->headers = cd->headers; if (!cd->types) { /* first data line (after optinal header line) */ if (cd->headers) { if (all_str) { /* data line is all string; emit header line */ strm_emit(task, strm_ptr_value(cd->headers), NULL); cd->headers = NULL; } else { /* intern header strings */ strm_array *h = cd->headers; strm_value *p = (strm_value*)h->ptr; int i; for (i=0; i<h->len; i++) { strm_string *str = strm_value_str(p[i]); p[i] = strm_ptr_value(strm_str_intern_str(str)); } } } /* initialize types (determined by first data line) */ cd->types = malloc(sizeof(enum csv_type)*fieldcnt); if (!cd->types) return; for (i=0; i<fieldcnt; i++) { cd->types[i] = csv_type(ary->ptr[i]); } } else { /* type check */ for (i=0; i<fieldcnt; i++) { if (cd->types[i] != csv_type(ary->ptr[i])) { if (cd->types[i] == STRING_TYPE) { /* convert value to string */ ((strm_value*)ary->ptr)[i] = strm_ptr_value(strm_to_str(ary->ptr[i])); } else { /* type mismatch (error); skip this line */ return; } } } } strm_emit(task, strm_ptr_value(ary), NULL); } }