11--- @class vm
2- local vm = require ' vm.vm'
3- local util = require ' utility'
4- local guide = require ' parser.guide'
5- local config = require ' config'
2+ local vm = require ' vm.vm'
3+ local util = require ' utility'
4+ local guide = require ' parser.guide'
5+ local config = require ' config'
66
7- vm .UNARY_OP = {
7+ vm .UNARY_OP = {
88 ' unm' ,
99 ' bnot' ,
1010 ' len' ,
1111}
12- vm .BINARY_OP = {
12+ vm .BINARY_OP = {
1313 ' add' ,
1414 ' sub' ,
1515 ' mul' ,
@@ -24,17 +24,17 @@ vm.BINARY_OP = {
2424 ' shr' ,
2525 ' concat' ,
2626}
27- vm .OTHER_OP = {
27+ vm .OTHER_OP = {
2828 ' call' ,
2929}
3030
31- local unaryMap = {
31+ local unaryMap = {
3232 [' -' ] = ' unm' ,
3333 [' ~' ] = ' bnot' ,
3434 [' #' ] = ' len' ,
3535}
3636
37- local binaryMap = {
37+ local binaryMap = {
3838 [' +' ] = ' add' ,
3939 [' -' ] = ' sub' ,
4040 [' *' ] = ' mul' ,
@@ -50,7 +50,7 @@ local binaryMap = {
5050 [' ..' ] = ' concat' ,
5151}
5252
53- local otherMap = {
53+ local otherMap = {
5454 [' ()' ] = ' call' ,
5555}
5656
9696
9797--- @param op string
9898--- @param exp parser.object
99- --- @param value ? parser.object
100- --- @return vm.node ?
101- function vm .runOperator (op , exp , value )
99+ --- @return parser.object[]
100+ function vm .getOperators (op , exp )
102101 local uri = guide .getUri (exp )
103102 local node = vm .compileNode (exp )
104- local result
103+ --- @type parser.object[]
104+ local operators = {}
105105 for c in node :eachObject () do
106106 if c .type == ' string'
107107 or c .type == ' doc.type.string' then
@@ -111,11 +111,27 @@ function vm.runOperator(op, exp, value)
111111 --- @cast c vm.global
112112 for _ , set in ipairs (c :getSets (uri )) do
113113 if set .operators and # set .operators > 0 then
114- result = checkOperators (set .operators , op , value , result )
114+ for _ , operator in ipairs (set .operators ) do
115+ table.insert (operators , operator )
116+ end
115117 end
116118 end
117119 end
118120 end
121+ return operators
122+ end
123+
124+ --- @param op string
125+ --- @param exp parser.object
126+ --- @param value ? parser.object
127+ --- @return vm.node ?
128+ function vm .runOperator (op , exp , value )
129+ local operators = vm .getOperators (op , exp )
130+ --- @type vm.node ?
131+ local result
132+ for _ , operator in ipairs (operators ) do
133+ result = checkOperators (operators , op , value , result )
134+ end
119135 return result
120136end
121137
@@ -247,10 +263,10 @@ vm.binarySwitch = util.switch()
247263 local op = source .op .type
248264 if a and b then
249265 local result = op == ' <<' and a << b
250- or op == ' >>' and a >> b
251- or op == ' &' and a & b
252- or op == ' |' and a | b
253- or op == ' ~' and a ~ b
266+ or op == ' >>' and a >> b
267+ or op == ' &' and a & b
268+ or op == ' |' and a | b
269+ or op == ' ~' and a ~ b
254270 --- @diagnostic disable-next-line : missing-fields
255271 vm .setNode (source , {
256272 type = ' integer' ,
@@ -281,18 +297,18 @@ vm.binarySwitch = util.switch()
281297 local b = vm .getNumber (source [2 ])
282298 local op = source .op .type
283299 local zero = b == 0
284- and ( op == ' %'
285- or op == ' /'
286- or op == ' //'
287- )
300+ and (op == ' %'
301+ or op == ' /'
302+ or op == ' //'
303+ )
288304 if a and b and not zero then
289- local result = op == ' +' and a + b
290- or op == ' -' and a - b
291- or op == ' *' and a * b
292- or op == ' /' and a / b
293- or op == ' %' and a % b
294- or op == ' //' and a // b
295- or op == ' ^' and a ^ b
305+ local result = op == ' +' and a + b
306+ or op == ' -' and a - b
307+ or op == ' *' and a * b
308+ or op == ' /' and a / b
309+ or op == ' %' and a % b
310+ or op == ' //' and a // b
311+ or op == ' ^' and a ^ b
296312 --- @diagnostic disable-next-line : missing-fields
297313 vm .setNode (source , {
298314 type = (op == ' //' or math.type (result ) == ' integer' ) and ' integer' or ' number' ,
@@ -353,10 +369,10 @@ vm.binarySwitch = util.switch()
353369 end )
354370 : case ' ..'
355371 : call (function (source )
356- local a = vm .getString (source [1 ])
357- or vm .getNumber (source [1 ])
358- local b = vm .getString (source [2 ])
359- or vm .getNumber (source [2 ])
372+ local a = vm .getString (source [1 ])
373+ or vm .getNumber (source [1 ])
374+ local b = vm .getString (source [2 ])
375+ or vm .getNumber (source [2 ])
360376 if a and b then
361377 if type (a ) == ' number' or type (b ) == ' number' then
362378 local uri = guide .getUri (source )
@@ -390,13 +406,13 @@ vm.binarySwitch = util.switch()
390406 local infer2 = vm .getInfer (source [2 ])
391407 if (
392408 infer1 :hasType (uri , ' integer' )
393- or infer1 :hasType (uri , ' number' )
394- or infer1 :hasType (uri , ' string' )
409+ or infer1 :hasType (uri , ' number' )
410+ or infer1 :hasType (uri , ' string' )
395411 )
396412 and (
397413 infer2 :hasType (uri , ' integer' )
398- or infer2 :hasType (uri , ' number' )
399- or infer2 :hasType (uri , ' string' )
414+ or infer2 :hasType (uri , ' number' )
415+ or infer2 :hasType (uri , ' string' )
400416 ) then
401417 vm .setNode (source , vm .declareGlobal (' type' , ' string' ))
402418 return
@@ -419,17 +435,17 @@ vm.binarySwitch = util.switch()
419435 local b = vm .getNumber (source [2 ])
420436 if a and b then
421437 local op = source .op .type
422- local result = op == ' >' and a > b
423- or op == ' <' and a < b
424- or op == ' >=' and a >= b
425- or op == ' <=' and a <= b
438+ local result = op == ' >' and a > b
439+ or op == ' <' and a < b
440+ or op == ' >=' and a >= b
441+ or op == ' <=' and a <= b
426442 --- @diagnostic disable-next-line : missing-fields
427443 vm .setNode (source , {
428444 type = ' boolean' ,
429445 start = source .start ,
430446 finish = source .finish ,
431447 parent = source ,
432- [1 ] = result ,
448+ [1 ] = result ,
433449 })
434450 else
435451 vm .setNode (source , vm .declareGlobal (' type' , ' boolean' ))
0 commit comments