int su_map_has(su_state *s, int idx) { value_t v = *STK(-1); unsigned hash = hash_value(&v); v = map_get(s, STK(TOP(idx))->obj.m, &v, hash); s->stack_top--; return v.type != SU_INV; }
int ft_rec(unsigned short map[16], t_tet *tets, t_tet *tet, int size) { int i; int j; if (tet->blocs == 0) return (0); i = (tet->ident != -1) ? HGH(((tets + tet->ident)->pos) & 0xff) - 1 : -1; j = (tet->ident != -1) ? LOW(((tets + tet->ident)->pos) & 0xff) : -1; while (++i + HGH(tet->max) < size) { while (++j + LOW(tet->max) < size) { if (ft_check(map, tet->blocs + (STK((i << 4) + j))) == 0) { ft_toggle(map, tet->blocs + (tet->pos = STK((i << 4) + j))); if (ft_rec(map, tets, tet + 1, size) == 0) return (0); ft_toggle(map, tet->pos + tet->blocs); } } j = -1; } return (-1); }
void su_vector_push(su_state *s, int idx, int num) { int i; value_t vec = *STK(TOP(idx)); for (i = 0; i < num; i++) vec = vector_push(s, vec.obj.vec, STK(-(num - i))); s->stack_top -= num; push_value(s, &vec); }
void su_vector_pop(su_state *s, int idx, int num) { int i; int n = (int)STK(TOP(num))->obj.num; value_t vec = *STK(TOP(idx)); for (i = 0; i < n; i++) vec = vector_pop(s, vec.obj.vec); push_value(s, &vec); }
int su_map_get(su_state *s, int idx) { value_t v = *STK(-1); unsigned hash = hash_value(&v); v = map_get(s, STK(TOP(idx))->obj.m, &v, hash); if (v.type == SU_INV) { s->stack_top--; return 0; } s->stack[s->stack_top - 1] = v; return 1; }
void su_map(su_state *s, int num) { int i; value_t k, v; value_t m = map_create_empty(s); for (i = num * 2; i > 0; i -= 2) { k = *STK(-i); v = *STK(-i + 1); m = map_insert(s, m.obj.m, &k, hash_value(&k), &v); } s->stack_top -= num * 2; push_value(s, &m); }
/* * search for a dynamic binding with the given tag * on the stack, and pushes the associanted value or * a default one if the binding was not found * the tag and a default value must have been pushed * on the stack */ static int dynamic_lookup(sly_state_t* S) { int idx; for(idx = S->sp - 3; idx >= 0; idx--) { if(STK(idx).type == SLY_TYPE_DYN_BIND && SLY_OBJ_EQ(SLY_DYN_BIND(STKGC(idx))->tag, STK(S->sp-2))) { STK(S->sp++) = SLY_DYN_BIND(STKGC(idx))->value; break; } } return 1; }
/* * search for a dynamic binding with the given tag * on the stack, sets the associated value * of the binding with the given argument, and * returns true if successful, false otherwise * the tag and the value must have been pushed * on the stack */ static int dynamic_store(sly_state_t* S) { int idx; for(idx = S->sp - 3; idx >= 0; idx--) { if(STK(idx).type == SLY_TYPE_DYN_BIND && SLY_OBJ_EQ(SLY_DYN_BIND(STKGC(idx))->tag, STK(S->sp-2))) { SLY_DYN_BIND(STKGC(idx))->value = STK(S->sp-1); break; } } STK(S->sp).type = SLY_TYPE_BOOL; if(idx < 0) { STK(S->sp++).value.bool = 0; } else {
void *su_todata(su_state *s, const su_data_class_t **vt, int idx) { value_t *v = STK(TOP(idx)); if (v->type == SU_NATIVEDATA) { if (vt) *vt = v->obj.data->vt; return (void*)v->obj.data->data; } return NULL; }
void su_setglobal(su_state *s, const char *name) { value_t v; unsigned size = strlen(name); v.type = SU_STRING; v.obj.gc_object = string_from_cache(s, name, size); set_global(s, name, hash_value(&v), size, STK(-1)); su_pop(s, 1); }
void su_vector(su_state *s, int num) { int i; value_t vec = vector_create_empty(s); for (i = 0; i < num; i++) vec = vector_push(s, vec.obj.vec, STK(-(num - i))); s->stack_top -= num; push_value(s, &vec); }
void su_cat_seq(su_state *s) { value_t v, f, r; v = *STK(-1); su_seq_reverse(s, -2); r = *STK(-1); while (v.type != SU_NIL) { f = seq_first(s, v.obj.q); r = cell_create(s, &f, &r); v = seq_rest(s, v.obj.q); } s->stack[s->stack_top - 3] = r; s->stack_top -= 2; su_seq_reverse(s, -1); s->stack[s->stack_top - 2] = s->stack[s->stack_top - 1]; s->stack_top--; }
const char *su_tostring(su_state *s, int idx, unsigned *size) { string_t *str; value_t *v = STK(TOP(idx)); if (v->type == SU_STRING) { str = (string_t*)v->obj.gc_object; if (size) *size = str->size; return str->str; } if (size) *size = 0; return NULL; }
int su_unpack_seq(su_state *s, int idx) { int num = 0; value_t tmp; value_t v = *STK(TOP(idx)); while (isseq(s, &v)) { tmp = v.obj.q->vt->first(s, v.obj.q); push_value(s, &tmp); v = v.obj.q->vt->rest(s, v.obj.q); num++; } return num; }
/* This is for testing - to see what libc considers raw mode. */ void mu_raw_termios() { struct termios before; struct termios after; int i; ioctl(0, TIOCGETA, &before); ioctl(0, TIOCGETA, &after); cfmakeraw(&after); for (i = 0; i < 4; i++) STK(-i-1) = ((uint *)&before)[i] ^ ((uint *)&after)[i]; DROP(-4); }
int su_clambda(su_state *s, su_nativefunc f) { value_t v; int id = s->msi->num_c_lambdas; su_assert(s, s->main_state == s, MAIN_STATE_ONLY_MSG); s->msi->c_lambdas = (value_t*)su_allocate(s, s->msi->c_lambdas, sizeof(value_t) * (++s->msi->num_c_lambdas)); if (f) { v.type = SU_NATIVEFUNC; v.obj.nfunc = f; s->msi->c_lambdas[id] = v; } else { s->msi->c_lambdas[id] = *STK(-1); s->stack_top--; } return id; }
void su_call(su_state *s, int narg, int nret) { int pc, tmp, fret; prototype_t *prot; int top = s->stack_top - narg - 1; value_t *f = &s->stack[top]; frame_t *frame = &s->frames[s->frame_top++]; assert(s->frame_top <= MAX_CALLS); frame->ret_addr = 0xffff; frame->func = f->obj.func; frame->stack_top = top; pc = s->pc; prot = s->prot; tmp = s->narg; s->narg = narg; if (f->type == SU_FUNCTION) { if (f->obj.func->narg < 0) { su_vector(s, narg); s->narg = narg = 1; } else { su_assert(s, f->obj.func->narg == narg, "Bad number of argument to function!"); } vm_loop(s, f->obj.func); if (nret == 0) su_pop(s, 1); } else if (f->type == SU_NATIVEFUNC) { fret = f->obj.nfunc(s, narg); if (nret > 0 && fret > 0) { s->stack[top] = *STK(-1); su_pop(s, narg); } else { s->stack_top = top; if (nret > 0) su_pushnil(s); } s->frame_top--; } else { assert(0); } s->narg = tmp; s->prot = prot; s->pc = pc; }
void su_seq(su_state *s, int idx, int reverse) { value_t v; value_t *seq = STK(TOP(idx)); switch (su_type(s, idx)) { case SU_NIL: su_pushnil(s); return; case SU_VECTOR: v = it_create_vector(s, seq->obj.vec, reverse); break; case SU_MAP: v = tree_create_map(s, seq->obj.m); break; case SU_STRING: v = it_create_string(s, seq->obj.str, reverse); break; case SU_SEQ: if (reverse) { su_seq_reverse(s, idx); return; } else { v = *seq; } break; case SU_NUMBER: if (reverse) v = range_create(s, (int)seq->obj.num, 0); else v = range_create(s, 0, (int)seq->obj.num); break; case SU_FUNCTION: case SU_NATIVEFUNC: if (!reverse) { v = lazy_create(s, seq); break; } default: su_error(s, "Can't sequence object of type: %s", type_name((su_object_type_t)seq->type)); } push_value(s, &v); }
void su_list(su_state *s, int num) { value_t seq = cell_create_array(s, STK(-num), num); s->stack_top -= num; push_value(s, &seq); }
void su_vector_set(su_state *s, int idx) { s->stack[s->stack_top - 2] = vector_set(s, STK(TOP(idx))->obj.vec, (int)STK(-2)->obj.num, STK(-1)); su_pop(s, 1); }
void su_map_insert(su_state *s, int idx) { value_t key = *STK(-2); unsigned hash = hash_value(&key); s->stack[s->stack_top - 2] = map_insert(s, STK(TOP(idx))->obj.m, &key, hash, STK(-1)); s->stack_top--; }
void su_vector_index(su_state *s, int idx) { s->stack[s->stack_top - 1] = vector_index(s, STK(TOP(idx))->obj.vec, (int)STK(-1)->obj.num); }
int su_vector_length(su_state *s, int idx) { return vector_length(STK(TOP(idx))->obj.vec); }
void su_vector_cat(su_state *s) { s->stack[s->stack_top - 2] = vector_cat(s, STK(-2)->obj.vec, STK(-1)->obj.vec); s->stack_top--; }
void su_map_remove(su_state *s, int idx) { value_t key = *STK(-1); unsigned hash = hash_value(&key); s->stack[s->stack_top - 1] = map_remove(s, STK(TOP(idx))->obj.m, &key, hash); }
void su_check_type(su_state *s, int idx, su_object_type_t t) { value_t *v = STK(TOP(idx)); su_assert(s, t == SU_SEQ ? isseq(s, v) : v->type == t, "Bad argument: Expected %s, but got %s.", type_name(t), type_name((su_object_type_t)v->type)); }
su_object_type_t su_type(su_state *s, int idx) { return isseq(s, STK(TOP(idx))) ? SU_SEQ : (su_object_type_t)STK(idx)->type; }
void su_rest(su_state *s, int idx) { value_t v = seq_rest(s, STK(TOP(idx))->obj.q); push_value(s, &v); }
void *su_reg_reference(su_state *s, int idx) { value_t key; unsigned hash; su_assert(s, s->main_state == s, MAIN_STATE_ONLY_MSG); key.type = SU_NATIVEPTR; key.obj.ptr = (void*)s->msi->ref_counter; hash = hash_value(&key); s->stack[SU_REGISTRY_INDEX] = map_insert(s, s->stack[SU_REGISTRY_INDEX].obj.m, &key, hash, STK(TOP(idx))); s->msi->ref_counter++; assert(s->msi->ref_counter); return key.obj.ptr; }
void su_cons(su_state *s) { s->stack[s->stack_top - 2] = cell_create(s, STK(-2), STK(-1)); s->stack_top--; }