feat(wpcarro/slx): Support numeric comparisons
I was (and still ~am) a bit leery of supporting this (scope creep?), but I need it in two of my personal projects all within the first O(days) of using this. So I'm thinking that if this tool is going to be a workhorse, I'll need to sacrifice some purity for practicality. Future me will find out the real answer... Change-Id: Ia71a8cf6627062440476b638d2c194c2c9ac97c4 Reviewed-on: https://cl.tvl.fyi/c/depot/+/7878 Autosubmit: wpcarro <wpcarro@gmail.com> Reviewed-by: wpcarro <wpcarro@gmail.com> Tested-by: BuildkiteCI
This commit is contained in:
parent
259faea2b2
commit
9df188ad03
1 changed files with 67 additions and 1 deletions
|
@ -49,6 +49,19 @@ function compile(ast, config) {
|
|||
};
|
||||
}
|
||||
}
|
||||
if (ast.type === 'COMPARE_SELECTION') {
|
||||
const f = compile(ast.val, config);
|
||||
|
||||
let compare = null;
|
||||
if (ast.operator === 'LT') { compare = (x, y) => x < y; }
|
||||
if (ast.operator === 'GT') { compare = (x, y) => x > y; }
|
||||
if (ast.operator === 'LTE') { compare = (x, y) => x <= y; }
|
||||
if (ast.operator === 'GTE') { compare = (x, y) => x >= y; }
|
||||
|
||||
return function(row) {
|
||||
return ast.negate ? !compare(row[ast.key], ast.val) : compare(row[ast.key], ast.val);
|
||||
};
|
||||
}
|
||||
if (ast.type === 'SELECTION') {
|
||||
const f = compile(ast.val, config);
|
||||
return function(row) {
|
||||
|
@ -116,6 +129,17 @@ function tokenize(x) {
|
|||
i += 1;
|
||||
continue;
|
||||
}
|
||||
// Tokenize numbers (i.e. integers, floats).
|
||||
if (/[0-9]/.test(x[i])) {
|
||||
let curr = x[i];
|
||||
i += 1;
|
||||
while (i < x.length && /[0-9]/.test(x[i])) {
|
||||
curr += x[i];
|
||||
i += 1;
|
||||
}
|
||||
result.push(['NUMBER', parseFloat(curr)]);
|
||||
continue;
|
||||
}
|
||||
if (ATOM_REGEX.test(x[i])) {
|
||||
let curr = x[i];
|
||||
i += 1;
|
||||
|
@ -126,6 +150,26 @@ function tokenize(x) {
|
|||
result.push(['ATOM', curr]);
|
||||
continue;
|
||||
}
|
||||
if (x[i] === '<' && i + 1 < x.length && x[i + 1] === '=') {
|
||||
result.push(['COMPARE', 'LTE']);
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
if (x[i] === '<') {
|
||||
result.push(['COMPARE', 'LT']);
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
if (x[i] === '>' && i + i < x.length && x[i + 1] === '=') {
|
||||
result.push(['COMPARE', 'GTE']);
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
if (x[i] === '>') {
|
||||
result.push(['COMPARE', 'GT']);
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
if (x[i] === ':') {
|
||||
result.push(['COLON', null]);
|
||||
i += 1;
|
||||
|
@ -297,7 +341,29 @@ function selection(p, config) {
|
|||
val,
|
||||
};
|
||||
}
|
||||
} else {
|
||||
}
|
||||
// column<value OR -column<value
|
||||
else if ((peekType(0, p) === 'ATOM' && peekType(1, p) === 'COMPARE') ||
|
||||
(peekType(0, p) === 'NEGATE' && peekType(1, p) === 'ATOM' && peekType(2, p) === 'COMPARE')) {
|
||||
let negate = false;
|
||||
if (p.tokens[p.i][0] === 'NEGATE') {
|
||||
negate = true;
|
||||
p.i += 1;
|
||||
}
|
||||
|
||||
const key = match((type, _) => type === 'ATOM', 'a column label', p);
|
||||
const operator = match((type, _) => type === 'COMPARE', 'a comparison operator (i.e. "<", ">", "<=", ">=")', p);
|
||||
const val = match((type, _) => type === 'NUMBER', 'a number', p);
|
||||
|
||||
return {
|
||||
type: 'COMPARE_SELECTION',
|
||||
operator,
|
||||
negate,
|
||||
key,
|
||||
val,
|
||||
};
|
||||
}
|
||||
else {
|
||||
return matchAll(p, config);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue