diff options
author | William Carroll <wpcarro@gmail.com> | 2023-01-20T16·04-0800 |
---|---|---|
committer | clbot <clbot@tvl.fyi> | 2023-01-20T16·09+0000 |
commit | 9df188ad0320fac33c57065eb1d166e8c7713158 (patch) | |
tree | 538e038e1fb3dd6b8342735c6bab132418191e8c /users/wpcarro/slx.js | |
parent | 259faea2b229edd8f2e31d0903b5fd185036b4a4 (diff) |
feat(wpcarro/slx): Support numeric comparisons r/5710
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
Diffstat (limited to 'users/wpcarro/slx.js')
-rw-r--r-- | users/wpcarro/slx.js/index.js | 68 |
1 files changed, 67 insertions, 1 deletions
diff --git a/users/wpcarro/slx.js/index.js b/users/wpcarro/slx.js/index.js index 9f2ed675f7a9..44f2f3643f8c 100644 --- a/users/wpcarro/slx.js/index.js +++ b/users/wpcarro/slx.js/index.js @@ -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); } } |