The Squirrel interpreter. See http://www.squirrel-lang.org/

Dependents:   Squirrel

Revision:
0:97a4f8cc534c
diff -r 000000000000 -r 97a4f8cc534c squirrel/sqtable.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/squirrel/sqtable.h	Tue Dec 16 10:20:34 2014 +0000
@@ -0,0 +1,92 @@
+/*	see copyright notice in squirrel.h */
+#ifndef _SQTABLE_H_
+#define _SQTABLE_H_
+/*
+* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.)
+* http://www.lua.org/copyright.html#4
+* http://www.lua.org/source/4.0.1/src_ltable.c.html
+*/
+
+#include "sqstring.h"
+
+
+#define hashptr(p)  ((SQHash)(((SQInteger)p) >> 3))
+
+inline SQHash HashObj(const SQObjectPtr &key)
+{
+	switch(type(key)) {
+		case OT_STRING:		return _string(key)->_hash;
+		case OT_FLOAT:		return (SQHash)((SQInteger)_float(key));
+		case OT_BOOL: case OT_INTEGER:	return (SQHash)((SQInteger)_integer(key));
+		default:			return hashptr(key._unVal.pRefCounted);
+	}
+}
+
+struct SQTable : public SQDelegable 
+{
+private:
+	struct _HashNode
+	{
+		_HashNode() { next = NULL; }
+		SQObjectPtr val;
+		SQObjectPtr key;
+		_HashNode *next;
+	};
+	_HashNode *_firstfree;
+	_HashNode *_nodes;
+	SQInteger _numofnodes;
+	SQInteger _usednodes;
+	
+///////////////////////////
+	void AllocNodes(SQInteger nSize);
+	void Rehash(bool force);
+	SQTable(SQSharedState *ss, SQInteger nInitialSize);
+	void _ClearNodes();
+public:
+	static SQTable* Create(SQSharedState *ss,SQInteger nInitialSize)
+	{
+		SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable));
+		new (newtable) SQTable(ss, nInitialSize);
+		newtable->_delegate = NULL;
+		return newtable;
+	}
+	void Finalize();
+	SQTable *Clone();
+	~SQTable()
+	{
+		SetDelegate(NULL);
+		REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
+		for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode();
+		SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode));
+	}
+#ifndef NO_GARBAGE_COLLECTOR 
+	void Mark(SQCollectable **chain);
+	SQObjectType GetType() {return OT_TABLE;}
+#endif
+	inline _HashNode *_Get(const SQObjectPtr &key,SQHash hash)
+	{
+		_HashNode *n = &_nodes[hash];
+		do{
+			if(_rawval(n->key) == _rawval(key) && type(n->key) == type(key)){
+				return n;
+			}
+		}while((n = n->next));
+		return NULL;
+	}
+	bool Get(const SQObjectPtr &key,SQObjectPtr &val);
+	void Remove(const SQObjectPtr &key);
+	bool Set(const SQObjectPtr &key, const SQObjectPtr &val);
+	//returns true if a new slot has been created false if it was already present
+	bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val);
+	SQInteger Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
+	
+	SQInteger CountUsed(){ return _usednodes;}
+	void Clear();
+	void Release()
+	{
+		sq_delete(this, SQTable);
+	}
+	
+};
+
+#endif //_SQTABLE_H_