コード例 #1
0
ファイル: exec.c プロジェクト: fenglyu/streem
static void
blk_exec(strm_task* task, strm_value data)
{
  strm_lambda *lambda = task->data;
  strm_value ret = strm_nil_value();
  node_values* args = (node_values*)lambda->body->args;
  int n;
  strm_state c = {0};

  c.task = task;
  c.prev = lambda->state;
  assert(args->len == 1);
  strm_var_set(&c, (strm_string*)args->data[0], data);

  n = exec_expr(&c, lambda->body->compstmt, &ret);
  if (n) return;
  if (lambda->state->exc) {
    if (lambda->state->exc->type == NODE_ERROR_RETURN) {
      ret = lambda->state->exc->arg;
      free(lambda->state->exc);
      lambda->state->exc = NULL;
    } else {
      return;
    }
  }
  strm_emit(task, ret, NULL);
}
コード例 #2
0
ファイル: exec.c プロジェクト: likeog/streem
static int
blk_exec(strm_task* task, strm_value data)
{
  strm_lambda lambda = task->data;
  strm_value ret = strm_nil_value();
  node_args* args = (node_args*)lambda->body->args;
  int n;
  strm_state c = {0};

  c.task = task;
  c.prev = lambda->state;
  if (args) {
    assert(args->len == 1);
    strm_var_set(&c, node_to_sym(args->data[0]), data);
  }

  n = exec_expr(&c, lambda->body->compstmt, &ret);
  if (n) return STRM_NG;
  if (lambda->state->exc) {
    if (lambda->state->exc->type == NODE_ERROR_RETURN) {
      ret = lambda->state->exc->arg;
      free(lambda->state->exc);
      lambda->state->exc = NULL;
    } else {
      return STRM_NG;
    }
  }
  strm_emit(task, ret, NULL);
  return STRM_OK;
}
コード例 #3
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;
}
コード例 #4
0
ファイル: exec.c プロジェクト: cbforks/streem
static int
blk_exec(strm_stream* strm, strm_value data)
{
  strm_lambda lambda = strm->data;
  strm_value ret = strm_nil_value();
  node_args* args = (node_args*)lambda->body->args;
  node_error* exc;
  int n;
  strm_state c = {0};

  c.prev = lambda->state;
  if (args) {
    assert(args->len == 1);
    strm_var_set(&c, node_to_sym(args->data[0]), data);
  }

  n = exec_expr(strm, &c, lambda->body->compstmt, &ret);
  exc = strm->exc;
  if (exc) {
    if (exc->type == NODE_ERROR_RETURN) {
      ret = exc->arg;
      strm_clear_exc(strm);
    }
    else {
      if (strm_option_verbose) {
        strm_eprint(strm);
      }
      return STRM_NG;
    }
  }
  if (n) return STRM_NG;
  strm_emit(strm, ret, NULL);
  return STRM_OK;
}
コード例 #5
0
ファイル: tcli.c プロジェクト: UlricE/SiagOffice
static int texec_expr(ClientData clientData, Tcl_Interp *interp,
			int argc, char *argv[])
{
	if (argc < 3) return TCL_ERROR;
	exec_expr(name2interpreter(argv[1]), argv[2]);
	Tcl_SetResult(interp, NULL, TCL_STATIC);
	return TCL_OK;
}
コード例 #6
0
ファイル: xegon.c プロジェクト: UlricE/SiagOffice
static void execute_tcl_action(Widget w, XEvent *event,
			   String *params, Cardinal *num_params)
{
	char b[256];
	int i;

	strcpy(b, params[0]);
	for (i = 1; i < *num_params; i++) {
		strcat(b, " ");
		strcat(b, params[i]);
	}
	exec_expr(name2interpreter("Tcl"), b);
}
コード例 #7
0
ファイル: xegon.c プロジェクト: UlricE/SiagOffice
static void execute_siod_action(Widget w, XEvent *event,
			String *params, Cardinal *num_params)
{
	char b[256];
	int i;

	strcpy(b, "(");
	strcat(b, params[0]);
	for (i = 1; i < *num_params; i++) {
		strcat(b, " ");
		strcat(b, params[i]);
	}
	strcat(b, ")");
	exec_expr(siod_interpreter, b);
}
コード例 #8
0
ファイル: exec.c プロジェクト: faicm/streem
int
node_run(parser_state* p)
{
  strm_value v;

  node_init(&p->ctx);
  strm_seq_init(&p->ctx);
  exec_expr(&p->ctx, (node*)p->lval, &v);
  if (p->ctx.exc != NULL) {
    strm_value v;
    exec_cputs(&p->ctx, stderr, 1, &p->ctx.exc->arg, &v);
    /* TODO: garbage correct previous exception value */
    p->ctx.exc = NULL;
  }
  return 0;
}
コード例 #9
0
ファイル: xegon.c プロジェクト: UlricE/SiagOffice
static void execute_guile_action(Widget w, XEvent * event,
			   String * params, Cardinal * num_params)
{
	char b[256];
	int i;

	strcpy(b, "(");
	strcat(b, params[0]);
	for (i = 1; i < *num_params; i++) {
		strcat(b, " ");
		strcat(b, params[i]);
	}
	strcat(b, ")");
#ifdef DEBUG
	printf("guile(%s)\n", b);
#endif
	exec_expr(name2interpreter("Guile"), b);
}
コード例 #10
0
ファイル: exec.c プロジェクト: cbforks/streem
int
node_run(parser_state* p)
{
  strm_value v;
  strm_state c = {0};
  strm_stream t = {0};
  node_error* exc;

  node_init(&c);

  exec_expr(&t, &c, (node*)p->lval, &v);
  exc = t.exc;
  if (exc != NULL) {
    if (exc->type != NODE_ERROR_RETURN) {
      strm_eprint(&t);
    }
    strm_clear_exc(&t);
  }
  return STRM_OK;
}
コード例 #11
0
ファイル: exec.c プロジェクト: fenglyu/streem
int
node_run(parser_state* p)
{
  strm_value v;
  strm_state *state = malloc(sizeof(strm_state));

  memset(state, 0, sizeof(strm_state));
  node_init(state);

  exec_expr(state, (node*)p->lval, &v);
  if (state->exc != NULL) {
    if (state->exc->type != NODE_ERROR_RETURN) {
      strm_value v;
      exec_cputs(state, stderr, 1, &state->exc->arg, &v);
      /* TODO: garbage correct previous exception value */
      state->exc = NULL;
    }
  }
  return STRM_OK;
}
コード例 #12
0
ファイル: exec.c プロジェクト: fenglyu/streem
static int
exec_call(strm_state* state, strm_string* name, int argc, strm_value* argv, strm_value* ret)
{
  int n;
  strm_value m;

  n = strm_var_get(state, name, &m);
  if (n == 0) {
    switch (m.type) {
    case STRM_VALUE_CFUNC:
      return ((exec_cfunc)m.val.p)(state, argc, argv, ret);
    case STRM_VALUE_PTR:
      {
        strm_lambda* lambda = strm_value_ptr(m);
        node_lambda* nlbd = lambda->body;
        node_values* args = (node_values*)nlbd->args;
        strm_state c = {0};
        int i;

        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, (strm_string*)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;
    }
  }
  node_raise(state, "function not found");
  return STRM_NG;
}
コード例 #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
ファイル: siodi.c プロジェクト: UlricE/SiagOffice
static LISP lexec_expr(LISP intp, LISP expr)
{
	exec_expr(name2interpreter(get_c_string(intp)), get_c_string(expr));
	return NIL;
}
コード例 #15
0
ファイル: exec.c プロジェクト: faicm/streem
static int
exec_expr(node_ctx* ctx, node* np, strm_value* val)
{
  int n;

  if (np == NULL) {
    return 1;
  }

  switch (np->type) {
/*
  case NODE_ARGS:
    break;
  case NODE_EMIT:
    break;
*/
  case NODE_IDENT:
    *val = strm_var_get(np->value.v.s);
    return 0;
  case NODE_IF:
    {
      strm_value v;
      node_if* nif = (node_if*)np;
      n = exec_expr(ctx, nif->cond, &v);
      if (n) return n;
      if (strm_value_bool(v)) {
        return exec_expr(ctx, nif->then, val);
      }
      else if (nif->opt_else != NULL) {
        return exec_expr(ctx, nif->opt_else, val);
      }
      else {
        *val = strm_nil_value();
        return 0;
      }
    }
    break;
  case NODE_OP:
    {
      node_op* nop = (node_op*)np;
      strm_value args[2];
      int i=0;

      if (nop->lhs) {
        n = exec_expr(ctx, nop->lhs, &args[i++]);
        if (n) return n;
      }
      if (nop->rhs) {
        n = exec_expr(ctx, nop->rhs, &args[i++]);
        if (n) return n;
      }
      return exec_call(ctx, nop->op, i, args, val);
    }
    break;
  case NODE_CALL:
    {
      /* TODO: wip code of ident */
      node_call* ncall = (node_call*)np;
      if (ncall->ident != NULL) {
        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(ctx, v0->data[i], &args[i]);
          if (n) return n;
        }
        return exec_call(ctx, ncall->ident->value.v.s, i, args, val);
      }
      else {
        node_block* nblk = (node_block*)ncall;
        strm_value v;
        int n;
        n = exec_expr(ctx, nblk->compstmt, &v);
        if (n && ctx->exc->type == NODE_ERROR_RETURN) {
          *val = ctx->exc->arg;
          free(ctx->exc);
          return 0;
        }
      }
    }
    break;
  case NODE_RETURN:
    {
      node_return* nreturn = (node_return*)np;
      ctx->exc = malloc(sizeof(node_error));
      ctx->exc->type = NODE_ERROR_RETURN;
      n = exec_expr(ctx, nreturn->rv, &ctx->exc->arg);
      return n;
    }
    break;
  case NODE_STMTS:
    {
      int i, n;
      node_values* v = (node_values*)np;
      for (i = 0; i < v->len; i++) {
        n = exec_expr(ctx, v->data[i], val);
        if (n) return n;
      }
      return 0;
    }
    break;
  case NODE_VALUE:
    switch (np->value.t) {
    case NODE_VALUE_BOOL:
      *val = strm_bool_value(np->value.v.b);
      return 0;
    case NODE_VALUE_NIL:
      *val = strm_nil_value();
      return 0;
    case NODE_VALUE_STRING:
    case NODE_VALUE_IDENT:
      *val = strm_ptr_value(np->value.v.s);
      return 0;
    case NODE_VALUE_DOUBLE:
      *val = strm_flt_value(np->value.v.d);
      return 0;
    case NODE_VALUE_INT:
      *val = strm_int_value(np->value.v.i);
      return 0;
      /* following type should not be evaluated */
    case NODE_VALUE_ERROR:
    case NODE_VALUE_USER:
    default:
      return 1;
    }
  default:
    break;
  }
  return 1;
}
コード例 #16
0
ファイル: interp_new.cpp プロジェクト: Ceyhunn/src
/* bll and parent bll  */
int pre_exec_new(struct band_list_el *head){

  struct band_list_el *bll = head;

  int id = bll->band_id;

  switch(id){
  case CAPET_NUMB:
    return exec_capet_numb(bll);
  case CAPET_CHR:
    return exec_capet_chr(bll);
  case CAPET_STR:
    return exec_capet_str(bll);
  case CAPET_FLOAT:
    return exec_capet_float(bll);
  case CAPET_IDT:
    return exec_capet_idt(bll);
  case CAPET_CRG1:
    return exec_capet_crg1(bll);
  case CAPET_CRG2:
    return exec_capet_crg2(bll);
  case CAPET_STRMEM:
    return exec_capet_strmem(bll);
  case CAPET_EXPR:
    return exec_capet_expr(bll);
  case INIT_DOVR:
    return exec_init_dovr(bll);
  case CHECK_DOVR:
    return exec_check_dovr(bll);
  case STEP_DOVR:
    return exec_step_dovr(bll);
  case NEQEDERKI2:
    return exec_neqederki_exp(bll);
  case NEQ_TOP:
    return exec_neq_top(bll);
  case SEC1:
    return exec_secim(bll);
  case HAL1:
    return exec_hal1(bll);
  case HAL1S:
    return exec_hal1s(bll);
  case SUS1:
	  return exec_sus1(bll);
  case FREE_SEC_DYN_STK:
	  return exec_free_sec_dyn_stk(bll);
  case EGER_EXP2:
    return exec_eger_exp(bll);
  case YOXSA:
    return exec_yoxsa(bll);
  case ASGN:
    return exec_asgn(bll);
  case NUMB:
    return exec_numb(bll);
  case ARTSIN:
    return exec_artsin(bll);
  case AZALSIN:
    return exec_azalsin(bll);
  case FLOAT:
    return exec_float(bll);
  case SHERT:
    return exec_shert(bll);
  case CHR:
    return exec_chr(bll);
  case EXPR:
    return exec_expr(bll);
  case STR_ADRS:
    return exec_str_adrs(bll);
  case IDT_ADRS:
    return exec_idt_adrs(bll);
  case IDT_VAL:
    return exec_idt_val(bll);
  case IDT_OFST:
    return exec_idt_ofst(bll);
  case CRG1_ADRS:
    return exec_crg1_adrs(bll);
  case CRG1_VAL:
    return exec_crg1_val(bll);
  case CRG1_OFST:
    return exec_crg1_ofst(bll);
  case CRG2_OFST:
    return exec_crg2_ofst(bll);
  case STRMEM_VAL:
    return exec_strmem_val(bll);
  case CRG2_ADRS:
    return exec_crg2_adrs(bll);
  case CRG2_VAL:
    return exec_crg2_val(bll);
  case DAXILET_IDT:
    return exec_daxilet_idt(bll); 
  case DAVAMET1:
    return exec_davamet1(bll);
  case DAYAN1:
    return exec_dayan1(bll);
  case FUNK:
    return exec_func(bll);
  case FCALL1:
    return exec_fcall1(bll, NULL);
  case SNMEM:
    return exec_snmem(bll);
  case PUT_RET_ADDR:
    return exec_put_ret_addr(bll);
  case POP_OBSTK:
    return exec_pop_obstk(bll);
  case FARGS_NUMB:
    return exec_fargs_numb(bll);
  case FPARM_IDT_VAL:
    return exec_fparm_idt_val(bll);
  case QAYTAR1:
    return exec_qaytar1(bll);
  case SON:
    return exec_son(bll);
 }

  return 0;
}
コード例 #17
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;
}
コード例 #18
0
ファイル: exec.c プロジェクト: fenglyu/streem
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;
}