Beispiel #1
0
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));
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
Value* Value_coerce(const Value* val, const Context* ctx) {
	Value* ret = Value_eval(val, ctx);
	
	if(ret->type == VAL_VAR) {
		Variable* var = Variable_get(ctx, ret->name);
		
		if(var == NULL) {
			Value* tmp = ValErr(varNotFound(ret->name));
			Value_free(ret);
			ret = tmp;
		}
		else {
			ret = Variable_coerce(var, ctx);
		}
	}
	
	return ret;
}
Beispiel #5
0
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));
}