diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2022-07-06 19:02:23 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2022-07-06 19:02:23 +0800 |
commit | 26e0310a410820650832f8576154c9b7ee183324 (patch) | |
tree | 3979fdaa48bdc223c2af9dd17b3f7a5f4764b8f6 /script/vm/operator.lua | |
parent | 91ab8e7b4c3c17da0a1bcdfb02a38c23cc786910 (diff) | |
download | lua-language-server-26e0310a410820650832f8576154c9b7ee183324.zip |
support unary operator
Diffstat (limited to 'script/vm/operator.lua')
-rw-r--r-- | script/vm/operator.lua | 55 |
1 files changed, 51 insertions, 4 deletions
diff --git a/script/vm/operator.lua b/script/vm/operator.lua index 0ed3ff1d..67d039e4 100644 --- a/script/vm/operator.lua +++ b/script/vm/operator.lua @@ -25,6 +25,47 @@ vm.BINARY_OP = { 'concat', } +---@param operators parser.object[] +---@param op string +---@param value? parser.object +---@param result? vm.node +---@return vm.node? +local function checkOperators(operators, op, value, result) + for _, operator in ipairs(operators) do + if operator.op[1] ~= op + or not operator.extends then + goto CONTINUE + end + if not result then + result = vm.createNode() + end + result:merge(vm.compileNode(operator.extends)) + ::CONTINUE:: + end + return result +end + +---@param op string +---@param exp parser.object +---@param value? parser.object +---@return vm.node? +function vm.runOperator(op, exp, value) + local uri = guide.getUri(exp) + local node = vm.compileNode(exp) + local result + for c in node:eachObject() do + if c.type == 'global' and c.cate == 'type' then + ---@cast c vm.global + for _, set in ipairs(c:getSets(uri)) do + if set.operators and #set.operators > 0 then + result = checkOperators(set.operators, op, value, result) + end + end + end + end + return result +end + vm.unarySwich = util.switch() : case 'not' : call(function (source) @@ -43,17 +84,22 @@ vm.unarySwich = util.switch() end) : case '#' : call(function (source) - vm.setNode(source, vm.declareGlobal('type', 'integer')) + local node = vm.runOperator('len', source[1]) + vm.setNode(source, node or vm.declareGlobal('type', 'integer')) end) : case '-' : call(function (source) local v = vm.getNumber(source[1]) if v == nil then + local uri = guide.getUri(source) local infer = vm.getInfer(source[1]) - if infer:hasType(guide.getUri(source), 'integer') then + if infer:hasType(uri, 'integer') then vm.setNode(source, vm.declareGlobal('type', 'integer')) - else + elseif infer:hasType(uri, 'number') then vm.setNode(source, vm.declareGlobal('type', 'number')) + else + local node = vm.runOperator('unm', source[1]) + vm.setNode(source, node or vm.declareGlobal('type', 'number')) end else vm.setNode(source, { @@ -69,7 +115,8 @@ vm.unarySwich = util.switch() : call(function (source) local v = vm.getInteger(source[1]) if v == nil then - vm.setNode(source, vm.declareGlobal('type', 'integer')) + local node = vm.runOperator('bnot', source[1]) + vm.setNode(source, node or vm.declareGlobal('type', 'integer')) else vm.setNode(source, { type = 'integer', |