Skip to content

Instantly share code, notes, and snippets.

@hughpearse
Created March 27, 2025 10:33
Show Gist options
  • Save hughpearse/6421dfe4c7c8fb28d99392d2f15fcb3b to your computer and use it in GitHub Desktop.
Save hughpearse/6421dfe4c7c8fb28d99392d2f15fcb3b to your computer and use it in GitHub Desktop.
Shell Expansion: Using Haxe
import haxe.ds.StringMap;
import haxe.ds.List;
import haxe.ds.Vector;
import StringTools;
class BraceExpander {
private var inputString:String;
private var braceExpressions:Array<String>;
public function new(inputString:String) {
this.inputString = inputString;
this.braceExpressions = findBraceExpressions();
}
private function findBraceExpressions():Array<String> {
var expressions:Array<String> = [];
var pattern:EReg = ~/\{([^}]+)\}/;
var pos:Int = 0;
while (pattern.matchSub(inputString, pos)) {
expressions.push(pattern.matched(1));
pos = pattern.matchedPos().pos + pattern.matchedPos().len;
}
return expressions;
}
private function expandBrace(braceContent:String):Array<String> {
var rangeStepPattern:EReg = ~/^(-?\d+)\.\.(-?\d+)\.\.(-?\d+)$/;
if (rangeStepPattern.match(braceContent)) {
var start:Int = Std.parseInt(rangeStepPattern.matched(1));
var end:Int = Std.parseInt(rangeStepPattern.matched(2));
var step:Int = Std.parseInt(rangeStepPattern.matched(3));
var result:Array<String> = [];
var i:Int = start;
while (i <= end) {
result.push(Std.string(i));
i += step;
}
return result;
}
var rangePattern:EReg = ~/^(-?\d+)\.\.(-?\d+)$/;
if (rangePattern.match(braceContent)) {
var start:Int = Std.parseInt(rangePattern.matched(1));
var end:Int = Std.parseInt(rangePattern.matched(2));
var result:Array<String> = [];
var i:Int = start;
while (i <= end) {
result.push(Std.string(i));
i++;
}
return result;
}
var letterRangePattern:EReg = ~/^([a-zA-Z])\.\.([a-zA-Z])$/;
if (letterRangePattern.match(braceContent)) {
var start:Int = letterRangePattern.matched(1).charCodeAt(0);
var end:Int = letterRangePattern.matched(2).charCodeAt(0);
var result:Array<String> = [];
var i:Int = start;
while (i <= end) {
result.push(String.fromCharCode(i));
i++;
}
return result;
}
return braceContent.split(",");
}
public function expand():Array<String> {
var expanded:Array<Array<String>> = [];
for (expr in braceExpressions) {
expanded.push(expandBrace(expr));
}
var result:Array<String> = [];
generateCombinations(expanded, 0, [], result);
return result;
}
private function generateCombinations(expanded:Array<Array<String>>, depth:Int, current:Array<String>, result:Array<String>):Void {
if (depth == expanded.length) {
var temp:String = inputString;
for (i in 0...braceExpressions.length) {
temp = StringTools.replace(temp, "{" + braceExpressions[i] + "}", current[i]);
}
result.push(temp);
return;
}
for (item in expanded[depth]) {
var newCurrent:Array<String> = current.copy();
newCurrent.push(item);
generateCombinations(expanded, depth + 1, newCurrent, result);
}
}
}
import StringTools;
class FilterGenerator {
public function new() {}
public function equalTo(value:String):Array<String> {
var expandedValue:Array<String> = new BraceExpander(value).expand();
var result:Array<String> = [];
for (i in 0...expandedValue.length) {
var equalValue = expandedValue[i];
var traceString = "is " + Std.parseInt(equalValue);
result.push(traceString);
}
return result;
}
public function between(start:String, end:String):Array<String> {
var expandedStart:Array<String> = new BraceExpander(start).expand();
var expandedEnd:Array<String> = new BraceExpander(end).expand();
var result:Array<String> = [];
for (i in 0...expandedStart.length) {
var first = expandedStart[i];
var second = expandedEnd[i % expandedEnd.length];
var traceString = 'between ' + Std.parseInt(first) + ' and ' + Std.parseInt(second);
result.push(traceString);
}
return result;
}
public static function main() {
var generator = new FilterGenerator();
var betweenResult = generator.between("{0,11,21}", "{10,20,30}");
for (item in betweenResult) {
trace(item);
}
var equalToResult = generator.equalTo("{1,2,3}");
for (item in equalToResult) {
trace(item);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment