summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--server/src/vm/source.lua1
-rw-r--r--server/src/vm/value.lua10
-rw-r--r--server/src/vm/vm.lua36
-rw-r--r--server/test/type_inference/init.lua5
4 files changed, 31 insertions, 21 deletions
diff --git a/server/src/vm/source.lua b/server/src/vm/source.lua
index a06b8e8a..5dcdac66 100644
--- a/server/src/vm/source.lua
+++ b/server/src/vm/source.lua
@@ -5,6 +5,7 @@ mt._hasInstant = true
function mt:bindLocal(loc, action)
if loc then
self._bindLocal = loc
+ self._bindValue = loc:getValue()
self._action = action
loc:addInfo(action, self)
else
diff --git a/server/src/vm/value.lua b/server/src/vm/value.lua
index 66f15da2..18b92667 100644
--- a/server/src/vm/value.lua
+++ b/server/src/vm/value.lua
@@ -72,11 +72,13 @@ function mt:rawGet(index)
end
function mt:setChild(index, value)
+ self:setType('table', 0.5)
self:rawSet(index, value)
return value
end
function mt:getChild(index, mark)
+ self:setType('table', 0.5)
local value = self:rawGet(index)
if value then
return value
@@ -213,6 +215,7 @@ function mt:setFunction(func)
end
function mt:getFunction()
+ self:setType('function', 0.5)
return self._func
end
@@ -224,13 +227,18 @@ function mt:getLib()
return self._lib
end
-return function (tp, source)
+function mt:getLiteral()
+ return self._literal
+end
+
+return function (tp, source, literal)
if tp == '...' then
error('Value type cant be ...')
end
local self = setmetatable({
source = source or getDefaultSource(),
_type = {},
+ _literal = literal,
}, mt)
if type(tp) == 'table' then
for i = 1, #tp do
diff --git a/server/src/vm/vm.lua b/server/src/vm/vm.lua
index 364dcf18..dbd2d49a 100644
--- a/server/src/vm/vm.lua
+++ b/server/src/vm/vm.lua
@@ -333,8 +333,8 @@ function mt:call(value, values, source)
return func:getReturn()
end
-function mt:createValue(tp, source)
- local value = createValue(tp, source)
+function mt:createValue(tp, source, literal)
+ local value = createValue(tp, source, literal)
local lib = library.object[tp]
if lib then
local child = libraryBuilder.child(lib)
@@ -374,8 +374,8 @@ function mt:setName(name, source, value)
self:instantSource(source)
local loc = self:loadLocal(name)
if loc then
- source:bindLocal(loc, 'set')
loc:setValue(value)
+ source:bindLocal(loc, 'set')
return
end
local global = source:bindValue()
@@ -500,7 +500,7 @@ function mt:isTrue(v)
if v:getType() == 'nil' then
return false
end
- if v:getType() == 'boolean' and not v:getValue() then
+ if v:getType() == 'boolean' and not v:getLiteral() then
return false
end
return true
@@ -530,8 +530,8 @@ function mt:getBinary(exp)
or op == '<'
or op == '>'
then
- v1:setType('number', 0.9)
- v2:setType('number', 0.9)
+ v1:setType('number', 0.5)
+ v2:setType('number', 0.5)
v1:setType('string', 0.1)
v2:setType('string', 0.1)
return self:createValue('boolean')
@@ -545,10 +545,10 @@ function mt:getBinary(exp)
or op == '<<'
or op == '>>'
then
- v1:setType('integer', 0.9)
- v2:setType('integer', 0.9)
- v1:setType('number', 0.9)
- v2:setType('number', 0.9)
+ v1:setType('integer', 0.5)
+ v2:setType('integer', 0.5)
+ v1:setType('number', 0.5)
+ v2:setType('number', 0.5)
v1:setType('string', 0.1)
v2:setType('string', 0.1)
if math.type(v1:getValue()) == 'integer' and math.type(v2:getValue()) == 'integer' then
@@ -566,8 +566,8 @@ function mt:getBinary(exp)
end
return self:createValue('integer')
elseif op == '..' then
- v1:setType('string', 0.9)
- v2:setType('string', 0.9)
+ v1:setType('string', 0.5)
+ v2:setType('string', 0.5)
v1:setType('number', 0.1)
v2:setType('number', 0.1)
if type(v1:getValue()) == 'string' and type(v2:getValue()) == 'string' then
@@ -582,8 +582,8 @@ function mt:getBinary(exp)
or op == '%'
or op == '//'
then
- v1:setType('number', 0.9)
- v2:setType('number', 0.9)
+ v1:setType('number', 0.5)
+ v2:setType('number', 0.5)
if type(v1:getValue()) == 'number' and type(v2:getValue()) == 'number' then
if op == '+' then
return self:createValue('number', exp, v1:getValue() + v2:getValue())
@@ -620,20 +620,20 @@ function mt:getUnary(exp)
if op == 'not' then
return self:createValue('boolean')
elseif op == '#' then
- v1:setType('table', 0.9)
- v1:setType('string', 0.9)
+ v1:setType('table', 0.5)
+ v1:setType('string', 0.5)
if type(v1:getValue()) == 'string' then
return self:createValue('integer', exp, #v1:getValue())
end
return self:createValue('integer')
elseif op == '-' then
- v1:setType('number', 0.9)
+ v1:setType('number', 0.5)
if type(v1:getValue()) == 'number' then
return self:createValue('number', exp, -v1:getValue())
end
return self:createValue('number')
elseif op == '~' then
- v1:setType('integer', 0.9)
+ v1:setType('integer', 0.5)
if math.type(v1:getValue()) == 'integer' then
return self:createValue('integer', exp, ~v1:getValue())
end
diff --git a/server/test/type_inference/init.lua b/server/test/type_inference/init.lua
index ef0ef001..4961b4b0 100644
--- a/server/test/type_inference/init.lua
+++ b/server/test/type_inference/init.lua
@@ -1,5 +1,6 @@
local parser = require 'parser'
local core = require 'core'
+local buildVM = require 'vm'
rawset(_G, 'TEST', true)
@@ -10,11 +11,11 @@ function TEST(res)
local pos = (start + finish) // 2 + 1
local new_script = script:gsub('<[!?]', ' '):gsub('[!?]>', ' ')
local ast = parser:ast(new_script)
- local vm = core.vm(ast)
+ local vm = buildVM(ast)
assert(vm)
local result = core.findSource(vm, pos)
assert(result)
- assert(res == result.value:getType())
+ assert(res == result:bindValue():getType())
end
end