Value* Vector_dot(const Vector* vector1, const Vector* vector2, const Context* ctx) { unsigned count = vector1->vals->count; if(count != vector2->vals->count && vector2->vals->count != 1) { /* Both vectors must have the same number of values */ return ValErr(mathError("Vectors must have the same dimensions for dot product.")); } /* Store the total value of the dot product */ Value* accum = ValInt(0); unsigned i; for(i = 0; i < count; i++) { Value* val2; if(vector2->vals->count == 1) { val2 = vector2->vals->args[0]; } else { val2 = vector2->vals->args[i]; } /* accum += v1[i] * val2 */ TP(tp); accum = TP_EVAL(tp, ctx, "@@+@@*@@", accum, Value_copy(vector1->vals->args[i]), Value_copy(val2)); } return accum; }
static Value* vecCompOp(const Vector* vector1, const Vector* vector2, const Context* ctx, BINTYPE bin) { unsigned count = vector1->vals->count; if(count != vector2->vals->count && vector2->vals->count > 1) { return ValErr(mathError("Cannot %s vectors of different sizes.", binop_verb[bin])); } ArgList* newv = ArgList_new(count); unsigned i; for(i = 0; i < count; i++) { /* Perform the specified operation on each matching component */ Value* val2; if(vector2->vals->count == 1) { val2 = vector2->vals->args[0]; } else { val2 = vector2->vals->args[i]; } BinOp* op = BinOp_new(bin, Value_copy(vector1->vals->args[i]), Value_copy(val2)); Value* result = BinOp_eval(op, ctx); BinOp_free(op); /* Error checking */ if(result->type == VAL_ERR) { ArgList_free(newv); return result; } /* Store result */ newv->args[i] = result; } return ValVec(Vector_new(newv)); }
static Value* eval_map(Context* ctx, ArgList* arglist) { if(arglist->count != 2) { return ValErr(builtinArgs("map", 2, arglist->count)); } Value* func = Value_copy(arglist->args[0]); if(func->type != VAL_VAR) { Value* val = Value_eval(func, ctx); Value_free(func); if(val->type == VAL_ERR) return val; if(val->type != VAL_VAR) { Value_free(val); return ValErr(typeError("Builtin 'map' expects a callable as its first argument.")); } func = val; } Value* vec = Value_eval(arglist->args[1], ctx); if(vec->type == VAL_ERR) { Value_free(func); return vec; } if(func->type != VAL_VAR) { Value_free(func); Value_free(vec); return ValErr(typeError("Builtin 'map' expects a callable as its first argument.")); } if(vec->type != VAL_VEC) { Value_free(func); Value_free(vec); return ValErr(typeError("Builtin 'map' expects a vector as its second argument.")); } ArgList* mapping = ArgList_new(vec->vec->vals->count); /* Don't evaluate the call now. Let Builtin_eval do this for us */ unsigned i; for(i = 0; i < mapping->count; i++) { ArgList* arg = ArgList_create(1, Value_copy(vec->vec->vals->args[i])); Value* call = ValCall(FuncCall_new(func->name, arg)); mapping->args[i] = call; } Value_free(func); Value_free(vec); return ValVec(Vector_new(mapping)); }
Value* Value_eval(const Value* val, const Context* ctx) { if(val == NULL) return ValErr(nullError()); Value* ret; Variable* var; switch(val->type) { /* These can be evaluated to a simpler form */ case VAL_EXPR: ret = BinOp_eval(val->expr, ctx); break; case VAL_UNARY: ret = UnOp_eval(val->term, ctx); break; case VAL_CALL: ret = FuncCall_eval(val->call, ctx); break; case VAL_FRAC: ret = Value_copy(val); Fraction_reduce(ret); break; case VAL_VAR: var = Variable_get(ctx, val->name); if(var) { ret = Variable_eval(var, ctx); } else { ret = ValErr(varNotFound(val->name)); } break; case VAL_VEC: ret = Vector_eval(val->vec, ctx); break; /* These can't be simplified, so just copy them */ case VAL_INT: case VAL_REAL: case VAL_NEG: case VAL_ERR: ret = Value_copy(val); break; default: /* Shouldn't be reached */ badValType(val->type); } return ret; }
Value AST_eval(AST_Node root) { if (root == NULL) return NOTHING; Value vl; Value vr; Value result; if ((root->v.type == OP)) { if (root->v.u.op != PAREN) { vl = AST_eval(root->left); vr = AST_eval(root->right); result = Value_combine(vl, root->v.u.op, vr); Value_free(&vl); Value_free(&vr); return result; } else { return AST_eval(root->right); } } else if (root->v.type == RELAT_OP) { vl = AST_eval(root->left); vr = AST_eval(root->right); result = Value_relate(vl, root->v.u.rop, vr); Value_free(&vl); Value_free(&vr); return result; } else { return Value_copy(root->v); } }
bool Streader_read_finite_rt(Streader* sr, Value* dest) { rassert(sr != NULL); if (Streader_is_error_set(sr)) return false; Streader_skip_whitespace(sr); const int64_t start_pos = sr->pos; Value* value = VALUE_AUTO; if (Streader_read_bool(sr, &value->value.bool_type)) value->type = VALUE_TYPE_BOOL; else if ((recover(sr, start_pos), Streader_read_int(sr, &value->value.int_type)) && (CUR_CH != '.') && (CUR_CH != 'e') && (CUR_CH != 'E')) value->type = VALUE_TYPE_INT; else if (recover(sr, start_pos), (Streader_read_float(sr, &value->value.float_type) && isfinite(value->value.float_type))) value->type = VALUE_TYPE_FLOAT; else if (recover(sr, start_pos), Streader_read_tstamp(sr, &value->value.Tstamp_type)) value->type = VALUE_TYPE_TSTAMP; if (value->type == VALUE_TYPE_NONE) return false; if (dest != NULL) Value_copy(dest, value); return true; }
static Value* eval_dot(Context* ctx, ArgList* arglist) { if(arglist->count != 2) { /* Two vectors are required for a dot product */ return ValErr(builtinArgs("dot", 2, arglist->count)); } Value* vector1 = Value_eval(arglist->args[0], ctx); if(vector1->type == VAL_ERR) { return vector1; } Value* vector2 = Value_eval(arglist->args[1], ctx); if(vector2->type == VAL_ERR) { Value_free(vector1); return vector2; } if(vector1->type != VAL_VEC || vector2->type != VAL_VEC) { /* Both values must be vectors */ return ValErr(typeError("Builtin dot expects two vectors.")); } unsigned count = vector1->vec->vals->count; if(count != vector2->vec->vals->count) { /* Both vectors must have the same number of values */ return ValErr(mathError("Vectors must have the same dimensions for dot product.")); } Value* total = ValInt(0); // store the total value of the dot product unsigned i; for(i = 0; i < count; i++) { /* Multiply v1[i] and v2[i] */ BinOp* mul = BinOp_new(BIN_MUL, Value_copy(vector1->vec->vals->args[i]), Value_copy(vector2->vec->vals->args[i])); Value* part = BinOp_eval(mul, ctx); BinOp_free(mul); /* Accumulate the sum for all products */ BinOp* add = BinOp_new(BIN_ADD, part, total); total = BinOp_eval(add, ctx); BinOp_free(add); } return total; }
static Value* eval_exp(const Context* ctx, const ArgList* arglist, bool internal) { if(arglist->count != 1) { return ValErr(builtinArgs("exp", 1, arglist->count)); } TP(tp); return TP_EVAL(tp, ctx, "e^@@", Value_copy(arglist->args[0])); }
static Value* vecMagOp(const Vector* vec, const Value* scalar, const Context* ctx, BINTYPE bin) { /* Calculate old magnitude */ Value* mag = Vector_magnitude(vec, ctx); /* Calculate new magnitude */ BinOp* magOp = BinOp_new(bin, Value_copy(mag), Value_copy(scalar)); Value* newMag = BinOp_eval(magOp, ctx); BinOp_free(magOp); /* Calculate scalar factor */ BinOp* newDivOld = BinOp_new(BIN_DIV, newMag, mag); Value* scalFact = BinOp_eval(newDivOld, ctx); BinOp_free(newDivOld); /* Both newMag and mag are freed with newDivOld */ /* Calculate new vector */ return vecScalarOp(vec, scalFact, ctx, BIN_MUL); }
void Env_var_set_value(Env_var* var, const Value* value) { rassert(var != NULL); rassert(value != NULL); rassert(var->value.type == value->type); Value_copy(&var->value, value); return; }
AST_Node AST_copy(AST_Node root) { if (root == NULL) return NULL; AST_Node n = AST_newv(Value_copy(root->v)); n->left = AST_copy(root->left); n->right = AST_copy(root->right); return n; }
Value* Expression_eval(Expression* expr, Context* ctx) { Value* ret; Variable* var = expr->var; if(var->type == VAR_VALUE) { /* Evaluate right side */ ret = Value_eval(var->val, ctx); /* If an error occurred, bail */ if(ret->type == VAL_ERR) return ret; /* Variable assignment? */ if(ret->type == VAL_VAR) { /* This means ret must be a function */ Variable* func = Variable_get(ctx, ret->name); if(func == NULL) { Value* err = ValErr(varNotFound(ret->name)); Value_free(ret); return err; } if(func->type == VAR_BUILTIN) { Value_free(ret); return ValErr(typeError("Cannot assign a variable to a builtin value.")); } if(var->name != NULL) { Context_setGlobal(ctx, var->name, Variable_copy(func)); } } else { /* This means ret must be a Value */ Value_free(var->val); var->val = Value_copy(ret); /* Update ans */ Context_setGlobal(ctx, "ans", Variable_copy(var)); /* Save the newly evaluated variable */ if(var->name != NULL) Context_setGlobal(ctx, var->name, Variable_copy(var)); } } else if(var->type == VAR_FUNC) { ret = ValVar(var->name); Context_setGlobal(ctx, var->name, Variable_copy(var)); } else { badVarType(var->type); } return ret; }
void Event_cache_update(Event_cache* cache, const char* event_name, const Value* value) { rassert(cache != NULL); rassert(event_name != NULL); rassert(value != NULL); Event_state* state = AAtree_get_exact(cache->cache, event_name); if (state == NULL) return; Value_copy(&state->value, value); return; }
static Value* vecScalarOp(const Vector* vec, const Value* scalar, const Context* ctx, BINTYPE bin) { ArgList* newv = ArgList_new(vec->vals->count); unsigned i; for(i = 0; i < vec->vals->count; i++) { /* Perform operation */ BinOp* op = BinOp_new(bin, Value_copy(vec->vals->args[i]), Value_copy(scalar)); Value* result = BinOp_eval(op, ctx); BinOp_free(op); /* Error checking */ if(result->type == VAL_ERR) { ArgList_free(newv); return result; } /* Store result */ newv->args[i] = result; } return ValVec(Vector_new(newv)); }
void AST_replace_vars(AST_Node root, Env e) { if (root == NULL) return; if (root->v.type == VAR) { Value v = Env_find(e, root->v.u.name); if (v.type != NONE) { Value_free(&(root->v)); root->v = Value_copy(v); } } AST_replace_vars(root->left, e); AST_replace_vars(root->right, e); }
Value* Vector_cross(const Vector* u, const Vector* v, const Context* ctx) { /* Down to one statement from almost 100 lines because of TP_EVAL :) */ /* Now up to two statements because MSVC doesn't support statement expressions :( */ TP(tp); return TP_EVAL(tp, ctx, "<@2@*@6@ - @3@*@5@," " @3@*@4@ - @1@*@6@," " @1@*@5@ - @2@*@4@>", Value_copy(u->vals->args[0]), Value_copy(u->vals->args[1]), Value_copy(u->vals->args[2]), Value_copy(v->vals->args[0]), Value_copy(v->vals->args[1]), Value_copy(v->vals->args[2])); }
Tuple Tuple_copy(Tuple t) { int i; if(t == NULL) { return NULL; } Tuple nt = (Tuple)malloc(sizeof(struct Tuple_t)); nt->size = t->size; if(t->size == 0) { nt->values = NULL; } else { nt->values = (Value*)malloc(sizeof(Value) * t->size); for(i=0; i<t->size; i++) { Tuple_set(nt, i, Value_copy(&(t->values[i]))); } } return nt; }
static Expression* parseExpr(const char** expr) { Variable* var; Value* val = Value_parse(expr, 0, 0); if(val->type == VAL_END) { var = VarErr(ignoreError()); } else if(val->type == VAL_ERR) { Error* err = Error_copy(val->err); var = VarErr(err); } else { var = VarValue(NULL, Value_copy(val)); } Value_free(val); return Expression_new(var); }
bool Channel_cv_state_set_value( Channel_cv_state* state, const char* var_name, const Value* value) { rassert(state != NULL); rassert(var_name != NULL); rassert(strlen(var_name) < KQT_VAR_NAME_MAX); rassert(value != NULL); rassert(Value_type_is_realtime(value->type)); const Entry* key = Entry_init(ENTRY_AUTO, var_name); Entry* entry = AAtree_get_exact(state->tree, key); if (entry == NULL) return false; Value_copy(&entry->value, value); entry->is_set = true; return true; }
Value* Vector_elem(const Vector* vec, const Value* index, const Context* ctx) { if(index->type != VAL_INT) { return ValErr(typeError("Subscript index must be an integer.")); } if(index->ival < 0) { return ValErr(mathError("Subscript index cannot be negative.")); } if(index->ival > UINT_MAX) { return ValErr(mathError("Subscript index %lld is too large.", index->ival)); } unsigned idx = (unsigned)index->ival; if(idx >= vec->vals->count) { return ValErr(mathError("Index %u is out of range: [0-%u]", idx, vec->vals->count - 1)); } return Value_copy(vec->vals->args[index->ival]); }
Env Env_bind(Env e, char *name, Value val) { if (name == NULL) return e; if (e == NULL) return e; Binding tmp; switch (val.type) { case INVALID: case NONE: return e; case NUMBER: case BOOL: case STRING: tmp = Binding_new(name, val); e->bindings = Binding_prepend(tmp, e->bindings); break; case VAR: return Env_bind(e, val.u.name, Value_copy(Env_find(e, val.u.name))); case OP: case RELAT_OP: fprintf(stderr, "Attempted to bind operator\n"); } return e; }
static void icdCopy(void *p_dest, const void *p_source) { Value_copy((Value *) p_dest, (const Value *) p_source); }
UnOp* UnOp_copy(const UnOp* term) { return UnOp_new(term->type, Value_copy(term->a)); }
static Value* eval_cross(Context* ctx, ArgList* arglist) { if(arglist->count != 2) { /* Two vectors are required for a cross product */ return ValErr(builtinArgs("cross", 2, arglist->count)); } Value* vector1 = Value_eval(arglist->args[0], ctx); if(vector1->type == VAL_ERR) { return vector1; } Value* vector2 = Value_eval(arglist->args[1], ctx); if(vector2->type == VAL_ERR) { Value_free(vector1); return vector2; } if(vector1->type != VAL_VEC || vector2->type != VAL_VEC) { /* Both values must be vectors */ return ValErr(typeError("Builtin dot expects two vectors.")); } if(vector1->vec->vals->count != 3) { /* Vectors must each have a size of 3 */ return ValErr(mathError("Vectors must each have a size of 3 for cross product.")); } /* First cross multiplication */ BinOp* i_pos_op = BinOp_new(BIN_MUL, Value_copy(vector1->vec->vals->args[1]), Value_copy(vector2->vec->vals->args[2])); BinOp* i_neg_op = BinOp_new(BIN_MUL, Value_copy(vector1->vec->vals->args[2]), Value_copy(vector2->vec->vals->args[1])); /* Evaluate multiplications */ Value* i_pos = BinOp_eval(i_pos_op, ctx); Value* i_neg = BinOp_eval(i_neg_op, ctx); BinOp_free(i_pos_op); BinOp_free(i_neg_op); /* Error checking */ if(i_pos->type == VAL_ERR) { Value_free(vector1); Value_free(vector2); Value_free(i_neg); return i_pos; } if(i_neg->type == VAL_ERR) { Value_free(vector1); Value_free(vector2); Value_free(i_pos); return i_neg; } /* Subtract products */ BinOp* i_op = BinOp_new(BIN_SUB, i_pos, i_neg); Value* i_val = BinOp_eval(i_op, ctx); BinOp_free(i_op); if(i_val->type == VAL_ERR) { Value_free(vector1); Value_free(vector2); return i_val; } /* Part 2 */ BinOp* j_pos_op = BinOp_new(BIN_MUL, Value_copy(vector1->vec->vals->args[0]), Value_copy(vector2->vec->vals->args[2])); BinOp* j_neg_op = BinOp_new(BIN_MUL, Value_copy(vector1->vec->vals->args[2]), Value_copy(vector2->vec->vals->args[0])); Value* j_pos = BinOp_eval(j_pos_op, ctx); Value* j_neg = BinOp_eval(j_neg_op, ctx); BinOp_free(j_pos_op); BinOp_free(j_neg_op); if(j_pos->type == VAL_ERR) { Value_free(vector1); Value_free(vector2); Value_free(j_neg); return j_pos; } if(j_neg->type == VAL_ERR) { Value_free(vector1); Value_free(vector2); Value_free(j_pos); return j_neg; } BinOp* j_op = BinOp_new(BIN_SUB, j_pos, j_neg); Value* j_val = BinOp_eval(j_op, ctx); BinOp_free(j_op); if(j_val->type == VAL_ERR) { Value_free(vector1); Value_free(vector2); return j_val; } /* Part 3 */ BinOp* k_pos_op = BinOp_new(BIN_MUL, Value_copy(vector1->vec->vals->args[0]), Value_copy(vector2->vec->vals->args[1])); BinOp* k_neg_op = BinOp_new(BIN_MUL, Value_copy(vector1->vec->vals->args[1]), Value_copy(vector2->vec->vals->args[0])); Value* k_pos = BinOp_eval(k_pos_op, ctx); Value* k_neg = BinOp_eval(k_neg_op, ctx); BinOp_free(k_pos_op); BinOp_free(k_neg_op); if(k_pos->type == VAL_ERR) { Value_free(vector1); Value_free(vector2); Value_free(k_neg); return k_pos; } if(k_neg->type == VAL_ERR) { Value_free(vector1); Value_free(vector2); Value_free(k_pos); return k_neg; } BinOp* k_op = BinOp_new(BIN_SUB, k_pos, k_neg); Value* k_val = BinOp_eval(k_op, ctx); BinOp_free(k_op); if(k_val->type == VAL_ERR) { Value_free(vector1); Value_free(vector2); return k_val; } ArgList* args = ArgList_create(3, i_val, j_val, k_val); return ValVec(Vector_new(args)); }