示例#1
0
static Value* eval_abs(const Context* ctx, const ArgList* arglist, bool internal) {
	if(arglist->count != 1) {
		return ValErr(builtinArgs("abs", 1, arglist->count));
	}
	
	Value* val = Value_coerce(arglist->args[0], ctx);
	if(val->type == VAL_ERR) {
		return val;
	}
	
	Value* ret;
	switch(val->type) {
		case VAL_INT:
			ret = ValInt(ABS(val->ival));
			break;
		
		case VAL_REAL:
			ret = ValReal(ABS(val->rval));
			break;
		
		case VAL_FRAC:
			ret = ValFrac(Fraction_new(ABS(val->frac->n), val->frac->d));
			break;
			
		case VAL_VEC:
			ret = Vector_magnitude(val->vec, ctx);
			break;
		
		default:
			badValType(val->type);
	}
	
	Value_free(val);
	return ret;
}
示例#2
0
static Value* parseNum(const char** expr) {
	Value* ret;
	char* end1;
	char* end2;
	
	errno = 0;
	double dbl = strtod(*expr, &end1);
	if(errno != 0 || *expr == end1) {
		/* An error occurred (EINVAL, ERANGE) */
		end1 = NULL;
	}
	
	long long ll = strtoll(*expr, &end2, 10);
	if(errno != 0 || *expr == end2) {
		/* An error occurred (EINVAL, ERANGE) */
		end2 = NULL;
	}
	
	if(end1 > end2) {
		/* Must be a double because more of the string was parsed as double than long long */
		ret = ValReal(dbl);
		*expr = end1;
	}
	else if(end2 != NULL) {
		/* Must be an integer */
		ret = ValInt(ll);
		*expr = end2;
	}
	else {
		/* Both failed to convert the data */
		ret = ValErr(badChar(**expr));
	}
	
	return ret;
}
示例#3
0
/* Arithmetic */
SCValue* Fraction_add(SCFraction* self, SCValue* other) {
    SCValue* ret;
    switch (other->type) {
        case kValueFraction:
        {
            SCNumber numerator = self->numerator * other->fraction->denominator + self->denominator * other->fraction->numerator;
            SCNumber denominator = self->denominator * other->fraction->denominator;
            ret = ValFrac(Fraction_new(numerator, denominator));
            break;
        }
        case kValueInteger:
        {
            SCNumber numerator = self->numerator + other->integer * self->denominator;
            SCNumber denominator = self->denominator;
            ret = ValFrac(Fraction_new(numerator, denominator));
            break;
        }
        case kValueReal:
        {
            ret = ValReal(Fraction_asReal(self) + other->real);
            break;
        }
        default:
            return ValErr(nonArithType(other->type));
            break;
    }
    return ret;
}
示例#4
0
Value* Value_copy(const Value* val) {
	Value* ret;
	
	switch(val->type) {
		case VAL_INT:
			ret = ValInt(val->ival);
			break;
		
		case VAL_REAL:
			ret = ValReal(val->rval);
			break;
		
		case VAL_FRAC:
			ret = ValFrac(Fraction_copy(val->frac));
			break;
		
		case VAL_EXPR:
			ret = ValExpr(BinOp_copy(val->expr));
			break;
		
		case VAL_CALL:
			ret = ValCall(FuncCall_copy(val->call));
			break;
		
		case VAL_UNARY:
			ret = ValUnary(UnOp_copy(val->term));
			break;
		
		case VAL_VAR:
			ret = ValVar(val->name);
			break;
		
		case VAL_VEC:
			ret = ValVec(Vector_copy(val->vec));
			break;
		
		case VAL_NEG:
			/* Shouldn't be reached, but so easy to code */
			ret = ValNeg();
			break;
		
		case VAL_ERR:
			ret = ValErr(Error_copy(val->err));
			break;
		
		default:
			typeError("Unknown value type: %d.", val->type);
			ret = NULL;
			break;
	}
	
	return ret;
}