More ergonomic variadic operations, hopefully
This commit is contained in:
@@ -249,16 +249,21 @@ class Macros {
|
|||||||
var uniqueVarName = "_" + Uuid.v4().toShort();
|
var uniqueVarName = "_" + Uuid.v4().toShort();
|
||||||
var uniqueVarSymbol = Symbol(uniqueVarName).withPosOf(wholeExp);
|
var uniqueVarSymbol = Symbol(uniqueVarName).withPosOf(wholeExp);
|
||||||
uniqueVarExps.push(uniqueVarSymbol);
|
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), [
|
CallExp(Symbol("let").withPosOf(wholeExp), [
|
||||||
ListExp(bindingList).withPosOf(wholeExp),
|
ListExp(bindingList).withPosOf(wholeExp),
|
||||||
CallExp(Symbol("Lambda.fold").withPosOf(wholeExp), [
|
CallExp(Symbol("kiss.Operand.toDynamic").withPosOf(wholeExp), [
|
||||||
ListExp(uniqueVarExps.slice(1)).withPosOf(wholeExp),
|
CallExp(Symbol("Lambda.fold").withPosOf(wholeExp), [
|
||||||
Symbol(func).withPosOf(wholeExp),
|
ListExp(uniqueVarExps.slice(1)).withPosOf(wholeExp),
|
||||||
uniqueVarExps[0]
|
Symbol(func).withPosOf(wholeExp),
|
||||||
]).withPosOf(wholeExp)
|
uniqueVarExps[0]
|
||||||
|
]).withPosOf(wholeExp)
|
||||||
|
]).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));
|
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)) {
|
return switch (Type.typeof(d)) {
|
||||||
case TInt: Right(Left(d));
|
case TInt: Right(Left(d));
|
||||||
case TFloat: Right(Right(d));
|
case TFloat: Right(Right(d));
|
||||||
default:
|
default:
|
||||||
if (Std.isOfType(d, String)) {
|
if (Std.isOfType(d, String)) {
|
||||||
Left(d);
|
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 {
|
} else {
|
||||||
throw '$d cannot be Operand';
|
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> {
|
// This wasn't working as an implicit conversion in conjunction with Lambda.fold()
|
||||||
return switch (this) {
|
|
||||||
case Right(Left(i)): i;
|
/* @:to */
|
||||||
case Right(Right(f)): f;
|
public static function toDynamic(o:Dynamic):Null<Dynamic> {
|
||||||
case Left(str): str;
|
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();
|
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());
|
return Math.pow(base.toFloat(), exponent.toFloat());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ class Prelude {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static function areEqual(a:Operand, b:Operand):Operand {
|
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) {
|
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) -> {
|
return (wholeExp:ReaderExp, args:Array<ReaderExp>, k:KissState) -> {
|
||||||
var callFoldMacroExpr = k.convert(CallExp(Symbol(func).withPosOf(wholeExp), args).withPosOf(wholeExp));
|
var callFoldMacroExpr = k.convert(CallExp(Symbol(func).withPosOf(wholeExp), args).withPosOf(wholeExp));
|
||||||
wholeExp.checkNumArgs(1, null);
|
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