Example #1
0
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;
}
Example #2
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;
}
Example #3
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;
}