static int invoke_func(Value *vret, Value cvt, GenML *gm, const char *name, GenMLNode *node, int opt) { RefStr *rs_name = fs->intern(name, -1); GenMLArgs *arg = fs->buf_new(cls_gmlargs, sizeof(GenMLArgs)); arg->gm = gm; arg->node = node; arg->cvt = cvt; if (opt > 0) { fs->Value_push("vrd", cvt, arg, opt); if (!fs->call_member_func(rs_name, 2, TRUE)) { arg->node = NULL; fs->unref(vp_Value(arg)); return FALSE; } } else { fs->Value_push("vr", cvt, arg); if (!fs->call_member_func(rs_name, 1, TRUE)) { arg->node = NULL; fs->unref(vp_Value(arg)); return FALSE; } } arg->node = NULL; fs->unref(vp_Value(arg)); fg->stk_top--; *vret = *fg->stk_top; return TRUE; }
static int net_getaddrinfo(Value *vret, Value *v, RefNode *node) { struct addrinfo *res = NULL; struct addrinfo *ai; RefArray *ra; RefStr *rs = Value_vp(v[1]); int err; if (str_has0(rs->c, rs->size)) { fs->throw_errorf(fs->mod_io, "SocketError", "No address found"); return FALSE; } err = getaddrinfo_sub(&res, rs->c, NULL, 0); if (err != 0) { throw_socket_error(err); return FALSE; } ra = fs->refarray_new(0); *vret = vp_Value(ra); for (ai = res; ai != NULL; ai = ai->ai_next) { Value *vt = fs->refarray_push(ra); *vt = vp_Value(new_refsockaddr(ai->ai_addr, FALSE)); } freeaddrinfo(res); return TRUE; }
static int listener_accept(Value *vret, Value *v, RefNode *node) { RefListener *ls = Value_vp(*v); socklen_t sa_len; struct sockaddr *sa; FileHandle sock; if (ls->sock == -1) { fs->throw_error_select(THROW_NOT_OPENED_FOR_READ); return FALSE; } sa = malloc(sizeof(struct sockaddr_in6)); sock = accept(ls->sock, sa, &sa_len); if (sock != -1) { Ref *sock_r = fs->ref_new(cls_socketio); RefFileHandle *fh = fs->buf_new(NULL, sizeof(RefFileHandle)); fs->init_stream_ref(sock_r, STREAM_READ|STREAM_WRITE); sock_r->v[INDEX_FILEIO_HANDLE] = vp_Value(fh); fh->fd_read = sock; fh->fd_write = sock; *vret = vp_Value(sock_r); } return TRUE; }
static int cursor_get(Value *vret, RefCursor *rc) { int i; int num = sqlite3_column_count(rc->stmt); if (rc->is_map) { RefMap *rm = fs->refmap_new(num); *vret = vp_Value(rm); for (i = 0; i < num; i++) { const char *key_p = sqlite3_column_name(rc->stmt, i); Value key = fs->cstr_Value(NULL, key_p, -1); HashValueEntry *ve = fs->refmap_add(rm, key, TRUE, FALSE); if (ve != NULL) { ve->val = cursor_get_sub(rc->stmt, i); } fs->unref(key); } } else { RefArray *ra = fs->refarray_new(num); *vret = vp_Value(ra); for (i = 0; i < num; i++) { ra->p[i] = cursor_get_sub(rc->stmt, i); } } return TRUE; }
static int textio_new(Value *vret, Value *v, RefNode *node) { RefTextIO *tio; RefCharset *cs = Value_vp(v[2]); Ref *r = ref_new(fs->cls_textio); *vret = vp_Value(r); tio = buf_new(NULL, sizeof(RefTextIO)); r->v[INDEX_TEXTIO_TEXTIO] = vp_Value(tio); r->v[INDEX_TEXTIO_STREAM] = Value_cp(v[1]); tio->in.ic = (void*)-1; tio->out.ic = (void*)-1; tio->cs = cs; tio->trans = FALSE; if (fg->stk_top > v + 3 && Value_bool(v[3])) { tio->trans = TRUE; } if (fg->stk_top > v + 4) { r->v[INDEX_TEXTIO_NEWLINE] = Value_cp(v[4]); } return TRUE; }
static void v_ctextio_init(void) { Ref *ref = ref_new(fs->cls_textio); fg->v_ctextio = vp_Value(ref); ref->v[INDEX_TEXTIO_STREAM] = Value_cp(fg->v_cio); ref->v[INDEX_TEXTIO_TEXTIO] = vp_Value(fv->ref_textio_utf8); }
static int socket_new(Value *vret, Value *v, RefNode *node) { FileHandle fd; Value addr = v[1]; int port = fs->Value_int64(v[2], NULL); RefNode *addr_type = fs->Value_type(addr); Ref *r = fs->ref_new(cls_socketio); *vret = vp_Value(r); if (port < 0 || port > 65535) { fs->throw_errorf(fs->mod_lang, "ValueError", "Illigal port number (0 - 65535)"); return FALSE; } if (addr_type == cls_ipaddr || addr_type == fs->cls_str) { if (!socket_connect_sub(&fd, addr, port)) { fs->throw_errorf(fs->mod_io, "SocketError", "Failed to connect"); return FALSE; } } else if (addr_type == fs->cls_list) { RefArray *ra = Value_vp(addr); int i; int succeeded = FALSE; for (i = 0; i < ra->size; i++) { Value ad = ra->p[i]; RefNode *ad_type = fs->Value_type(ad); if (ad_type != cls_ipaddr && ad_type != fs->cls_str) { fs->throw_errorf(fs->mod_lang, "TypeError", "Array of IPAddr or Str required but %n (argument #1)", ad_type); return FALSE; } if (socket_connect_sub(&fd, ad, port)) { succeeded = TRUE; break; } } if (!succeeded) { fs->throw_errorf(fs->mod_io, "SocketError", "Fault to connect"); return FALSE; } } else { fs->throw_errorf(fs->mod_lang, "TypeError", "IPAddr, Str, List required but %n (argument #1)", addr_type); return FALSE; } fs->init_stream_ref(r, STREAM_READ|STREAM_WRITE); { RefFileHandle *fh = fs->buf_new(NULL, sizeof(RefFileHandle)); r->v[INDEX_FILEIO_HANDLE] = vp_Value(fh); fh->fd_read = fd; fh->fd_write = fd; } return TRUE; }
static int strio_dup(Value *vret, Value *v, RefNode *node) { RefBytesIO *src = Value_bytesio(*v); Ref *r = ref_new(fv->cls_strio); *vret = vp_Value(r); r->v[INDEX_TEXTIO_STREAM] = vp_Value(bytesio_new_sub(src->buf.p, src->buf.size)); r->v[INDEX_TEXTIO_TEXTIO] = vp_Value(fv->ref_textio_utf8); return TRUE; }
static Ref *xmlelem_new(const char *name) { RefArray *ra; Ref *r = fs->ref_new(cls_xmlelem); r->v[INDEX_ELEM_NAME] = vp_Value(fs->intern(name, -1)); ra = fs->refarray_new(0); ra->rh.type = cls_nodelist; r->v[INDEX_ELEM_CHILDREN] = vp_Value(ra); return r; }
/** * 右辺が数値の場合、各要素をx倍する * 右辺がRefMatrixの場合、行列の積を求める */ static int matrix_multiple(Value *vret, Value *v, RefNode *node) { RefMatrix *m1 = Value_vp(v[0]); const RefNode *v1_type = fs->Value_type(v[1]); int cols1 = m1->cols; int rows1 = m1->rows; if (v1_type == cls_matrix) { RefMatrix *m2 = Value_vp(v[1]); RefMatrix *mat; int cols2 = m2->cols; int rows2 = m2->rows; int i, j, k; if (cols1 != rows2) { fs->throw_errorf(fs->mod_lang, "ValueError", "RefMatrix size mismatch"); return FALSE; } mat = fs->buf_new(cls_matrix, sizeof(RefMatrix) + sizeof(double) * rows1 * cols2); *vret = vp_Value(mat); mat->rows = rows1; mat->cols = cols2; for (i = 0; i < rows1; i++) { for (j = 0; j < cols2; j++) { double sum = 0.0; for (k = 0; k < cols1; k++) { sum += m1->d[i * cols1 + k] * m2->d[k * cols2 + j]; } mat->d[i * cols2 + j] = sum; } } } else if (v1_type == fs->cls_float || v1_type == fs->cls_int || v1_type == fs->cls_frac) { int i; double d2 = fs->Value_float(v[1]); int size = cols1 * rows1; RefMatrix *mat = fs->buf_new(cls_matrix, sizeof(RefMatrix) + sizeof(double) * size); *vret = vp_Value(mat); mat->cols = cols1; mat->rows = rows1; for (i = 0; i < size; i++) { mat->d[i] = m1->d[i] * d2; } } else { fs->throw_error_select(THROW_ARGMENT_TYPE2__NODE_NODE_NODE_INT, cls_matrix, fs->cls_number, v1_type, 1); return FALSE; } return TRUE; }
/* * 0行列 */ static int matrix_zero(Value *vret, Value *v, RefNode *node) { int64_t size1 = fs->Value_int64(v[1], NULL); int64_t size2 = fs->Value_int64(v[2], NULL); RefMatrix *mat; double *p; // 0x0の行列も可能 if (size1 < 0 || size1 > 16384 || size2 < 0 || size2 > 16384) { fs->throw_errorf(fs->mod_lang, "ValueError", "Illigal Matrix size (0 - 16384)"); return FALSE; } mat = fs->buf_new(cls_matrix, sizeof(RefMatrix) + sizeof(double) * size1 * size2); *vret = vp_Value(mat); mat->cols = size1; mat->rows = size2; p = mat->d; { int size = size1 * size2; int i; for (i = 0; i < size; i++) { *p = 0.0; p++; } } return TRUE; }
void throw_stopiter() { if (fg->error != VALUE_NULL) { unref(fg->error); } fg->error = vp_Value(ref_new(fs->cls_stopiter)); }
static int vector_new(Value *vret, Value *v, RefNode *node) { Value *vv = v + 1; int size = (fg->stk_top - v) - 1; int i; RefVector *vec; if (size == 1) { if (fs->Value_type(v[1]) == fs->cls_list) { RefArray *ra = Value_vp(v[1]); vv = ra->p; size = ra->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++) { const RefNode *v_type = fs->Value_type(vv[i]); if (v_type != fs->cls_float && v_type != fs->cls_int && v_type != fs->cls_frac) { fs->throw_error_select(THROW_ARGMENT_TYPE__NODE_NODE_INT, fs->cls_number, v_type, i + 1); return FALSE; } vec->d[i] = fs->Value_float(vv[i]); } return TRUE; }
static int markdown_new(Value *vret, Value *v, RefNode *node) { RefNode *cls_markdown = FUNC_VP(node); Ref *ref; Markdown *md; RefNode *type = fs->Value_type(*v); // 継承可能なクラス if (type == fs->cls_fn) { ref = fs->ref_new(cls_markdown); *vret = vp_Value(ref); } else { ref = Value_vp(*v); *vret = fs->Value_cp(*v); } md = malloc(sizeof(Markdown)); memset(md, 0, sizeof(Markdown)); ref->v[INDEX_MARKDOWN_MD] = ptr_Value(md); fs->Mem_init(&md->mem, 1024); md->tabstop = 4; md->heading_level = 1; md->footnote_id = 1; md->heading_p = &md->heading; md->footnote_p = &md->footnote; fs->Hash_init(&md->hilight, &md->mem, 16); return TRUE; }
/** * 複製 */ int map_dup(Value *vret, Value *v, RefNode *node) { RefMap *src = Value_vp(*v); RefNode *type = FUNC_VP(node); int i; int max = src->entry_num; RefMap *dst = buf_new(type, sizeof(RefMap)); *vret = vp_Value(dst); dst->count = src->count; dst->entry_num = max; dst->entry = malloc(sizeof(HashValueEntry*) * max); for (i = 0; i < max; i++) { HashValueEntry *hsrc = src->entry[i]; HashValueEntry **hdst = &dst->entry[i]; for (; hsrc != NULL; hsrc = hsrc->next) { HashValueEntry *he = malloc(sizeof(HashValueEntry)); he->key = Value_cp(hsrc->key); he->val = Value_cp(hsrc->val); he->hash = hsrc->hash; *hdst = he; hdst = &he->next; } *hdst = NULL; } return TRUE; }
static int ipaddr_const_any(Value *vret, Value *v, RefNode *node) { RefSockAddr *rsa = NULL; switch (FUNC_INT(node)) { case AF_INET: rsa = fs->buf_new(cls_ipaddr, sizeof(RefSockAddr) + sizeof(struct sockaddr_in)); rsa->len = sizeof(struct sockaddr_in); { struct sockaddr_in *addr_in = (struct sockaddr_in*)rsa->addr; addr_in->sin_family = AF_INET; } break; case AF_INET6: rsa = fs->buf_new(cls_ipaddr, sizeof(RefSockAddr) + sizeof(struct sockaddr_in6)); rsa->len = sizeof(struct sockaddr_in6); { struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6*)rsa->addr; addr_in6->sin6_family = AF_INET6; } break; default: break; } if (rsa != NULL) { rsa->mask_bits = 0; *vret = vp_Value(rsa); } return TRUE; }
/* * 単位行列 */ static int matrix_i(Value *vret, Value *v, RefNode *node) { int64_t size = fs->Value_int64(v[1], NULL); RefMatrix *mat; double *p; // 0x0の行列も可能 if (size < 0 || size > MATRIX_MAX_SIZE) { fs->throw_errorf(fs->mod_lang, "ValueError", "Illigal Matrix size (0 - %d)", MATRIX_MAX_SIZE); return FALSE; } mat = fs->buf_new(cls_matrix, sizeof(RefMatrix) + sizeof(double) * size * size); *vret = vp_Value(mat); mat->rows = size; mat->cols = size; p = mat->d; { int i, j; for (i = 0; i < size; i++) { for (j = 0; j < size; j++) { *p = (i == j ? 1.0 : 0.0); p++; } } } return TRUE; }
int set_and(Value *vret, Value *v, RefNode *node) { RefMap *rm = Value_vp(*v); RefMap *rm1 = Value_vp(v[1]); int i; RefMap *rm2 = refmap_new(rm->count); *vret = vp_Value(rm2); rm2->rh.type = fs->cls_set; rm->lock_count++; for (i = 0; i < rm->entry_num; i++) { HashValueEntry *ep = rm->entry[i]; for (; ep != NULL; ep = ep->next) { Value key = ep->key; HashValueEntry *ep2 = NULL; // v1に同じ値があれば追加 if (!refmap_get(&ep2, rm1, key)) { goto ERROR_END; } if (ep2 != NULL) { if (refmap_add(rm2, key, TRUE, FALSE) == NULL) { goto ERROR_END; } } } } rm->lock_count--; return TRUE; ERROR_END: rm->lock_count--; return FALSE; }
int conv_graphics_to_image(Value *vret, GraphicsHandle img) { int width, height; int pitch, has_alpha = FALSE; // pitch:1行あたりのバイト数 BITMAP bmp; BITMAPINFO bmi; int y; uint8_t *dst; RefImage *fi = fs->buf_new(cls_image, sizeof(RefImage)); *vret = vp_Value(fi); GetObject(img, sizeof(bmp), &bmp); width = bmp.bmWidth; height = bmp.bmHeight; if (width > MAX_IMAGE_SIZE || height > MAX_IMAGE_SIZE) { fs->throw_errorf(mod_gui, "GuiError", "Graphics size too large (max:%d)", MAX_IMAGE_SIZE); return FALSE; } pitch = width * 3; pitch = (pitch + 3) & ~3; memset(&bmi, 0, sizeof(bmi)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = width; bmi.bmiHeader.biHeight = -height; // 負の数の場合、並びが上から下 bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 24; bmi.bmiHeader.biCompression = BI_RGB; dst = malloc(pitch * height); GetDIBits(hDisplayDC, img, 0, height, dst, &bmi, DIB_RGB_COLORS); // BGR -> RGB for (y = 0; y < height; y++) { int x; uint8_t *b1 = dst + y * pitch; for (x = 0; x < width; x++) { uint8_t *p = b1 + x * 3; uint8_t tmp = p[2]; p[2] = p[0]; p[0] = tmp; } } fi->data = dst; if (has_alpha) { fi->bands = BAND_RGBA; } else { fi->bands = BAND_RGB; } fi->width = width; fi->height = height; fi->pitch = pitch; 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 conn_memory(Value *vret, Value *v, RefNode *node) { sqlite3 *conn = NULL; Ref *r = fs->ref_new(cls_sqlite); int result = sqlite3_open(":memory:", &conn); *vret = vp_Value(r); if (result != SQLITE_OK || conn == NULL) { fs->throw_errorf(mod_sqlite, "SQLiteError", "Cannot connect sqlite (memory)"); return FALSE; } r->v[INDEX_SQLITE_CONN] = ptr_Value(conn); r->v[INDEX_SQLITE_FUNC] = vp_Value(fs->refarray_new(0)); return TRUE; }
static int mapentry_new(Value *vret, Value *v, RefNode *node) { Ref *r = ref_new(fv->cls_entry); *vret = vp_Value(r); r->v[INDEX_ENTRY_KEY] = Value_cp(v[1]); r->v[INDEX_ENTRY_VAL] = Value_cp(v[2]); return TRUE; }
static int matrix_new(Value *vret, Value *v, RefNode *node) { const Value *vv = v + 1; int size = (fg->stk_top - v) - 1; int cols = -1; int i; RefMatrix *mat; // 引数が配列1つで、その配列の最初の要素も配列の場合 if (size == 1) { if (fs->Value_type(v[1]) == fs->cls_list) { RefArray *ra = Value_vp(v[1]); if (ra->size > 0 && fs->Value_type(ra->p[0]) == fs->cls_list) { vv = ra->p; size = ra->size; } } } for (i = 0; i < size; i++) { const RefNode *v_type = fs->Value_type(vv[i]); RefArray *ra; if (v_type != fs->cls_list) { fs->throw_error_select(THROW_ARGMENT_TYPE__NODE_NODE_INT, fs->cls_list, v_type, i + 1); return FALSE; } ra = Value_vp(vv[i]); if (cols == -1) { cols = ra->size; } else { if (cols != ra->size) { fs->throw_errorf(fs->mod_lang, "ValueError", "List length mismatch"); return FALSE; } } } mat = fs->buf_new(cls_matrix, sizeof(RefMatrix) + sizeof(double) * size * cols); *vret = vp_Value(mat); mat->rows = size; mat->cols = cols; for (i = 0; i < size; i++) { RefArray *ra = Value_vp(vv[i]); int j; for (j = 0; j < cols; j++) { const RefNode *v_type = fs->Value_type(ra->p[j]); if (v_type != fs->cls_float && v_type != fs->cls_int && v_type != fs->cls_frac) { fs->throw_errorf(fs->mod_lang, "TypeError", "Number required but %n", v_type); return FALSE; } mat->d[i * cols + j] = fs->Value_float(ra->p[j]); } } 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 vector_dup(Value *vret, Value *v, RefNode *node) { const RefVector *src = Value_vp(*v); int size = sizeof(RefVector) + sizeof(double) * src->size; RefVector *dst = fs->buf_new(cls_vector, size); *vret = vp_Value(dst); memcpy(dst->d, src->d, size); return TRUE; }
void native_timer_new(int millisec, Ref *r) { UINT_PTR id = SetTimer(NULL, 0, millisec, timeout_callback); Value *v_tmp = GuiHash_add_p(&timer_entry, (const void*)id); *v_tmp = fs->Value_cp(vp_Value(r)); r->v[INDEX_TIMER_ID] = int32_Value(id); r->rh.nref++; }
static int net_getifaddrs(Value *vret, Value *v, RefNode *node) { RefArray *ra = fs->refarray_new(0); *vret = vp_Value(ra); if (!getifaddrs_sub(ra)) { return FALSE; } return TRUE; }
static int matrix_dup(Value *vret, Value *v, RefNode *node) { const RefMatrix *src = Value_vp(*v); int size = sizeof(RefMatrix) + sizeof(double) * src->cols * src->rows; RefMatrix *dst = fs->buf_new(cls_matrix, size); *vret = vp_Value(dst); memcpy(dst->d, src->d, size); return TRUE; }
int textio_charset(Value *vret, Value *v, RefNode *node) { Ref *ref = Value_ref(*v); RefTextIO *tio = Value_vp(ref->v[INDEX_TEXTIO_TEXTIO]); RefCharset *cs = (tio != NULL ? tio->cs : NULL); if (cs != NULL) { *vret = vp_Value(cs); } return TRUE; }
static int vector_to_list(Value *vret, Value *v, RefNode *node) { int i; const RefVector *vec = Value_vp(*v); RefArray *ra = fs->refarray_new(vec->size); *vret = vp_Value(ra); for (i = 0; i < vec->size; i++) { ra->p[i] = fs->float_Value(fs->cls_float, vec->d[i]); } return TRUE; }