static int exec_seq(strm_state* state, int argc, strm_value* args, strm_value* ret) { long start, end, inc=1; struct seq_seeder *s; switch (argc) { case 1: start = 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: node_raise(state, "wrong number of arguments"); return STRM_NG; } s = malloc(sizeof(struct seq_seeder)); s->n = start; s->inc = inc; s->end = end; *ret = strm_task_value(strm_task_new(strm_task_prod, seq_seed, NULL, (void*)s)); return STRM_OK; }
static int exec_call(node_ctx* ctx, strm_string *name, int argc, strm_value* args, strm_value* ret) { strm_value m = strm_var_get(name); if (m.type == STRM_VALUE_CFUNC) { return ((exec_cfunc)m.val.p)(ctx, argc, args, ret); } node_raise(ctx, "function not found"); return 1; }
static int exec_bar(node_ctx* ctx, int argc, strm_value* args, strm_value* ret) { assert(argc == 2); 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 0; } if (strm_task_p(args[0]) && strm_task_p(args[1])) { strm_connect(strm_value_task(args[0]), strm_value_task(args[1])); *ret = args[1]; return 0; } node_raise(ctx, "type error"); return 1; }
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; }
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 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; }