/*** map * Mapping functional form. Accepts a single function argument. Input to the * form should always be in the form of a list, and the return value will be * the result of applying the argument function to each element in the list. * * map{ f } : < x, y, z > = < f : x, f : y, f : z > */ struct value *map(struct list *args, struct value *in) { struct value *out = NULL; struct function *f = list_get(args, 0); struct list *l = NULL; struct cursor *c; // First ensure valid input if(args->count != 1 || in->type != SEQ_VAL) { value_delete(in); return value_new(); } // Otherwise create an output list by applying f to each element of in out = value_new(); out->type = SEQ_VAL; out->data.seq_val = list_new(); l = in->data.seq_val; for(c = cursor_new_front(l); cursor_valid(c); cursor_next(c)) list_push_back(out->data.seq_val, function_exec(f, value_copy(cursor_get(c)))); value_delete(in); cursor_delete(c); return out; }
/*** if * Conditional form. Accepts exactly three arguments. First feeds its input * to the first argument. If the result is boolean True, it feeds the input to * its second argument, if False then it feeds it to its third argument, * otherwise it just returns Bottom. * * if{ f, g, h } : x = if f : x then g : x else h : x */ struct value *iff(struct list *args, struct value *in) { struct value *test = value_copy(in); struct value *out = NULL; // Checking for correct number of arguments if(args->count != 3) { value_delete(test); value_delete(in); return value_new(); } // Testing input with first argument test = function_exec(list_get(args, 0), test); if(test->type == BOOL_VAL) { if(test->data.bool_val) { value_delete(test); return function_exec(list_get(args, 1), in); } else { value_delete(test); return function_exec(list_get(args, 2), in); } } else { value_delete(in); return value_new(); } }
/* match */ static int strpto_match(PSTATE *ps, Value *args, Value *_this, Value *ret, int asc) { if (asc) die("Execute String.prototype.match as constructor\n"); if (_this->vt != VT_OBJECT || _this->d.obj->ot != OT_STRING) { die("apply String.prototype.match to a non-string object\n"); } unichar *v = _this->d.obj->d.str; Value *seq = value_object_lookup_array(args, 0, NULL); if (!seq || seq->vt != VT_OBJECT || seq->d.obj->ot != OT_REGEXP) { value_make_null(*ret); return 0; } regex_t *reg = seq->d.obj->d.robj; regmatch_t pos[MAX_SUBREGEX]; memset(&pos, 0, MAX_SUBREGEX * sizeof(regmatch_t)); int r; if ((r = regexec(reg, tochars(v), MAX_SUBREGEX, pos, 0)) != 0) { if (r == REG_NOMATCH) { value_make_null(*ret); return 0; } else die("Out of memory\n"); } Object *obj = object_new(); obj->__proto__ = Array_prototype; value_make_object(*ret, obj); object_set_length(ret->d.obj, 0); int i; for (i = 0; i < MAX_SUBREGEX; ++i) { if (pos[i].rm_so <= 0 && pos[i].rm_eo <= 0) break; Value *val = value_new(); value_make_string(*val, unisubstrdup(v, pos[i].rm_so, pos[i].rm_eo - pos[i].rm_so)); value_object_utils_insert_array(ret, i, val, 1, 1, 1); } Value *vind = value_new(); value_make_number(*vind, pos[0].rm_so); value_object_utils_insert(ret, INDEX.unistr, vind, 1, 1, 1); Value *vinput = value_new(); value_make_string(*vinput, unistrdup(v)); value_object_utils_insert(ret, INPUT.unistr, vinput, 1, 1, 1); return 0; }
/* Sets a string attribute. */ SLPError SLPAttrSet_str( SLPAttributes attr_h, const char *tag, const char *val, SLPInsertionPolicy policy ) { struct xx_SLPAttributes *slp_attr = (struct xx_SLPAttributes *)attr_h; value_t *value; /***** Sanity check. *****/ if ( is_valid_tag(tag) == SLP_FALSE ) { return SLP_TAG_BAD; } if ( val == NULL ) { return SLP_PARAMETER_BAD; } /***** Create new value. *****/ value = value_new(); assert(value); value->data.va_str = strdup(val); if (value->data.va_str == NULL) { value_free(value); return SLP_MEMORY_ALLOC_FAILED; } value->escaped_len = find_escaped_size(value->data.va_str, -1); return generic_set_val(slp_attr, tag, value, policy, SLP_STRING); return SLP_OK; }
/* Sets an integer attribute. */ SLPError SLPAttrSet_int( SLPAttributes attr_h, const char *tag, long val, SLPInsertionPolicy policy ) { struct xx_SLPAttributes *slp_attr = (struct xx_SLPAttributes *)attr_h; value_t *value; /***** Sanity check. *****/ if ( is_valid_tag(tag) == SLP_FALSE ) { return SLP_TAG_BAD; } /***** Create new value. *****/ value = value_new(); if (value == NULL) { return SLP_MEMORY_ALLOC_FAILED; } /**** Set ****/ value->data.va_int = val; value->escaped_len = count_digits(value->data.va_int); assert(value->escaped_len > 0); return generic_set_val(slp_attr, tag, value, policy, SLP_INTEGER); }
Slapi_Value * slapi_value_new_string(const char *s) { Slapi_Value *v= value_new(NULL,CSN_TYPE_UNKNOWN,NULL); slapi_value_set_string(v, s); return v; }
static Value * _relation(const Ast *expr) { Value *rval = value_new(); Value *v1 = eval(expr->child); Value *v2 = eval(expr->child->next); Ast *rtable = expr->child->next->next; rf_Set *domains[] = { v1->as_Set, v2->as_Set, }; int table_size = rf_set_get_cardinality(domains[0]) * rf_set_get_cardinality(domains[1]); bool table[table_size]; int i = 0; for(Ast *rtable_row = rtable->child; rtable_row != NULL; rtable_row = rtable_row->next) { for(Ast *rtable_cell = rtable_row->child; rtable_cell != NULL; rtable_cell = rtable_cell->next) { assert(i < table_size); table[i++] = rtable_cell->value[0] == '1'; } assert(i % rf_set_get_cardinality(domains[0]) == 0); } value_set_relation(rval, rf_relation_new(domains[0], domains[1], table)); value_free(v1); value_free(v2); return rval; }
static Value * _set(const Ast *expr) { Value *rval = value_new(); int n = 0; for(Ast *c = expr->child; c != NULL; c = c->next) n++; int eidx = -1; rf_SetElement *elems[n]; for(Ast *c = expr->child; c != NULL; c = c->next) { Value *v; switch(c->class) { case N_STRING: elems[++eidx] = rf_set_element_new_string(c->value); break; case N_SET: v = _set(c); elems[++eidx] = rf_set_element_new_set(v->as_Set); value_free(v); break; } } value_set_set(rval, rf_set_new(n, elems)); return rval; }
/* Set a boolean attribute. */ SLPError SLPAttrSet_bool( SLPAttributes attr_h, const char *tag, SLPBoolean val ) { struct xx_SLPAttributes *slp_attr = (struct xx_SLPAttributes *)attr_h; value_t *value = NULL; /***** Sanity check. *****/ if (val != SLP_TRUE && val != SLP_FALSE) { return SLP_PARAMETER_BAD; } if ( is_valid_tag(tag) == SLP_FALSE ) { return SLP_TAG_BAD; } /***** Set the initial (and only) value. *****/ /**** Create ****/ value = value_new(); assert(value); /*** Set escaped information. ***/ if (val == SLP_TRUE) { value->escaped_len = BOOL_TRUE_STR_LEN; } else { value->escaped_len = BOOL_FALSE_STR_LEN; } value->data.va_bool = val; /**** Set the value and return. ****/ return generic_set_val(slp_attr, tag, value, SLP_REPLACE, SLP_BOOLEAN); }
static void returnstat(const Ast *return_stmt) { Ast *expr = return_stmt->child; callstack_returnvalue = (expr != NULL) ? eval(expr) : value_new(); }
static Value * _float(const Ast *expr) { Value *rval = value_new(); value_set_float(rval, atof(expr->value)); return rval; }
static Value * _string(const Ast *expr) { Value *rval = value_new(); value_set_string(rval, strdup(expr->value)); return rval; }
Slapi_Value * slapi_value_dup(const Slapi_Value *v) { Slapi_Value *newvalue= value_new(&v->bv,CSN_TYPE_UNKNOWN,NULL); newvalue->v_csnset= csnset_dup(v->v_csnset); newvalue->v_flags = v->v_flags; return newvalue; }
static void declaration(const Ast *declaration) { //Ast *type = declaration->child; Ast *id = declaration->child->next; Memory *m = mem_new(id->symbol); m->value = value_new(); memspace_store(current_memspace, m); }
Value *func_utils_make_func_value(SSFunc callback) { Object *o = object_new(); o->ot = OT_FUNCTION; o->d.fobj = func_make_internal(callback); Value *v = value_new(); value_make_object(*v, o); return v; }
static Value * builtin_bool2str(Scope *args, MemorySpace *memspace) { Value *arg[] = { get_value_by_name(args, memspace, "0"), }; Value *rval = value_new(); value_set_string(rval, strdup((arg[0]->as_bool) ? "true" : "false")); return rval; }
static Value * builtin_relation_is_bijective(Scope *args, MemorySpace *memspace) { Value *arg[] = { get_value_by_name(args, memspace, "0"), }; Value *rval = value_new(); value_set_bool(rval, rf_relation_is_bijective(arg[0]->as_Relation)); return rval; }
static Value * builtin_relation_new_complement(Scope *args, MemorySpace *memspace) { Value *arg[] = { get_value_by_name(args, memspace, "0"), }; Value *rval = value_new(); value_set_relation(rval, rf_relation_new_complement(arg[0]->as_Relation)); return rval; }
void proto_number_init(Value *global) { if (!Number_prototype) bug("proto init failed?"); int i; for (i = 0; i < sizeof(numpro_funcs) / sizeof(struct st_numpro_tab); ++i) { Value *n = func_utils_make_func_value(numpro_funcs[i].func); n->d.obj->__proto__ = Function_prototype; value_object_utils_insert(Number_prototype, tounichars(numpro_funcs[i].name), n, 0, 0, 0); } Value *NaN = value_new(); value_make_number(*NaN, ieee_makenan()); Value *Inf = value_new(); value_make_number(*Inf, ieee_makeinf(1)); value_object_utils_insert(global, tounichars("NaN"), NaN, 0, 0, 0); value_object_utils_insert(global, tounichars("Infinity"), Inf, 0, 0, 0); }
static Value * builtin_set_new_powerset(Scope *args, MemorySpace *memspace) { Value *arg[] = { get_value_by_name(args, memspace, "0"), }; Value *rval = value_new(); value_set_set(rval, rf_set_new_powerset(arg[0]->as_Set)); return rval; }
/*** reduce * Reducing functional form. Accepts a single function argument. Expects * input in the form of a list, return value is the result of first applying * the argument function to a pair formed from the first two elements of the * input list, then forming a new pair from that result and the next * right-most element, and so on until the list is exhausted. * * reduce{ f } : < x, y, z > = f : < f : < x, y>, z > */ struct value *reduce(struct list *args, struct value *in) { struct value *out = value_new(); struct value *v = NULL; struct function *f = list_get(args, 0); int i = 0; // Check for valid input if (args->count != 1 || in->type != SEQ_VAL || in->data.seq_val->count < 2) { value_delete(in); return out; } // Setting up initial pair out->type = SEQ_VAL; out->data.seq_val = list_new(); list_push_back(out->data.seq_val, value_copy(list_get(in->data.seq_val, 0))); list_push_back(out->data.seq_val, value_copy(list_get(in->data.seq_val, 1))); // Pairing up elements and feeding them to f for (i = 2; i <= in->data.seq_val->count; i++) { out = function_exec(f, out); if (i < in->data.seq_val->count) { v = value_new(); v->type = SEQ_VAL; v->data.seq_val = list_new(); list_push_back(v->data.seq_val, out); list_push_back(v->data.seq_val, value_copy(list_get(in->data.seq_val, i))); out = v; } } value_delete(in); return out; }
static Value * builtin_set_is_subset(Scope *args, MemorySpace *memspace) { Value *arg[] = { get_value_by_name(args, memspace, "0"), get_value_by_name(args, memspace, "1"), }; Value *rval = value_new(); value_set_bool(rval, rf_set_is_subset(arg[0]->as_Set, arg[1]->as_Set)); return rval; }
static Value * builtin_println(Scope *args, MemorySpace *memspace) { Value *arg[] = { get_value_by_name(args, memspace, "0"), }; Value *rval = value_new(); printf("%s\n", arg[0]->as_String); value_set_void(rval); return rval; }
static Value * builtin_relation_new_intersection(Scope *args, MemorySpace *memspace) { Value *arg[] = { get_value_by_name(args, memspace, "0"), get_value_by_name(args, memspace, "1"), }; Value *rval = value_new(); value_set_relation(rval, rf_relation_new_intersection(arg[0]->as_Relation, arg[1]->as_Relation)); return rval; }
static Value * identifier(const Ast *expr) { Memory *m = memspace_load(current_memspace, expr->symbol); assert(m != NULL); assert(m->value != NULL); Value *rval = value_new(); value_copy(rval, m->value); return rval; }
void func_init_localvar(Value *arguments, Func *who) { if (who->localnames) { int i; for (i = 0; i < who->localnames->count; ++i) { const unichar *argkey = strs_get(who->localnames, i); if (argkey) { ObjKey *strkey = objkey_new(argkey, OM_DONTEMU); value_object_insert(arguments, strkey, value_new()); } } } }
static Value * call(const Ast *expr) { Ast *id = expr->child; Ast *cargs = expr->child->next; MemorySpace *global_memspace = current_memspace; while(global_memspace->parent != NULL) global_memspace = global_memspace->parent; MemorySpace *fn_memspace = memspace_new(global_memspace); Ast *carg = cargs->child; Symbol *farg = id->symbol->args->symbols; for(; carg != NULL && farg != NULL; carg = carg->next, farg = farg->next) { Memory *m = mem_new(farg); m->value = eval(carg); memspace_store(fn_memspace, m); } switch(id->symbol->class) { case S_FUNCTION: { MemorySpace *local_memspace = current_memspace; current_memspace = fn_memspace; exec(id->symbol->code); current_memspace = local_memspace; }; break; case S_BUILTIN: { callstack_returnvalue = id->symbol->fn(id->symbol->args, fn_memspace); }; break; default: assert(false); } memspace_free(fn_memspace); Value *rval; if(callstack_returnvalue != NULL) { rval = callstack_returnvalue; callstack_returnvalue = NULL; } else { rval = value_new(); value_set_void(rval); } return rval; }
static Value * builtin_set2str(Scope *args, MemorySpace *memspace) { Value *arg[] = { get_value_by_name(args, memspace, "0"), }; Value *rval = value_new(); char *buf = rf_set_to_string(arg[0]->as_Set); value_set_string(rval, strdup(buf)); rf_string_free(buf); return rval; }
static Value * builtin_float2str(Scope *args, MemorySpace *memspace) { Value *arg[] = { get_value_by_name(args, memspace, "0"), }; Value *rval = value_new(); char buf[64]; snprintf(buf, 64, "%f", arg[0]->as_float); value_set_string(rval, strdup(buf)); return rval; }
static Value * builtin_r2tex(Scope *args, MemorySpace *memspace) { Value *arg[] = { get_value_by_name(args, memspace, "0"), }; Value *rval = value_new(); char *buf = rf_relation_format_tex(arg[0]->as_Relation); value_set_string(rval, strdup(buf)); rf_string_free(buf); return rval; }