diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2.dm b/code/modules/admin/verbs/SDQL2/SDQL_2.dm index d2a106f9179..b470d2962a8 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2.dm @@ -61,6 +61,10 @@ "SELECT /mob WHERE client MAP client WHERE holder MAP holder" + You can also generate a new list on the fly using a selector array. @[] will generate a list of objects based off the selector provided. + + "SELECT /mob/living IN (@[/area/crew_quarters/bar MAP contents])[1]" + What if some dumbass admin spawned a bajillion spiders and you need to kill them all? Oh yeah you'd rather not delete all the spiders in maintenace. Only that one room the spiders were spawned in. @@ -879,6 +883,22 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null dummy[result] = assoc result = dummy val += result + + else if(expression[i] == "@\[") + var/list/search_tree = expression[++i] + var/already_searching = (state == SDQL2_STATE_SEARCHING) //In case we nest, don't want to break out of the searching state until we're all done. + + if(!already_searching) + state = SDQL2_STATE_SEARCHING + + val = Search(search_tree) + SDQL2_STAGE_SWITCH_CHECK + + if(!already_searching) + state = SDQL2_STATE_EXECUTING + else + state = SDQL2_STATE_SEARCHING + else val = world.SDQL_var(object, expression, i, object, superuser, src) i = expression.len @@ -968,6 +988,10 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null return null start++ long = start < expression.len + else if(expression[start] == "(" && long) + v = query.SDQL_expression(source, expression[start + 1]) + start++ + long = start < expression.len else if(D != null && (!long || expression[start + 1] == ".") && (expression[start] in D.vars)) if(D.can_vv_get(expression[start]) || superuser) v = D.vars[expression[start]] @@ -1060,7 +1084,8 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null "=" = list("", "="), "<" = list("", "=", ">"), ">" = list("", "="), - "!" = list("", "=")) + "!" = list("", "="), + "@" = list("\[")) var/word = "" var/list/query_list = list() diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2_parser.dm b/code/modules/admin/verbs/SDQL2/SDQL_2_parser.dm index 272bf83ca47..83592d27681 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2_parser.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2_parser.dm @@ -19,24 +19,28 @@ // // from_item : 'world' | expression // -// call_function : '(' [arguments] ')' -// arguments : expression [',' arguments] +// call_function : '(' [expression_list] ')' // // object_type : // // assignments : assignment [',' assignments] // assignment : '=' expression -// variable : | '.' variable | '[' ']' | '[' ']' '.' variable +// variable : | variable '.' variable | variable '[' ']' | '{' '}' | '(' 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 : ''' ''' | '"' '"' // number : // @@ -336,7 +340,7 @@ return i -//variable: | '.' variable | '[' ']' | '[' ']' '.' variable +//variable: | variable '.' variable | variable '[' ']' | '{' '}' | '(' 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: ['(' [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)