Index: /trunk/nv/lua/lua_path.hh
===================================================================
--- /trunk/nv/lua/lua_path.hh	(revision 181)
+++ /trunk/nv/lua/lua_path.hh	(revision 181)
@@ -0,0 +1,106 @@
+// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// http://chaosforge.org/
+//
+// This file is part of NV Libraries.
+// For conditions of distribution and use, see copyright notice in nv.hh
+
+#ifndef NV_LUA_PATH_HH
+#define NV_LUA_PATH_HH
+
+#include <nv/common.hh>
+#include <nv/string.hh>
+#include <cstring>
+
+struct lua_State;
+
+namespace nv
+{
+	namespace lua
+	{
+
+		class path
+		{
+			struct element 
+			{
+				uint32 value;
+				uint32 length;
+				element() : value( 0 ), length( 0 ) {}
+			};
+
+
+		public:
+			path( nv::string p );
+			path( const char* p );
+			path( int i );
+
+			template < typename T1, typename T2 >
+			path( const T1& p1, const T2& p2 )
+			{
+				const size_t l1 = string_length<T1>::get( p1 );
+				const size_t l2 = string_length<T2>::get( p2 );
+				m_path.reserve( l1 + l2 + 1 );
+				push( p1, l1 );
+				push( p2, l2 );
+			}
+
+			template < typename T1, typename T2, typename T3 >
+			path( const T1& p1, const T2& p2, const T3& p3 ) : m_count( 0 )
+			{
+				const size_t l1 = string_length<T1>::get( p1 );
+				const size_t l2 = string_length<T2>::get( p2 );
+				const size_t l3 = string_length<T3>::get( p3 );
+				m_path.reserve( l1 + l2 + l3 + 1 );
+				push( p1, l1 );
+				push( p2, l2 );
+				push( p3, l3 );
+			}
+
+			template < typename T1, typename T2, typename T3, typename T4 >
+			path( const T1& p1, const T2& p2, const T3& p3, const T4& p4 ) : m_count( 0 )
+			{
+				const size_t l1 = string_length<T1>::get( p1 );
+				const size_t l2 = string_length<T2>::get( p2 );
+				const size_t l3 = string_length<T3>::get( p3 );
+				const size_t l4 = string_length<T4>::get( p4 );
+				m_path.reserve( l1 + l2 + l3 + l4 + 1 );
+				push( p1, l1 );
+				push( p2, l2 );
+				push( p3, l3 );
+				push( p4, l4 );
+			}
+
+			template < typename T1, typename T2, typename T3, typename T4, typename T5 >
+			path( const T1& p1, const T2& p2, const T3& p3, const T4& p4, const T5& p5 ) : m_count( 0 )
+			{
+				const size_t l1 = string_length<T1>::get( p1 );
+				const size_t l2 = string_length<T2>::get( p2 );
+				const size_t l3 = string_length<T3>::get( p3 );
+				const size_t l4 = string_length<T4>::get( p4 );
+				const size_t l5 = string_length<T5>::get( p5 );
+				m_path.reserve( l1 + l2 + l3 + l4 + l5 + 1 );
+				push( p1, l1 );
+				push( p2, l2 );
+				push( p3, l3 );
+				push( p4, l4 );
+				push( p4, l5 );
+			}
+
+			std::string to_string() const;
+			bool resolve( lua_State* L, bool global = true ) const;
+		private:
+			void parse();
+			void push( uint32 start, uint32 length );
+			void push( uint32 e );
+			void push( const nv::string& p, uint32 lenght );
+			void push( const char* s, uint32 length );
+		private:
+			element     m_elements[8];
+			sint32      m_count;
+			std::string m_path;
+		};
+
+	} // namespace lua
+
+} // namespace nv
+
+#endif // NV_LUA_PATH_HH
Index: /trunk/nv/lua/lua_state.hh
===================================================================
--- /trunk/nv/lua/lua_state.hh	(revision 180)
+++ /trunk/nv/lua/lua_state.hh	(revision 181)
@@ -12,4 +12,5 @@
 #include <nv/common.hh>
 #include <nv/flags.hh>
+#include <nv/lua/lua_path.hh>
 #include <string>
 
@@ -42,9 +43,6 @@
 		{
 		public:
-			table_guard( state* lstate, const std::string& table, bool global = true );
-			table_guard( state* lstate, const std::string& table, int index, bool global = true );
-			table_guard( state* lstate, const std::string& table, const std::string& index, bool global = true );
-			table_guard( const table_guard& parent, const std::string& index );
-			table_guard( const table_guard& parent, int index );
+			table_guard( state* lstate, const path& p, bool global = true );
+			table_guard( const table_guard& parent, const path& p );
 			bool has_field( const std::string& element );
 			std::string get_string( const std::string& element, const std::string& defval = "" );
Index: /trunk/nv/string.hh
===================================================================
--- /trunk/nv/string.hh	(revision 180)
+++ /trunk/nv/string.hh	(revision 181)
@@ -7,4 +7,5 @@
 
 #include <string>
+#include <cstring>
 #include <sstream>
 #include <fstream>
@@ -119,4 +120,25 @@
 	}
 
