public
Last active

Chained comparisons using sweet.js

  • Download Gist
gistfile1.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
macro $if {
case ($x ...) => { if (relCar($x ...)) }
}
 
macro $while {
case ($x ...) => { while (relCar($x ...)) }
}
 
// naive form:
/*
macro rel {
case $x => { $x }
case ($x:ident $op $y:ident $rest ...) => {
$x $op $y && $rel($y $rest ...)
}
}
*/
 
// better: works even with the presence of &&, |, etc.
macro relGen {
case ($cmp ...) => {
macro relCar {
$(case ($x $cmp $y $rest $[...]) => {
$x $cmp $y relCdr($y $rest $[...])
}) ...
case $x => { $x }
}
 
macro relCdr {
$(case ($y $cmp $z) => {
&& $y $cmp $z
}) ...
/* since the following two sequences are of equal length, order is important */
case ($y:ident $op $z:ident $rest $[...]) => {
$op relCar($z $rest $[...])
}
$(case ($y:ident $cmp $z:ident $rest $[...]) => {
&& $y $cmp $z relCdr($z $rest $[...])
}) ...
case $y => { $y }
}
}
}
 
relGen(>= <= > < != !== === ==)
 
$while (1 > 2 > 3 >= 4 <= 5 > 6) {
console.log("foo");
}
 
$if (1 < 2 < 3 < 4 < 5 < 6) {
console.log("bar");
}
 
$if (1 < 2 && 3 < 4 < 5 || 1 == 2 == 3) {
console.log("bar");
}
 
// result:
/*
while (1 > 2 && 2 > 3 && 3 >= 4 && 4 <= 5 && 5 > 6) {
console.log('foo');
}
if (1 < 2 && 2 < 3 && 3 < 4 && 4 < 5 && 5 < 6) {
console.log('bar');
}
if (1 < 2 && 3 < 4 && 4 < 5 || 1 == 2 && 2 == 3) {
console.log('bar');
}
*/

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.