而不用
if (a < 3) {
throw new Exception("Value must be less than 3.");
}
算术操作
iScheme 算术操作包含 + - * / % 五个操作,它们仅应用于数值类型(也就是 SNumber )。
从加减法开始:
.BuildIn("+", (args, scope) => {
var numbers = args.Select(obj => obj.Evaluate(scope)).Cast<SNumber>();
return numbers.Sum(n => n);
})
.BuildIn("-", (args, scope) => {
var numbers = args.Select(obj => obj.Evaluate(scope)).Cast<SNumber>().ToArray();
Int64 firstValue = numbers[0];
if (numbers.Length == 1) {
return -firstValue;
}
return firstValue - numbers.Skip(1).Sum(s => s);
})
注意到这里有一段重复逻辑负责转型求值(Cast then Evaluation),考虑到接下来还有不少地方要用这个逻辑,我把这段逻辑抽象成扩展方法:
public static IEnumerable<T> Evaluate<T>(this IEnumerable<SExpression> expressions, SScope scope)
where T : SObject {
return expressions.Evaluate(scope).Cast<T>();
}
public static IEnumerable<SObject> Evaluate(this IEnumerable<SExpression> expressions, SScope scope) {
return expressions.Select(exp => exp.Evaluate(scope));
}
然后加减法就可以如此定义:
.BuildIn("+", (args, scope) => (args.Evaluate<SNumber>(scope).Sum(s => s)))
.BuildIn("-", (args, scope) => {
var numbers = args.Evaluate<SNumber>(scope).ToArray();
Int64 firstValue = numbers[0];
if (numbers.Length == 1) {
return -firstValue;
}
return firstValue - numbers.Skip(1).Sum(s => s);
})
乘法,除法和求模定义如下:
.BuildIn("*", (args, scope) => args.Evaluate<SNumber>(scope).Aggregate((a, b) => a * b))
.BuildIn("/", (args, scope) => {
var numbers = args.Evaluate<SNumber>(scope).ToArray();
Int64 firstValue = numbers[0];
return firstValue / numbers.Skip(1).Aggregate((a, b) => a * b);
})
.BuildIn("%", (args, scope) => {
(args.Length == 2).OrThrows("Parameters count in mod should be 2");
var numbers = args.Evaluate<SNumber>(scope).ToArray();
return numbers[0] % numbers[1];
})
逻辑操作
iScheme 逻辑操作包括 and , or 和 not ,即与,或和非。
需要注意的是 iScheme 逻辑操作是 短路求值(Short-circuit evaluation),也就是说:
(and condA condB) ,如果 condA 为假,那么整个表达式为假,无需对 condB 求值。 (or condA condB) ,如果 condA 为真,那么整个表达式为真,无需对 condB 求值。此外和 + - * / 一样, and 和 or 也可以接收任意数量的参数。










