static int cursor_columns(Value *vret, Value *v, RefNode *node) { int i; RefCursor *rc = Value_vp(*v); int num = sqlite3_column_count(rc->stmt); RefArray *r = fs->refarray_new(num); *vret = vp_Value(r); for (i = 0; i < num; i++) { const char *col_p = sqlite3_column_name(rc->stmt, i); r->p[i] = fs->cstr_Value(fs->cls_str, col_p, -1); } return TRUE; }
// 削除した要素を返す static int map_delete(Value *vret, Value *v, RefNode *node) { RefMap *rm = Value_vp(*v); Value key = v[1]; if (rm->lock_count > 0) { throw_error_select(THROW_CANNOT_MODIFY_ON_ITERATION); return FALSE; } if (!refmap_del(vret, rm, key)) { return FALSE; } return TRUE; }
int map_iterator(Value *vret, Value *v, RefNode *node) { RefMap *rm = Value_vp(*v); int type = FUNC_INT(node); Ref *r = ref_new(cls_mapiter); rm->lock_count++; r->v[INDEX_MAPITER_VAL] = Value_cp(*v); r->v[INDEX_MAPITER_TYPE] = int32_Value(type); r->v[INDEX_MAPITER_PTR] = ptr_Value(NULL); r->v[INDEX_MAPITER_IDX] = int32_Value(0); *vret = vp_Value(r); return TRUE; }
static int ipaddr_new(Value *vret, Value *v, RefNode *node) { RefStr *rs = Value_vp(v[1]); RefSockAddr *rsa; if (str_has0(rs->c, rs->size)) { fs->throw_errorf(fs->mod_io, "SocketError", "No address found"); return FALSE; } rsa = cstr_to_ipaddr(rs->c, FALSE); if (rsa == NULL) { return FALSE; } *vret = vp_Value(rsa); return TRUE; }
static int markdown_heading_level(Value *vret, Value *v, RefNode *node) { Ref *r = Value_vp(*v); Markdown *md = Value_ptr(r->v[INDEX_MARKDOWN_MD]); if (fg->stk_top > v + 1) { int64_t i64 = fs->Value_int64(v[1], NULL); if (i64 < 1 || i64 > 6) { fs->throw_errorf(fs->mod_lang, "ValueError", "Out of range (1 - 6)"); return FALSE; } md->heading_level = (int)i64; } else { *vret = int32_Value(md->heading_level); } return TRUE; }
static int strio_tostr(Value *vret, Value *v, RefNode *node) { RefBytesIO *mb = Value_bytesio(*v); if (fg->stk_top > v + 1) { Str s = Str_new(mb->buf.p, mb->buf.size); RefStr *fmt = Value_vp(v[1]); if (!string_format_sub(vret, s, fmt->c, fmt->size, FALSE)) { return FALSE; } } else { *vret = cstr_Value(fs->cls_str, mb->buf.p, mb->buf.size); } return TRUE; }
static int matrix_hash(Value *vret, Value *v, RefNode *node) { int i, size; RefMatrix *mat = Value_vp(*v); uint32_t *i32 = (uint32_t*)mat->d; uint32_t hash = 0; size = mat->rows * mat->cols * 2; // sizeof(double) / sizeof(uint32_t) for (i = 0; i < size; i++) { hash = hash * 31 + i32[i]; } *vret = int32_Value(hash & INT32_MAX); return TRUE; }
static int map_add_entry(Value *vret, Value *v, RefNode *node) { RefMap *rm = Value_vp(*v); Ref *r = Value_ref(v[1]); HashValueEntry *ve; if (rm->lock_count > 0) { throw_error_select(THROW_CANNOT_MODIFY_ON_ITERATION); return FALSE; } ve = refmap_add(rm, r->v[0], TRUE, FALSE); if (ve == NULL) { return FALSE; } ve->val = Value_cp(r->v[1]); return TRUE; }
static int strio_new(Value *vret, Value *v, RefNode *node) { RefStr *src; Ref *r = ref_new(fv->cls_strio); *vret = vp_Value(r); if (fg->stk_top > v + 1) { src = Value_vp(v[1]); } else { src = fs->str_0; } r->v[INDEX_TEXTIO_STREAM] = vp_Value(bytesio_new_sub(src->c, src->size)); r->v[INDEX_TEXTIO_TEXTIO] = vp_Value(fv->ref_textio_utf8); return TRUE; }
static int vector_index_set(Value *vret, Value *v, RefNode *node) { RefVector *vec = Value_vp(*v); int err = FALSE; int64_t i = fs->Value_int64(v[1], &err); if (i < 0) { i += vec->size; } if (i >= 0 && i < vec->size) { vec->d[i] = fs->Value_float(v[i]); } else { fs->throw_error_select(THROW_INVALID_INDEX__VAL_INT, v[1], vec->size); return FALSE; } return TRUE; }
static int vector_minus(Value *vret, Value *v, RefNode *node) { const RefVector *v1 = Value_vp(v[0]); int size, i; RefVector *vec; size = v1->size; vec = fs->buf_new(cls_vector, sizeof(RefVector) + sizeof(double) * size); *vret = vp_Value(vec); vec->size = size; for (i = 0; i < size; i++) { vec->d[i] = -v1->d[i]; } return TRUE; }
static int markdown_heading_list(Value *vret, Value *v, RefNode *node) { Ref *r = Value_vp(*v); Markdown *md = Value_ptr(r->v[INDEX_MARKDOWN_MD]); RefArray *ra = fs->refarray_new(0); MDNodeLink *link; *vret = vp_Value(ra); for (link = md->heading; link != NULL; link = link->next) { StrBuf sb; fs->StrBuf_init_refstr(&sb, 0); MDNode_tostr(&sb, link->node); *fs->refarray_push(ra) = fs->StrBuf_str_Value(&sb, fs->cls_str); } return TRUE; }
static void xmlelem_add_attr(Ref *r, const char *ckey, const char *cval) { RefMap *rm; Value key; HashValueEntry *ve; if (Value_isref(r->v[INDEX_ELEM_ATTR])) { rm = Value_vp(r->v[INDEX_ELEM_ATTR]); } else { rm = fs->refmap_new(0); r->v[INDEX_ELEM_ATTR] = vp_Value(rm); } key = fs->cstr_Value(fs->cls_str, ckey, -1); ve = fs->refmap_add(rm, key, TRUE, FALSE); fs->unref(key); fs->unref(ve->val); ve->val = fs->cstr_Value(fs->cls_str, cval, -1); }
static int textio_close(Value *vret, Value *v, RefNode *node) { Ref *r = Value_ref(*v); RefTextIO *tio = Value_vp(r->v[INDEX_TEXTIO_TEXTIO]); if (tio != NULL) { if (tio != (RefTextIO*)fv->ref_textio_utf8) { IconvIO_close(&tio->in); IconvIO_close(&tio->out); free(tio); } r->v[INDEX_TEXTIO_TEXTIO] = VALUE_NULL; } Value_dec(r->v[INDEX_TEXTIO_STREAM]); r->v[INDEX_TEXTIO_STREAM] = VALUE_NULL; return TRUE; }
static int matrix_to_list(Value *vret, Value *v, RefNode *node) { const RefMatrix *mat = Value_vp(*v); RefArray *ra = fs->refarray_new(mat->rows); int i, j; *vret = vp_Value(ra); for (i = 0; i < mat->rows; i++) { RefArray *ra2 = fs->refarray_new(mat->cols); const double *src = &mat->d[i * mat->cols]; ra->p[i] = vp_Value(ra2); for (j = 0; j < mat->cols; j++) { ra2->p[j] = fs->float_Value(fs->cls_float, src[j]); } } return TRUE; }
static int matrix_minus(Value *vret, Value *v, RefNode *node) { const RefMatrix *m1 = Value_vp(v[0]); int size, i; RefMatrix *mat; size = m1->rows * m1->cols; mat = fs->buf_new(cls_matrix, sizeof(RefMatrix) + sizeof(double) * size); *vret = vp_Value(mat); mat->rows = m1->rows; mat->cols = m1->cols; for (i = 0; i < size; i++) { mat->d[i] = -m1->d[i]; } return TRUE; }
int set_add_value(Value *vret, Value *v, RefNode *node) { RefMap *rm = Value_vp(*v); Value *v1 = v + 1; int argc = fg->stk_top - fg->stk_base - 1; int i; if (rm->lock_count > 0) { throw_error_select(THROW_CANNOT_MODIFY_ON_ITERATION); return FALSE; } for (i = 0; i < argc; i++) { if (refmap_add(rm, v1[i], TRUE, FALSE) == NULL) { return FALSE; } } return TRUE; }
static int matrix_index_set(Value *vret, Value *v, RefNode *node) { RefMatrix *mat = Value_vp(*v); int64_t i = fs->Value_int64(v[1], NULL); // 行 int64_t j = fs->Value_int64(v[2], NULL); // 列 if (i < 0) { i += mat->rows; } if (j < 0) { j += mat->cols; } if (i >= 0 && i < mat->rows && j >= 0 && j < mat->cols) { mat->d[i * mat->cols + j] = fs->Value_float(v[3]); } else { fs->throw_errorf(fs->mod_lang, "IndexError", "Invalid matrix index ((%v, %v) of (%d, %d))", v[1], v[2], mat->rows, mat->cols); return FALSE; } return TRUE; }
// a["hoge"] int map_index(Value *vret, Value *v, RefNode *node) { RefMap *rm = Value_vp(*v); HashValueEntry *ep = NULL; Value key = v[1]; if (!refmap_get(&ep, rm, key)) { return FALSE; } if (ep != NULL) { // 一致 *vret = Value_cp(ep->val); } else { throw_errorf(fs->mod_lang, "IndexError", "No keys exists %v", key); return FALSE; } return TRUE; }
static int ipaddr_family(Value *vret, Value *v, RefNode *node) { RefSockAddr *rsa = Value_vp(*v); const char *name = ""; switch (rsa->addr->sa_family) { case AF_INET: name = "IPv4"; break; case AF_INET6: name = "IPv6"; break; default: break; } *vret = fs->cstr_Value(fs->cls_str, name, -1); return TRUE; }
static int cursor_next(Value *vret, Value *v, RefNode *node) { RefCursor *rc = Value_vp(*v); int result = sqlite3_step(rc->stmt); if (result == SQLITE_DONE) { fs->throw_stopiter(); return FALSE; } else if (result == SQLITE_ROW) { if (!cursor_get(vret, rc)) { return FALSE; } } else { fs->throw_errorf(mod_sqlite, "SQLiteError", "sqlite3_step error (%d)", result); return FALSE; } return TRUE; }
// a.get("hoge", "Not Exist") -> "Not Exist" int map_get(Value *vret, Value *v, RefNode *node) { RefMap *rm = Value_vp(*v); HashValueEntry *ep = NULL; Value key = v[1]; if (!refmap_get(&ep, rm, key)) { return FALSE; } if (ep != NULL) { // 一致 *vret = Value_cp(ep->val); } else { if (v + 2 < fg->stk_top) { *vret = Value_cp(v[2]); } } return TRUE; }
/* * 転置行列 */ static int matrix_transpose(Value *vret, Value *v, RefNode *node) { const RefMatrix *mat = Value_vp(*v); RefMatrix *mat2; int i, j; int rows = mat->rows; int cols = mat->cols; mat2 = fs->buf_new(cls_matrix, sizeof(RefMatrix) + sizeof(double) * rows * cols); *vret = vp_Value(mat2); mat2->rows = cols; mat2->cols = rows; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { mat2->d[j * rows + i] = mat->d[i * cols + j]; } } return TRUE; }
/** * 各要素をx倍する */ static int vector_muldiv(Value *vret, Value *v, RefNode *node) { const RefVector *v1 = Value_vp(v[0]); double d = fs->Value_float(v[1]); int i; RefVector *vec; if (FUNC_INT(node)) { d = 1.0 / d; } vec = fs->buf_new(cls_vector, sizeof(RefVector) + sizeof(double) * v1->size); *vret = vp_Value(vec); vec->size = v1->size; for (i = 0; i < v1->size; i++) { vec->d[i] = v1->d[i] * d; } return TRUE; }
int map_dispose(Value *vret, Value *v, RefNode *node) { RefMap *r = Value_vp(*v); int i; for (i = 0; i < r->entry_num; i++) { HashValueEntry *p = r->entry[i]; while (p != NULL) { HashValueEntry *prev = p; unref(p->key); unref(p->val); p = p->next; free(prev); } } free(r->entry); r->entry = NULL; r->entry_num = 0; return TRUE; }
static int conn_new(Value *vret, Value *v, RefNode *node) { int flag = SQLITE_OPEN_READONLY; sqlite3 *conn = NULL; int result = SQLITE_OK; Ref *r = fs->ref_new(cls_sqlite); Str path_s; char *path = fs->file_value_to_path(&path_s, v[1], 0); *vret = vp_Value(r); if (path == NULL) { return FALSE; } if (fg->stk_top > v + 2) { RefStr *m = Value_vp(v[2]); if (str_eq(m->c, m->size, "r", -1)) { } else if (str_eq(m->c, m->size, "w", -1)) { flag = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; } else { fs->throw_errorf(fs->mod_lang, "ValueError", "Unknown open mode %q", m->c); free(path); return FALSE; } } result = sqlite3_open_v2(path, &conn, flag, NULL); if (result != SQLITE_OK || conn == NULL) { fs->throw_error_select(THROW_CANNOT_OPEN_FILE__STR, path_s); free(path); return FALSE; } r->v[INDEX_SQLITE_CONN] = ptr_Value(conn); r->v[INDEX_SQLITE_FUNC] = vp_Value(fs->refarray_new(0)); free(path); return TRUE; }
static wchar_t *make_filter_string(RefArray *r) { int i; int pos = 0; int max = 256; wchar_t *buf = malloc(max * sizeof(wchar_t)); for (i = 0; i < r->size; i++) { Str name, ft; int name_len, ft_len; wchar_t *wname, *wft; int next; split_filter_name(&name, &ft, Value_vp(r->p[i])); wname = cstr_to_utf16(name.p, name.size); wft = cstr_to_utf16(ft.p, ft.size); // 追加後サイズ計算 name_len = wcslen(wname); ft_len = wcslen(wft); next = pos + name_len + ft_len + 8; if (next > max) { while (next > max) { max *= 2; } buf = realloc(buf, max * sizeof(wchar_t)); } // 文字列を\0区切りで追加 wcscpy(&buf[pos], wname); pos += name_len + 1; wcscpy(&buf[pos], wft); pos += ft_len + 1; } buf[pos++] = L'\0'; buf[pos++] = L'\0'; return buf; }
static int mapiter_next(Value *vret, Value *v, RefNode *node) { Ref *r = Value_ref(*v); RefMap *map = Value_vp(r->v[INDEX_MAPITER_VAL]); int idx = Value_integral(r->v[INDEX_MAPITER_IDX]); HashValueEntry *ep = Value_ptr(r->v[INDEX_MAPITER_PTR]); if (ep != NULL) { ep = ep->next; } while (ep == NULL && idx < map->entry_num) { ep = map->entry[idx]; idx++; } r->v[INDEX_MAPITER_IDX] = int32_Value(idx); r->v[INDEX_MAPITER_PTR] = ptr_Value(ep); if (ep != NULL) { switch (Value_integral(r->v[INDEX_MAPITER_TYPE])) { case ITERATOR_KEY: *vret = Value_cp(ep->key); break; case ITERATOR_VAL: *vret = Value_cp(ep->val); break; default: { Ref *r2 = ref_new(fv->cls_entry); *vret = vp_Value(r2); r2->v[INDEX_ENTRY_KEY] = Value_cp(ep->key); r2->v[INDEX_ENTRY_VAL] = Value_cp(ep->val); break; } } } else { throw_stopiter(); return FALSE; } return TRUE; }
static int vector_marshal_write(Value *vret, Value *v, RefNode *node) { const RefVector *vec = Value_vp(*v); Value w = Value_ref(v[1])->v[INDEX_MARSHALDUMPER_SRC]; uint8_t *data; int i; if (!fs->stream_write_uint32(w, vec->size)) { return FALSE; } data = malloc(8 * vec->size); for (i = 0; i < vec->size; i++) { double_to_bytes(data + i * 8, vec->d[i]); } if (!fs->stream_write_data(w, (const char*)data, 8 * vec->size)) { free(data); return FALSE; } free(data); return TRUE; }
static int vector_tostr(Value *vret, Value *v, RefNode *node) { StrBuf sb; const RefVector *vec = Value_vp(*v); int i; fs->StrBuf_init_refstr(&sb, 0); fs->StrBuf_add(&sb, "Vector(", 7); for (i = 0; i < vec->size; i++) { char cbuf[64]; if (i > 0) { fs->StrBuf_add(&sb, ", ", 2); } sprintf(cbuf, "%g", vec->d[i]); fs->StrBuf_add(&sb, cbuf, -1); } fs->StrBuf_add_c(&sb, ')'); *vret = fs->StrBuf_str_Value(&sb, fs->cls_str); return TRUE; }