+	template< typename T >
+	struct string_length
+	{
+		static const size_t get( T ) { return 0; }
+	};
+	template< size_t S >
+	struct string_length< const char[S] >
+	{
+		static const size_t get( const char* ) { return S-1; }
+	};
+	template<>
+	struct string_length< const char* >
+	{
+		static const size_t get( const char* s ) { return std::strlen( s ); }
+	};
+	template<>
+	struct string_length< std::string >
+	{
+		static const size_t get( const std::string& s ) { return s.length(); }
+	};
+
 
 }
Index: /trunk/src/lua/lua_path.cc
===================================================================
--- /trunk/src/lua/lua_path.cc	(revision 181)
+++ /trunk/src/lua/lua_path.cc	(revision 181)
@@ -0,0 +1,124 @@
+// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// http://chaosforge.org/
+//
+// This file is part of NV Libraries.
+// For conditions of distribution and use, see copyright notice in nv.hh
+
+#include "nv/lua/lua_path.hh"
+
+#include "nv/lua/lua_raw.hh"
+
+using namespace nv;
+
+lua::path::path( nv::string p )
+	: m_count(0), m_path( std::move( p ) )
+{
+	parse();
+}
+
+lua::path::path( const char* p )
+	: m_count(0), m_path( p )
+{
+	parse();
+}
+
+lua::path::path( int i )
+	: m_count(0)
+{
+	push( i );
+}
+
+void lua::path::parse()
+{
+	size_t start = 0;
+	size_t point = m_path.find('.');
+
+	while( point != std::string::npos )
+	{
+		push( start, point-start );
+		start = point+1;
+		point = m_path.find( '.', start );
+	}
+
+	push( start, m_path.length() - start );
+}
+
+void lua::path::push( uint32 e )
+{
+	m_elements[ m_count ].value  = e;
+	m_elements[ m_count ].length = 0;
+	m_count++;
+}
+
+void lua::path::push( uint32 start, uint32 length )
+{
+	m_elements[ m_count ].value  = start;
+	m_elements[ m_count ].length = length;
+	m_count++;
+}
+
+void lua::path::push( const char* p, uint32 length )
+{
+	m_elements[ m_count ].value  = m_path.length();
+	m_elements[ m_count ].length = length;
+	m_path.append( p, length );
+	m_count++;
+}
+
+void lua::path::push( const std::string& s, uint32 length )
+{
+	m_elements[ m_count ].value  = m_path.length();
+	m_elements[ m_count ].length = length;
+	m_path.append( s, 0, length );
+	m_count++;
+}
+
+bool lua::path::resolve( lua_State* L, bool global /*= true */ ) const
+{
+	if (m_count == 0) return false;
+	if (global) lua_pushglobaltable( L );
+	for (int i = 0; i < m_count; ++i )
+	{
+		if ( lua_istable( L, -1 ) )
+		{
+			if ( m_elements[i].length > 0 )
+			{
+				lua_pushlstring( L, m_path.c_str() + m_elements[i].value, m_elements[i].length );
+			}
+			else
+			{
+				lua_pushinteger( L, m_elements[i].value );
+			}
+			lua_gettable( L, -2 );
+			if (i > 0 || global ) lua_replace( L, -2 );
+		}
+		else
+		{
+			lua_pop(L, 1);
+			return false;
+		}
+	}
+	return true;
+}
+
+std::string nv::lua::path::to_string() const
+{
+	std::string result;
+	result.reserve( 2 * m_path.length() );
+	bool dot = false;
+	for ( const element& e : m_elements )
+	{
+		if ( dot ) result.append(".");
+		if ( e.length == 0 )
+		{
+			result.append("[" + nv::to_string( e.value ) + "]" );
+			dot = false;
+		}
+		else
+		{
+			result.append( m_path, e.value, e.length );
+			dot = true;
+		}
+	}
+	return result;
+}
Index: /trunk/src/lua/lua_state.cc
===================================================================
--- /trunk/src/lua/lua_state.cc	(revision 180)
+++ /trunk/src/lua/lua_state.cc	(revision 181)
@@ -198,35 +198,20 @@
 }
 
-lua::table_guard::table_guard( lua::state* lstate, const std::string& table, bool global )
+lua::table_guard::table_guard( lua::state* lstate, const path& p, bool global )
 	: L(lstate), m_guard(lstate)
 {
-	L->push( table, global );
-}
-
-lua::table_guard::table_guard( lua::state* lstate, const std::string& table, int index, bool global )
-	: L(lstate), m_guard(lstate)
-{
-	L->push( table, global );
-	lua_rawgeti( L->L, -1, index );
-}
-
-lua::table_guard::table_guard( lua::state* lstate, const std::string& table, const std::string& index, bool global /*= true */ )
-	: L(lstate), m_guard(lstate)
-{
-	L->push( table, global );
-	lua_pushstring( L->L, index.c_str() );
-	lua_rawget( L->L, -2 );
-}
-
-lua::table_guard::table_guard( const table_guard& parent, const std::string& index )
+	if ( !p.resolve( L->get_raw(), global ) )
+	{
+		// TODO : error handling
+	}
+}
+
+lua::table_guard::table_guard( const table_guard& parent, const path& p )
 	: L( parent.L ), m_guard( parent.L )
 {
-	lua_getfield( L->L, -1, index.c_str() );
-}
-
-lua::table_guard::table_guard( const table_guard& parent, int index )
-	: L( parent.L ), m_guard( parent.L )
-{
-	lua_rawgeti( L->L, -1, index );
+	if ( !p.resolve( L->get_raw(), false ) )
+	{
+		// TODO : error handling
+	}
 }
 
