예제 #1
0
파일: stat.c 프로젝트: byelipk/streem
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;
}
예제 #2
0
파일: iter.c 프로젝트: matz/streem
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;
}
예제 #3
0
파일: iter.c 프로젝트: cbforks/streem
static int
exec_seq(strm_stream* strm, int argc, strm_value* args, strm_value* ret)
{
  strm_int start=1, end=-1, inc=1;
  struct seq_data* d;

  switch (argc) {
  case 0:
    break;
  case 1:
    end = strm_value_int(args[0]);
    break;
  case 2:
    start = strm_value_int(args[0]);
    end = strm_value_int(args[1]);
    break;
  case 3:
    start = strm_value_int(args[0]);
    inc = strm_value_int(args[1]);
    end = strm_value_int(args[2]);
    break;
  default:
    strm_raise(strm, "wrong number of arguments");
    return STRM_NG;
  }
  d = malloc(sizeof(struct seq_data));
  d->n = start;
  d->inc = inc;
  d->end = end;
  *ret = strm_stream_value(strm_stream_new(strm_producer, gen_seq, NULL, (void*)d));
  return STRM_OK;
}
예제 #4
0
파일: exec.c 프로젝트: cbforks/streem
static int
lambda_call(strm_stream* strm, strm_value func, int argc, strm_value* argv, strm_value* ret)
{
  strm_lambda lambda = strm_value_lambda(func);
  node_lambda* nlbd = lambda->body;
  node_args* args = (node_args*)nlbd->args;
  strm_state c = {0};
  int i, n;
  node_error* exc;

  c.prev = lambda->state;
  if ((args == NULL && argc != 0) || (args->len != argc)) {
    if (strm) {
      strm_raise(strm, "wrong number of arguments");
      strm->exc->fname = nlbd->fname;
      strm->exc->lineno = nlbd->lineno;
    }
    return STRM_NG;
  }
  for (i=0; i<argc; i++) {
    n = strm_var_set(&c, node_to_sym(args->data[i]), argv[i]);
    if (n) return n;
  }
  n = exec_expr(strm, &c, nlbd->compstmt, ret);
  if (n == STRM_NG && strm) {
    exc = strm->exc;
    if (exc && exc->type == NODE_ERROR_RETURN) {
      *ret = exc->arg;
    }
  }
  return n;
}
예제 #5
0
파일: exec.c 프로젝트: cbforks/streem
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;
}
예제 #6
0
파일: exec.c 프로젝트: cbforks/streem
int
strm_funcall(strm_stream* strm, strm_value func, int argc, strm_value* argv, strm_value* ret)
{
  switch (strm_value_tag(func)) {
  case STRM_TAG_CFUNC:
    return (strm_value_cfunc(func))(strm, argc, argv, ret);
  case STRM_TAG_ARRAY:
    return ary_get(strm, func, argc, argv, ret);
  case STRM_TAG_PTR:
    if (!strm_lambda_p(func)) {
      strm_raise(strm, "not a function");
      return STRM_NG;
    }
    else {
      return lambda_call(strm, func, argc, argv, ret);
    }
  default:
    strm_raise(strm, "not a function");
    break;
  }
  return STRM_NG;
}
예제 #7
0
파일: stat.c 프로젝트: byelipk/streem
static strm_value
convert_number(strm_stream* strm, strm_value data, strm_value func)
{
  strm_value val;

  if (strm_funcall(strm, func, 1, &data, &val) == STRM_NG) {
    return STRM_NG;
  }
  if (!strm_number_p(val)) {
    strm_raise(strm, "number required");
    return STRM_NG;
  }
  return val;
}
예제 #8
0
파일: iter.c 프로젝트: matz/streem
static int
exec_drop(strm_stream* strm, int argc, strm_value* args, strm_value* ret)
{
  struct take_data* d;
  strm_int n;

  strm_get_args(strm, argc, args, "i", &n);
  if (n < 0) {
    strm_raise(strm, "negative iteration");
    return STRM_NG;
  }
  d = malloc(sizeof(*d));
  if (!d) return STRM_NG;
  d->n = n;
  *ret = strm_stream_value(strm_stream_new(strm_filter, iter_drop, NULL, (void*)d));
  return STRM_OK;
}
예제 #9
0
파일: iter.c 프로젝트: matz/streem
static int
exec_cycle(strm_stream* strm, int argc, strm_value* args, strm_value* ret)
{
  strm_array a;
  strm_int n = -1;
  struct cycle_data *d;

  strm_get_args(strm, argc, args, "A|i", &a, &n);
  if (argc == 2 && n <= 0) {
    strm_raise(strm, "invalid count number");
    return STRM_NG;
  }
  d = malloc(sizeof(*d));
  d->ary = a;
  d->count = n;
  *ret = strm_stream_value(strm_stream_new(strm_producer, gen_cycle, fin_cycle, (void*)d));
  return STRM_OK;
}
예제 #10
0
파일: iter.c 프로젝트: matz/streem
static int
exec_repeat(strm_stream* strm, int argc, strm_value* args, strm_value* ret)
{
  strm_value v;
  strm_int n = -1;
  struct repeat_data *d;

  strm_get_args(strm, argc, args, "v|i", &v, &n);
  if (argc == 2 && n <= 0) {
    strm_raise(strm, "invalid count number");
    return STRM_NG;
  }
  d = malloc(sizeof(*d));
  d->v = v;
  d->count = n;
  *ret = strm_stream_value(strm_stream_new(strm_producer, gen_repeat, fin_repeat, (void*)d));
  return STRM_OK;
}
예제 #11
0
파일: graph.c 프로젝트: matz/streem
static int
iter_bar(strm_stream* strm, strm_value data)
{
  struct bar_data* d = strm->data;
  double f, max = 1.0;

  if (interrupt) {
    interrupt = FALSE;
    strm_unsignal(SIGINT, sigupdate);
    move_cursor(d->row-1, 1);
    show_cursor();
    exit(1);
  }
  if (!strm_number_p(data)) {
    strm_raise(strm, "invalid data");
    return STRM_NG;
  }

  if (winch) {
    winch = FALSE;
    free(d->data);
    if (init_bar(d) == STRM_NG) {
      strm_stream_close(strm);
      return STRM_NG;
    }
  }
  f = strm_value_float(data);
  if (f < 0) f = 0;
  d->data[d->offset++] = f;
  max = 1.0;
  for (int i=0; i<d->dlen; i++) {
    f = d->data[i];
    if (f > max) max = f;
  }
  d->max = max;
  if (d->offset == d->dlen) {
    d->offset = 0;
  }
  show_graph(d);
  return STRM_OK;
}
예제 #12
0
파일: iter.c 프로젝트: matz/streem
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;
}
예제 #13
0
파일: exec.c 프로젝트: likeog/streem
int
strm_funcall(strm_state* state, strm_value func, int argc, strm_value* argv, strm_value* ret)
{
  switch (strm_value_tag(func)) {
  case STRM_TAG_CFUNC:
    return (strm_value_cfunc(func))(state, argc, argv, ret);
  case STRM_TAG_ARRAY:
    return ary_get(state, func, argc, argv, ret);
  case STRM_TAG_PTR:
    if (!strm_lambda_p(func)) {
      strm_raise(state, "not a function");
      return STRM_NG;
    }
    else {
      strm_lambda lambda = strm_value_lambda(func);
      node_lambda* nlbd = lambda->body;
      node_args* args = (node_args*)nlbd->args;
      strm_state c = {0};
      int i, n;

      c.prev = lambda->state;
      if ((args == NULL && argc != 0) &&
          (args->len != argc)) return STRM_NG;
      for (i=0; i<argc; i++) {
        n = strm_var_set(&c, node_to_sym(args->data[i]), argv[i]);
        if (n) return n;
      }
      n = exec_expr(&c, nlbd->compstmt, ret);
      if (c.exc && c.exc->type == NODE_ERROR_RETURN) {
        *ret = c.exc->arg;
        return STRM_OK;
      }
      return n;
    }
  default:
    break;
  }
  return STRM_NG;
}
예제 #14
0
파일: exec.c 프로젝트: cbforks/streem
static int
ary_get(strm_stream* strm, strm_value ary, int argc, strm_value* argv, strm_value* ret)
{
  struct strm_array* a;
  strm_value idx;

  if (argc != 1) {
    strm_raise(strm, "wrong number of arguments");
    return STRM_NG;
  }

  a = strm_ary_struct(ary);
  idx = argv[0];
  if (strm_num_p(idx)) {
    strm_int i = strm_value_int(idx);

    if (i>=a->len)
      return STRM_NG;
    *ret = a->ptr[i];
    return STRM_OK;
  }
  if (strm_string_p(idx)) {
    if (a->headers) {
      strm_int i, len = a->len;

      for (i=0; i<len; i++) {
        if (strm_str_eq(strm_value_str(idx),
                        strm_value_str(strm_ary_ptr(a->headers)[i]))) {
          *ret = a->ptr[i];
          return STRM_OK;
        }
      }
    }
  }
  return STRM_NG;
}
예제 #15
0
파일: exec.c 프로젝트: cbforks/streem
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;
}
예제 #16
0
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;
}
예제 #17
0
파일: csv.c 프로젝트: applideveloper/streem
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;
}
예제 #18
0
파일: exec.c 프로젝트: cbforks/streem
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;
}
예제 #19
0
파일: exec.c 프로젝트: likeog/streem
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_ary(lhs);
    arrd->n = 0;
    lhs = strm_task_value(strm_task_new(strm_task_prod, arr_exec, NULL, (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)) {
    strm_cfunc func = strm_value_cfunc(rhs);
    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 (strm_value_task(lhs) == NULL || strm_value_task(rhs) == NULL) {
      strm_raise(state, "task error");
      return STRM_NG;
    }
    strm_task_connect(strm_value_task(lhs), strm_value_task(rhs));
    *ret = rhs;
    return STRM_OK;
  }

  strm_raise(state, "type error");
  return STRM_NG;
}