diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2019-11-20 14:47:00 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2019-11-20 14:47:00 +0800 |
commit | a7c23a257127d583e3754e23544d1ed97dda0a12 (patch) | |
tree | 6b622603c645e5cdf118527b6ef58ac0a55a5dcb /server-beta/src | |
parent | 974323b5885b85818c09afeda73e1832a3779d6b (diff) | |
download | lua-language-server-a7c23a257127d583e3754e23544d1ed97dda0a12.zip |
更新 getValue
Diffstat (limited to 'server-beta/src')
-rw-r--r-- | server-beta/src/vm/getValue.lua | 262 |
1 files changed, 230 insertions, 32 deletions
diff --git a/server-beta/src/vm/getValue.lua b/server-beta/src/vm/getValue.lua index b13d822d..d5db880b 100644 --- a/server-beta/src/vm/getValue.lua +++ b/server-beta/src/vm/getValue.lua @@ -187,37 +187,235 @@ local function checkBinary(source) source = source, } elseif op.type == '<=' then - elseif op.type == '>=' - or op.type == '<' - or op.type == '>' then - return 'boolean' - end - if op.type == '|' - or op.type == '~' - or op.type == '&' - or op.type == '<<' - or op.type == '>>' then - return 'integer' - end - if op.type == '..' then - return 'string' - end - if op.type == '^' - or op.type == '/' then - return 'number' - end + local v1 = vm.getLiteral(source[1], 'integer') or vm.getLiteral(source[1], 'number') + local v2 = vm.getLiteral(source[2], 'integer') or vm.getLiteral(source[2], 'number') + local v + if v1 and v2 then + v = v1 <= v2 + end + return { + type = 'boolean', + value = v, + source = source, + } + elseif op.type == '>=' then + local v1 = vm.getLiteral(source[1], 'integer') or vm.getLiteral(source[1], 'number') + local v2 = vm.getLiteral(source[2], 'integer') or vm.getLiteral(source[2], 'number') + local v + if v1 and v2 then + v = v1 >= v2 + end + return { + type = 'boolean', + value = v, + source = source, + } + elseif op.type == '<' then + local v1 = vm.getLiteral(source[1], 'integer') or vm.getLiteral(source[1], 'number') + local v2 = vm.getLiteral(source[2], 'integer') or vm.getLiteral(source[2], 'number') + local v + if v1 and v2 then + v = v1 < v2 + end + return { + type = 'boolean', + value = v, + source = source, + } + elseif op.type == '>' then + local v1 = vm.getLiteral(source[1], 'integer') or vm.getLiteral(source[1], 'number') + local v2 = vm.getLiteral(source[2], 'integer') or vm.getLiteral(source[2], 'number') + local v + if v1 and v2 then + v = v1 > v2 + end + return { + type = 'boolean', + value = v, + source = source, + } + elseif op.type == '|' then + local v1 = vm.getLiteral(source[1], 'integer') + local v2 = vm.getLiteral(source[2], 'integer') + local v + if v1 and v2 then + v = v1 | v2 + end + return { + type = 'integer', + value = v, + source = source, + } + elseif op.type == '~' then + local v1 = vm.getLiteral(source[1], 'integer') + local v2 = vm.getLiteral(source[2], 'integer') + local v + if v1 and v2 then + v = v1 ~ v2 + end + return { + type = 'integer', + value = v, + source = source, + } + elseif op.type == '&' then + local v1 = vm.getLiteral(source[1], 'integer') + local v2 = vm.getLiteral(source[2], 'integer') + local v + if v1 and v2 then + v = v1 & v2 + end + return { + type = 'integer', + value = v, + source = source, + } + elseif op.type == '<<' then + local v1 = vm.getLiteral(source[1], 'integer') + local v2 = vm.getLiteral(source[2], 'integer') + local v + if v1 and v2 then + v = v1 << v2 + end + return { + type = 'integer', + value = v, + source = source, + } + elseif op.type == '>>' then + local v1 = vm.getLiteral(source[1], 'integer') + local v2 = vm.getLiteral(source[2], 'integer') + local v + if v1 and v2 then + v = v1 >> v2 + end + return { + type = 'integer', + value = v, + source = source, + } + elseif op.type == '..' then + local v1 = vm.getLiteral(source[1], 'string') + local v2 = vm.getLiteral(source[2], 'string') + local v + if v1 and v2 then + v = v1 .. v2 + end + return { + type = 'string', + value = v, + source = source, + } + elseif op.type == '^' then + local v1 = vm.getLiteral(source[1], 'integer') or vm.getLiteral(source[1], 'number') + local v2 = vm.getLiteral(source[2], 'integer') or vm.getLiteral(source[2], 'number') + local v + if v1 and v2 then + v = v1 ^ v2 + end + return { + type = 'number', + value = v, + source = source, + } + elseif op.type == '/' then + local v1 = vm.getLiteral(source[1], 'integer') or vm.getLiteral(source[1], 'number') + local v2 = vm.getLiteral(source[2], 'integer') or vm.getLiteral(source[2], 'number') + local v + if v1 and v2 then + v = v1 > v2 + end + return { + type = 'number', + value = v, + source = source, + } -- 其他数学运算根据2侧的值决定,当2侧的值均为整数时返回整数 - if op.type == '+' - or op.type == '-' - or op.type == '*' - or op.type == '%' - or op.type == '//' then - if hasType('integer', vm.getValue(source[1])) - and hasType('integer', vm.getValue(source[2])) then - return 'integer' - else - return 'number' + elseif op.type == '+' then + local v1 = vm.getLiteral(source[1], 'integer') + local v2 = vm.getLiteral(source[2], 'integer') + if v1 and v2 then + return { + type = 'integer', + value = v1 + v2, + source = source, + } + end + v1 = v1 or vm.getLiteral(source[1], 'number') + v2 = v2 or vm.getLiteral(source[1], 'number') + return { + type = 'number', + value = (v1 and v2) and (v1 + v2) or nil, + source = source, + } + elseif op.type == '-' then + local v1 = vm.getLiteral(source[1], 'integer') + local v2 = vm.getLiteral(source[2], 'integer') + if v1 and v2 then + return { + type = 'integer', + value = v1 - v2, + source = source, + } + end + v1 = v1 or vm.getLiteral(source[1], 'number') + v2 = v2 or vm.getLiteral(source[1], 'number') + return { + type = 'number', + value = (v1 and v2) and (v1 - v2) or nil, + source = source, + } + elseif op.type == '*' then + local v1 = vm.getLiteral(source[1], 'integer') + local v2 = vm.getLiteral(source[2], 'integer') + if v1 and v2 then + return { + type = 'integer', + value = v1 * v2, + source = source, + } + end + v1 = v1 or vm.getLiteral(source[1], 'number') + v2 = v2 or vm.getLiteral(source[1], 'number') + return { + type = 'number', + value = (v1 and v2) and (v1 * v2) or nil, + source = source, + } + elseif op.type == '%' then + local v1 = vm.getLiteral(source[1], 'integer') + local v2 = vm.getLiteral(source[2], 'integer') + if v1 and v2 then + return { + type = 'integer', + value = v1 % v2, + source = source, + } end + v1 = v1 or vm.getLiteral(source[1], 'number') + v2 = v2 or vm.getLiteral(source[1], 'number') + return { + type = 'number', + value = (v1 and v2) and (v1 % v2) or nil, + source = source, + } + elseif op.type == '//' then + local v1 = vm.getLiteral(source[1], 'integer') + local v2 = vm.getLiteral(source[2], 'integer') + if v1 and v2 then + return { + type = 'integer', + value = v1 // v2, + source = source, + } + end + v1 = v1 or vm.getLiteral(source[1], 'number') + v2 = v2 or vm.getLiteral(source[1], 'number') + return { + type = 'number', + value = (v1 and v2) and (v1 // v2) or nil, + source = source, + } end end @@ -394,14 +592,14 @@ function vm.isSameValue(a, b) return true end -function vm.typeInference(source) +function vm.getType(source) local values = vm.getValue(source) if not values then return 'any' end local types = {} - for _ = 1, #values do - local tp = values.type + for i = 1, #values do + local tp = values[i].type if not types[tp] then types[tp] = true types[#types+1] = tp |