⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hash.c

📁 lua解释器早期1.0版本
💻 C
字号:
/*** hash.c** hash manager for lua** Luiz Henrique de Figueiredo - 17 Aug 90** Modified by Waldemar Celes Filho** 12 May 93*/#include <string.h>#include <stdlib.h>#include "opcode.h"#include "hash.h"#include "inout.h"#include "table.h"#include "lua.h"#define streq(s1,s2)	(strcmp(s1,s2)==0)#define strneq(s1,s2)	(strcmp(s1,s2)!=0)#define new(s)		((s *)malloc(sizeof(s)))#define newvector(n,s)	((s *)calloc(n,sizeof(s)))#define nhash(t)	((t)->nhash)#define nodelist(t)	((t)->list)#define list(t,i)	((t)->list[i])#define ref_tag(n)	(tag(&(n)->ref))#define ref_nvalue(n)	(nvalue(&(n)->ref))#define ref_svalue(n)	(svalue(&(n)->ref))static int head (Hash *t, Object *ref)		/* hash function */{ if (tag(ref) == T_NUMBER) return (((int)nvalue(ref))%nhash(t)); else if (tag(ref) == T_STRING) {  int h;  char *name = svalue(ref);  for (h=0; *name!=0; name++)		/* interpret name as binary number */  {   h <<= 8;   h  += (unsigned char) *name;		/* avoid sign extension */   h  %= nhash(t);			/* make it a valid index */  }  return h; } else {  lua_reportbug ("unexpected type to index table");  return -1; }}static Node *present(Hash *t, Object *ref, int h){ Node *n=NULL, *p; if (tag(ref) == T_NUMBER) {  for (p=NULL,n=list(t,h); n!=NULL; p=n, n=n->next)   if (ref_tag(n) == T_NUMBER && nvalue(ref) == ref_nvalue(n)) break; }   else if (tag(ref) == T_STRING) {  for (p=NULL,n=list(t,h); n!=NULL; p=n, n=n->next)   if (ref_tag(n) == T_STRING && streq(svalue(ref),ref_svalue(n))) break; }   if (n==NULL)				/* name not present */  return NULL;#if 0 if (p!=NULL)				/* name present but not first */ {  p->next=n->next;			/* move-to-front self-organization */  n->next=list(t,h);  list(t,h)=n; }#endif return n;}static void freelist (Node *n){ while (n) {  Node *next = n->next;  free (n);  n = next; }}/*** Create a new hash. Return the hash pointer or NULL on error.*/Hash *lua_hashcreate (unsigned int nhash){ Hash *t = new (Hash); if (t == NULL) {  lua_error ("not enough memory");  return NULL; } nhash(t) = nhash; markarray(t) = 0; nodelist(t) = newvector (nhash, Node*); if (nodelist(t) == NULL) {  lua_error ("not enough memory");  return NULL; } return t;}/*** Delete a hash*/void lua_hashdelete (Hash *h){ int i; for (i=0; i<nhash(h); i++)  freelist (list(h,i)); free (nodelist(h)); free(h);}/*** If the hash node is present, return its pointer, otherwise create a new** node for the given reference and also return its pointer.** On error, return NULL.*/Object *lua_hashdefine (Hash *t, Object *ref){ int   h; Node *n; h = head (t, ref); if (h < 0) return NULL;   n = present(t, ref, h); if (n == NULL) {  n = new(Node);  if (n == NULL)  {   lua_error ("not enough memory");   return NULL;  }  n->ref = *ref;  tag(&n->val) = T_NIL;  n->next = list(t,h);			/* link node to head of list */  list(t,h) = n; } return (&n->val);}/*** Mark a hash and check its elements */void lua_hashmark (Hash *h){ int i;  markarray(h) = 1;  for (i=0; i<nhash(h); i++) {  Node *n;  for (n = list(h,i); n != NULL; n = n->next)  {   lua_markobject (&n->ref);   lua_markobject (&n->val);  } }}/*** Internal function to manipulate arrays. ** Given an array object and a reference value, return the next element** in the hash.** This function pushs the element value and its reference to the stack.*/#include "lua.h"static void firstnode (Hash *a, int h){ if (h < nhash(a)) {    int i;  for (i=h; i<nhash(a); i++)  {   if (list(a,i) != NULL && tag(&list(a,i)->val) != T_NIL)   {    lua_pushobject (&list(a,i)->ref);    lua_pushobject (&list(a,i)->val);    return;   }  } } lua_pushnil(); lua_pushnil();}void lua_next (void){ Hash   *a; Object *o = lua_getparam (1); Object *r = lua_getparam (2); if (o == NULL || r == NULL) { lua_error ("too few arguments to function `next'"); return; } if (lua_getparam (3) != NULL) { lua_error ("too many arguments to function `next'"); return; } if (tag(o) != T_ARRAY) { lua_error ("first argument of function `next' is not a table"); return; } a = avalue(o); if (tag(r) == T_NIL) {  firstnode (a, 0);  return; } else {  int h = head (a, r);  if (h >= 0)  {   Node *n = list(a,h);   while (n)   {    if (memcmp(&n->ref,r,sizeof(Object)) == 0)    {     if (n->next == NULL)     {      firstnode (a, h+1);      return;     }     else if (tag(&n->next->val) != T_NIL)     {      lua_pushobject (&n->next->ref);      lua_pushobject (&n->next->val);      return;     }     else     {      Node *next = n->next->next;      while (next != NULL && tag(&next->val) == T_NIL) next = next->next;      if (next == NULL)      {       firstnode (a, h+1);       return;      }      else      {       lua_pushobject (&next->ref);       lua_pushobject (&next->val);      }      return;     }    }    n = n->next;   }   if (n == NULL)    lua_error ("error in function 'next': reference not found");  } }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -