[READY] Adds selector lists to SDQL (#43383)

* [SDQL2] Adds selector arrays

* SDQL2 documentation spec updated slightly

* SDQL2 selector array docs + tweaks

If a single list is the only result of a MAP statement,
meaning objs.len == 1, AND it's a list, it will unwrap
the result from its containing list and return it directly.

The selector array logic keeps track of the state of the query
when it starts the first Search. It won't change the state back
to Execute until the top-level is reached, which sets a var
to keep track.

* SDQL2 MAP change from objs.len to length(objs)

* [SDQL2] Reverts MAP list unwrap

* [SDQL] Move (expr) from expr, unary_expr to var

This should result in the same functionality but instead of expressions and unary_expressions processing sub expressions, variables do
This means that expression->value->variable is now completely recursable

* [SDQL2] Update selector list documentation
This commit is contained in:
JJRcop
2019-04-15 09:22:30 +02:00
committed by AnturK
parent a4906f2382
commit 1cf1df847c
2 changed files with 72 additions and 37 deletions
+46 -36
View File
@@ -19,24 +19,28 @@
//
// from_item : 'world' | expression
//
// call_function : <function name> '(' [arguments] ')'
// arguments : expression [',' arguments]
// call_function : <function name> '(' [expression_list] ')'
//
// object_type : <type path>
//
// assignments : assignment [',' assignments]
// assignment : <variable name> '=' expression
// variable : <variable name> | <variable name> '.' variable | '[' <hex number> ']' | '[' <hex number> ']' '.' variable
// variable : <variable name> | variable '.' variable | variable '[' <list index> ']' | '{' <ref as hex number> '}' | '(' expression ')' | call_function
//
// bool_expression : expression comparitor expression [bool_operator bool_expression]
// expression : ( unary_expression | '(' expression ')' | value ) [binary_operator expression]
// unary_expression : unary_operator ( unary_expression | value | '(' expression ')' )
// expression_list : expression [',' expression_list]
// unary_expression : unary_operator ( unary_expression | value )
//
// comparitor : '=' | '==' | '!=' | '<>' | '<' | '<=' | '>' | '>='
// value : variable | string | number | 'null' | object_type
// value : variable | string | number | 'null' | object_type | array | selectors_array
// unary_operator : '!' | '-' | '~'
// binary_operator : comparitor | '+' | '-' | '/' | '*' | '&' | '|' | '^' | '%'
// bool_operator : 'AND' | '&&' | 'OR' | '||'
//
// array : '[' expression_list ']'
// selectors_array : '@[' object_selectors ']'
//
// string : ''' <some text> ''' | '"' <some text > '"'
// number : <some digits>
//
@@ -336,7 +340,7 @@
return i
//variable: <variable name> | <variable name> '.' variable | '[' <hex number> ']' | '[' <hex number> ']' '.' variable
//variable: <variable name> | variable '.' variable | variable '[' <list index> ']' | '{' <ref as hex number> '}' | '(' expression ')' | call_function
/datum/SDQL_parser/proc/variable(i, list/node)
var/list/L = list(token(i))
node[++node.len] = L
@@ -348,6 +352,16 @@
if(token(i) != "}")
parse_error("Missing } at end of pointer.")
else if(token(i) == "(") // not a proc but an expression
var/list/sub_expression = list()
i = expression(i + 1, sub_expression)
if(token(i) != ")")
parse_error("Missing ) at end of expression.")
L[++L.len] = sub_expression
if(token(i + 1) == ".")
L += "."
i = variable(i + 2, L)
@@ -424,7 +438,7 @@
return i + 1
//array: '[' expression, expression, ... ']'
//array: '[' expression_list ']'
/datum/SDQL_parser/proc/array(var/i, var/list/node)
// Arrays get turned into this: list("[", list(exp_1a = exp_1b, ...), ...), "[" is to mark the next node as an array.
if(copytext(token(i), 1, 2) != "\[")
@@ -490,6 +504,23 @@
return i + 1
//selectors_array: '@[' object_selectors ']'
/datum/SDQL_parser/proc/selectors_array(var/i, var/list/node)
if(token(i) == "@\[")
node += token(i++)
if(token(i) != "]")
var/list/select = list()
i = object_selectors(i, select)
node[++node.len] = select
if(token(i) != "]")
parse_error("Expected ']' to close selector array, but found '[token(i)]'")
else
parse_error("Selector array expected a selector, but found nothing")
else
parse_error("Expected '@\[' but found '[token(i)]'")
return i + 1
//call_function: <function name> ['(' [arguments] ')']
/datum/SDQL_parser/proc/call_function(i, list/node, list/arguments)
if(length(tokenl(i)))
@@ -520,25 +551,12 @@
return i + 1
//expression: ( unary_expression | '(' expression ')' | value ) [binary_operator expression]
//expression: ( unary_expression | value ) [binary_operator expression]
/datum/SDQL_parser/proc/expression(i, list/node)
if(token(i) in unary_operators)
i = unary_expression(i, node)
else if(token(i) == "(")
var/list/expr = list()
i = expression(i + 1, expr)
if(token(i) != ")")
parse_error("Missing ) at end of expression.")
else
i++
node[++node.len] = expr
else
i = value(i, node)
@@ -558,7 +576,7 @@
return i
//unary_expression: unary_operator ( unary_expression | value | '(' expression ')' )
//unary_expression: unary_operator ( unary_expression | value )
/datum/SDQL_parser/proc/unary_expression(i, list/node)
if(token(i) in unary_operators)
@@ -570,19 +588,6 @@
if(token(i) in unary_operators)
i = unary_expression(i, unary_exp)
else if(token(i) == "(")
var/list/expr = list()
i = expression(i + 1, expr)
if(token(i) != ")")
parse_error("Missing ) at end of expression.")
else
i++
unary_exp[++unary_exp.len] = expr
else
i = value(i, unary_exp)
@@ -607,7 +612,7 @@
return i + 1
//value: variable | string | number | 'null' | object_type
//value: variable | string | number | 'null' | object_type | array | selectors_array
/datum/SDQL_parser/proc/value(i, list/node)
if(token(i) == "null")
node += "null"
@@ -626,8 +631,13 @@
else if(copytext(token(i), 1, 2) == "\[") // Start a list.
i = array(i, node)
else if(copytext(token(i), 1, 3) == "@\[")
i = selectors_array(i, node)
else if(copytext(token(i), 1, 2) == "/")
i = object_type(i, node)
else
i = variable(i, node)