diff --git a/library/lua/utils.lua b/library/lua/utils.lua index 1b626f051..00e31929f 100644 --- a/library/lua/utils.lua +++ b/library/lua/utils.lua @@ -608,7 +608,7 @@ df_env = df_shortcut_env() function df_expr_to_ref(expr) expr = expr:gsub('%["(.-)"%]', function(field) return '.' .. field end) :gsub('%[\'(.-)\'%]', function(field) return '.' .. field end) - :gsub('%[(%d+)]', function(field) return '.' .. field end) + :gsub('%[(%-?%d+)%]', function(field) return '.' .. field end) local parts = expr:split('.', true) local obj = df_env[parts[1]] for i = 2, #parts do diff --git a/test/library/utils.lua b/test/library/utils.lua index 2434da321..509fab8bc 100644 --- a/test/library/utils.lua +++ b/test/library/utils.lua @@ -89,5 +89,27 @@ function test.df_expr_to_ref() -- primitive field expect.eq(utils.df_expr_to_ref('unit.profession'), fake_unit:_field('profession')) end) + + -- vector items + dfhack.with_temp_object(df.new('ptr-vector'), function(vec) + fake_unit = vec + vec:insert('#', df.global.world) + vec:insert('#', df.global.ui) + + expect.eq(utils.df_expr_to_ref('unit'), vec) + + expect.eq(utils.df_expr_to_ref('unit[0]'), utils.df_expr_to_ref('unit.0')) + expect.eq(df.reinterpret_cast(df.world, utils.df_expr_to_ref('unit[0]').value), df.global.world) + + expect.eq(utils.df_expr_to_ref('unit[1]'), utils.df_expr_to_ref('unit.1')) + expect.eq(df.reinterpret_cast(df.ui, utils.df_expr_to_ref('unit[1]').value), df.global.ui) + + expect.error_match('index out of bounds', function() utils.df_expr_to_ref('unit.2') end) + expect.error_match('index out of bounds', function() utils.df_expr_to_ref('unit[2]') end) + expect.error_match('index out of bounds', function() utils.df_expr_to_ref('unit.-1') end) + expect.error_match('index out of bounds', function() utils.df_expr_to_ref('unit[-1]') end) + + expect.error_match('not found', function() utils.df_expr_to_ref('unit.a') end) + end) end) end