summaryrefslogtreecommitdiff
path: root/server-beta/src
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2019-11-20 14:47:00 +0800
committer最萌小汐 <sumneko@hotmail.com>2019-11-20 14:47:00 +0800
commita7c23a257127d583e3754e23544d1ed97dda0a12 (patch)
tree6b622603c645e5cdf118527b6ef58ac0a55a5dcb /server-beta/src
parent974323b5885b85818c09afeda73e1832a3779d6b (diff)
downloadlua-language-server-a7c23a257127d583e3754e23544d1ed97dda0a12.zip
更新 getValue
Diffstat (limited to 'server-beta/src')
-rw-r--r--server-beta/src/vm/getValue.lua262
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