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
+	}
 }
 
