More ergonomic variadic operations, hopefully
This commit is contained in:
@@ -249,16 +249,21 @@ class Macros {
|
||||
var uniqueVarName = "_" + Uuid.v4().toShort();
|
||||
var uniqueVarSymbol = Symbol(uniqueVarName).withPosOf(wholeExp);
|
||||
uniqueVarExps.push(uniqueVarSymbol);
|
||||
bindingList = bindingList.concat([TypedExp("kiss.Operand", uniqueVarSymbol).withPosOf(wholeExp), exp]);
|
||||
bindingList = bindingList.concat([
|
||||
TypedExp("kiss.Operand", uniqueVarSymbol).withPosOf(wholeExp),
|
||||
CallExp(Symbol("kiss.Operand.fromDynamic").withPosOf(wholeExp), [exp]).withPosOf(wholeExp)
|
||||
]);
|
||||
};
|
||||
|
||||
CallExp(Symbol("let").withPosOf(wholeExp), [
|
||||
ListExp(bindingList).withPosOf(wholeExp),
|
||||
CallExp(Symbol("Lambda.fold").withPosOf(wholeExp), [
|
||||
ListExp(uniqueVarExps.slice(1)).withPosOf(wholeExp),
|
||||
Symbol(func).withPosOf(wholeExp),
|
||||
uniqueVarExps[0]
|
||||
]).withPosOf(wholeExp)
|
||||
CallExp(Symbol("kiss.Operand.toDynamic").withPosOf(wholeExp), [
|
||||
CallExp(Symbol("Lambda.fold").withPosOf(wholeExp), [
|
||||
ListExp(uniqueVarExps.slice(1)).withPosOf(wholeExp),
|
||||
Symbol(func).withPosOf(wholeExp),
|
||||
uniqueVarExps[0]
|
||||
]).withPosOf(wholeExp)
|
||||
]).withPosOf(wholeExp),
|
||||
]).withPosOf(wholeExp);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -18,13 +18,21 @@ abstract Operand(Either<String, Either<Int, Float>>) from Either<String, Either<
|
||||
return Right(Right(f));
|
||||
}
|
||||
|
||||
@:from inline static function fromDynamic(d:Dynamic):Operand {
|
||||
// Doing this one implicitly just wasn't working in conjunction with Lambda.fold
|
||||
|
||||
/* @:from */
|
||||
public inline static function fromDynamic(d:Dynamic):Operand {
|
||||
return switch (Type.typeof(d)) {
|
||||
case TInt: Right(Left(d));
|
||||
case TFloat: Right(Right(d));
|
||||
default:
|
||||
if (Std.isOfType(d, String)) {
|
||||
Left(d);
|
||||
}
|
||||
// Taking a gamble here that no one will ever try to pass a different kind of Either as an operand,
|
||||
// because at runtime this is as specific as the check can get.
|
||||
else if (Std.isOfType(d, Either)) {
|
||||
d;
|
||||
} else {
|
||||
throw '$d cannot be Operand';
|
||||
};
|
||||
@@ -54,11 +62,19 @@ abstract Operand(Either<String, Either<Int, Float>>) from Either<String, Either<
|
||||
};
|
||||
}
|
||||
|
||||
@:to public inline function toDynamic():Null<Dynamic> {
|
||||
return switch (this) {
|
||||
case Right(Left(i)): i;
|
||||
case Right(Right(f)): f;
|
||||
case Left(str): str;
|
||||
}
|
||||
// This wasn't working as an implicit conversion in conjunction with Lambda.fold()
|
||||
|
||||
/* @:to */
|
||||
public static function toDynamic(o:Dynamic):Null<Dynamic> {
|
||||
return if (Std.isOfType(o, Either)) {
|
||||
var o:Operand = cast o;
|
||||
switch (o) {
|
||||
case Right(Left(i)): i;
|
||||
case Right(Right(f)): f;
|
||||
case Left(str): str;
|
||||
};
|
||||
} else {
|
||||
o;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,11 +72,11 @@ class Prelude {
|
||||
};
|
||||
}
|
||||
|
||||
public static function mod(bottom:Operand, top:Operand):Operand {
|
||||
public static function mod(bottom:Operand, top:Operand):Float {
|
||||
return top.toFloat() % bottom.toFloat();
|
||||
}
|
||||
|
||||
public static function pow(exponent:Operand, base:Operand):Operand {
|
||||
public static function pow(exponent:Operand, base:Operand):Float {
|
||||
return Math.pow(base.toFloat(), exponent.toFloat());
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ class Prelude {
|
||||
}
|
||||
|
||||
public static function areEqual(a:Operand, b:Operand):Operand {
|
||||
return if (a.toDynamic() == b.toDynamic()) a else Right(Right(Math.NaN));
|
||||
return if (Operand.toDynamic(a) == Operand.toDynamic(b)) a else Right(Right(Math.NaN));
|
||||
}
|
||||
|
||||
public static function groups<T>(a:Array<T>, size, keepRemainder = false) {
|
||||
|
||||
@@ -287,7 +287,7 @@ class SpecialForms {
|
||||
return (wholeExp:ReaderExp, args:Array<ReaderExp>, k:KissState) -> {
|
||||
var callFoldMacroExpr = k.convert(CallExp(Symbol(func).withPosOf(wholeExp), args).withPosOf(wholeExp));
|
||||
wholeExp.checkNumArgs(1, null);
|
||||
EBinop(OpEq, k.convert(args[0]), macro ${callFoldMacroExpr}.toDynamic()).withMacroPosOf(wholeExp);
|
||||
EBinop(OpEq, k.convert(args[0]), macro kiss.Operand.toDynamic($callFoldMacroExpr)).withMacroPosOf(wholeExp);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user