mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-29 18:30:09 +00:00
refining the query language + docs...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
76d0b50b0d
commit
ec42cf7899
@ -771,42 +771,95 @@ var TagsPrototype = {
|
|||||||
|
|
||||||
// Query API...
|
// Query API...
|
||||||
//
|
//
|
||||||
// The language (JS):
|
//
|
||||||
|
// The language (String):
|
||||||
// <query> ::= <tag>
|
// <query> ::= <tag>
|
||||||
// | <call>
|
// | <call>
|
||||||
// | <list>
|
// | <list>
|
||||||
|
// <query> ::= <query> ..
|
||||||
//
|
//
|
||||||
// <tag> ::= string
|
// <tag> ::= string
|
||||||
//
|
//
|
||||||
// <call> ::= [ <function-name> ]
|
// <call> ::= (<function-name>)
|
||||||
// | [ <function-name>, <query>, .. ]
|
// | (<function-name> <query> .. )
|
||||||
//
|
//
|
||||||
// <list> ::= []
|
// <list> ::= ()
|
||||||
// | [ <query>, .. ]
|
// | (<query> .. )
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Values resolution:
|
//
|
||||||
|
//
|
||||||
|
// Execution model:
|
||||||
|
// Pre-processor stage
|
||||||
|
// Executes before the main stage and produces code to be run
|
||||||
|
// on the main stage.
|
||||||
|
// Main stage
|
||||||
|
// Executes after the pre-processor and produces a list of values.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// The language supports three types of "functions":
|
||||||
|
// Pre-processor function
|
||||||
|
// this is processed prior to query execution and generates valid
|
||||||
|
// code to be executed on the next stage
|
||||||
|
// Function (normal)
|
||||||
|
// gets a list of resolved arguments and resolves to a list
|
||||||
|
// Special form
|
||||||
|
// gets a list of unresolved arguments (as-is) and resolves to a list
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Value resolution:
|
||||||
// tag -> resolves to list of matching values as returned by .values(tag)
|
// tag -> resolves to list of matching values as returned by .values(tag)
|
||||||
// list -> resolved to list of resolved items
|
// list -> resolved to list of resolved items
|
||||||
// call -> resolves to list of values returned by the called function
|
// call -> resolves to list of values returned by the called function
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
// Quoting:
|
||||||
|
// `a
|
||||||
|
// will resolve to a literal 'a'
|
||||||
|
// NOTE: this is not the same as (values a) because (values ..)
|
||||||
|
// returns a list while quoting will place the value as-is
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Pre-processor function:
|
||||||
|
// (search ..)
|
||||||
|
// resolves to an (or ..) call passed a list of tags matching
|
||||||
|
// the arguments.
|
||||||
|
//
|
||||||
|
// Shorthand:
|
||||||
|
// `a` -> (search a)
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
// Functions:
|
// Functions:
|
||||||
// (and ..)
|
// (and ..)
|
||||||
// resolves to the list of values present in each of the arguments
|
// resolves to the list of values present in each of the arguments
|
||||||
|
//
|
||||||
// (or ..)
|
// (or ..)
|
||||||
// resolves to the list of all the values of all the arguments
|
// resolves to the list of all the values of all the arguments
|
||||||
|
//
|
||||||
// (not a ..)
|
// (not a ..)
|
||||||
// resolves to list of values in a not present in any of the
|
// resolves to list of values in a not present in any of the
|
||||||
// other arguments
|
// other arguments
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
//
|
||||||
// Special forms:
|
// Special forms:
|
||||||
// (values ..)
|
// (values ..)
|
||||||
// resolves to the list of values as-is.
|
// resolves to the list of values as-is.
|
||||||
// this makes it possible to pass in a set of values as-is
|
// this makes it possible to pass in a set of values as-is
|
||||||
// without resolving them as tags.
|
// without resolving them as tags.
|
||||||
//
|
//
|
||||||
|
// Shorthand:
|
||||||
|
// (`a `b `c)
|
||||||
|
// -> (values a b c)
|
||||||
|
//
|
||||||
|
// NOTE: the braces in the shorthand, (values ..) always produces
|
||||||
|
// a list while quoting a value is always a single value.
|
||||||
|
//
|
||||||
|
//
|
||||||
//
|
//
|
||||||
// Testing queries:
|
// Testing queries:
|
||||||
// (values ..) adds the ability to test queries independently of
|
// (values ..) adds the ability to test queries independently of
|
||||||
@ -821,7 +874,37 @@ var TagsPrototype = {
|
|||||||
// -> ['b', 'c']
|
// -> ['b', 'c']
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
//
|
||||||
|
// The language AST:
|
||||||
|
// <query> ::= <tag>
|
||||||
|
// | <call>
|
||||||
|
// | <list>
|
||||||
|
// <query> ::= [ <query>, .. ]
|
||||||
|
//
|
||||||
|
// <tag> ::= string
|
||||||
|
//
|
||||||
|
// <call> ::= [ <function-name> ]
|
||||||
|
// | [ <function-name>, <query>, .. ]
|
||||||
|
//
|
||||||
|
// <list> ::= []
|
||||||
|
// | [ <query>, .. ]
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// NOTE: the AST can be used as a query format as-is, this will
|
||||||
|
// avoid the parse stage...
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// XXX do we need quoting???
|
||||||
// XXX not sure about the .flat(1) calls...
|
// XXX not sure about the .flat(1) calls...
|
||||||
|
__query_ns_pre: {
|
||||||
|
search: function(...args){
|
||||||
|
return ['or',
|
||||||
|
...args
|
||||||
|
.map(function(t){
|
||||||
|
return this.search(t) }.bind(this))
|
||||||
|
.flat()
|
||||||
|
.unique() ] },
|
||||||
|
},
|
||||||
__query_ns: {
|
__query_ns: {
|
||||||
and: function(...args){
|
and: function(...args){
|
||||||
// NOTE: we are sorting the lists here to start with the
|
// NOTE: we are sorting the lists here to start with the
|
||||||
@ -830,10 +913,16 @@ var TagsPrototype = {
|
|||||||
// up...
|
// up...
|
||||||
args = args
|
args = args
|
||||||
.sort(function(a, b){ return a.length - b.length })
|
.sort(function(a, b){ return a.length - b.length })
|
||||||
|
var t = args.pop()
|
||||||
|
t = t instanceof Array ? t : [t]
|
||||||
return [...args
|
return [...args
|
||||||
.reduce(function(res, l){
|
.reduce(function(res, l){
|
||||||
return res.intersect(l.flat(1)) },
|
//return res.intersect(l.flat(1)) },
|
||||||
new Set(args.pop()))] },
|
return res
|
||||||
|
.intersect(l instanceof Array ?
|
||||||
|
l.flat(1)
|
||||||
|
: [l]) },
|
||||||
|
new Set(t))] },
|
||||||
or: function(...args){
|
or: function(...args){
|
||||||
return [...new Set(args.flat(1))] },
|
return [...new Set(args.flat(1))] },
|
||||||
not: function(...args){
|
not: function(...args){
|
||||||
@ -856,9 +945,26 @@ var TagsPrototype = {
|
|||||||
//
|
//
|
||||||
query: function(query, raw){
|
query: function(query, raw){
|
||||||
var that = this
|
var that = this
|
||||||
|
var pre = this.__query_ns_pre
|
||||||
var ns = this.__query_ns
|
var ns = this.__query_ns
|
||||||
var sns = this.__query_ns_special
|
var sns = this.__query_ns_special
|
||||||
|
|
||||||
|
// Query Language pre-processor...
|
||||||
|
var PreQL = function(args){
|
||||||
|
return (
|
||||||
|
// function -> query args and call...
|
||||||
|
args[0] in pre ?
|
||||||
|
pre[args[0]].call(that, ...PreQL(args.slice(1)))
|
||||||
|
// list of tags -> query each arg...
|
||||||
|
: args
|
||||||
|
.map(function(arg){
|
||||||
|
return arg instanceof Array ?
|
||||||
|
PreQL(arg)
|
||||||
|
// search shorthand...
|
||||||
|
: arg.startsWith('`') && arg.endsWith('`') ?
|
||||||
|
PreQL(['search', arg.slice(1, -1)])
|
||||||
|
: arg }) ) }
|
||||||
|
|
||||||
// Query Language Executor...
|
// Query Language Executor...
|
||||||
var QL = function(args){
|
var QL = function(args){
|
||||||
return (
|
return (
|
||||||
@ -873,11 +979,15 @@ var TagsPrototype = {
|
|||||||
.map(function(arg){
|
.map(function(arg){
|
||||||
return arg instanceof Array ?
|
return arg instanceof Array ?
|
||||||
QL(arg)
|
QL(arg)
|
||||||
|
// quoting...
|
||||||
|
// XXX this should be a lexer directive (???)
|
||||||
|
: arg.startsWith('`') ?
|
||||||
|
arg.slice(1)
|
||||||
: that.values(arg) }) ) }
|
: that.values(arg) }) ) }
|
||||||
|
|
||||||
return QL(query instanceof Array ?
|
return QL(PreQL(query instanceof Array ?
|
||||||
query
|
query
|
||||||
: this.parseQuery(query) )
|
: this.parseQuery(query) ))
|
||||||
.run(function(){
|
.run(function(){
|
||||||
return raw ?
|
return raw ?
|
||||||
this
|
this
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user