Added ability to define multiple functions (without parameters) and
[zilutils.git] / zilasm / symtable.c
index 2c5735f93cebb003ce8241b4ae898c9bf7575bb8..a5ff791b864307b80df14bb9088b8097d621c6fe 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * symtable.c -- part of ZilUtils/ZilAsm
  *
- * Copyright (C) 2016 Jason Self <j@jxself.org>
+ * Copyright (C) 2016, 2019 Jason Self <j@jxself.org>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License as
@@ -20,6 +20,7 @@
  */
 
 #include <string.h>
+#include "strings.h"
 #include <stdlib.h>
 #include <assert.h>
 
 
 #define FIELD_SIZE(Typ,Field)  (sizeof(((Typ*)0)->Field))
 
-Symtable* symtable_create(unsigned elems_count, unsigned name_size, unsigned elem_size)
+Symtable *
+symtable_create (unsigned elems_count, unsigned name_size, unsigned elem_size)
 {
-       size_t n = elems_count * (name_size + elem_size) + sizeof(Symtable) - FIELD_SIZE(Symtable, contents);
-       Symtable *p = malloc(n);
-       assert(p);
-       bzero(p, n);
-       p->elems_count = elems_count;
-       p->name_size   = name_size;
-       p->elem_size   = elem_size;
-       return p;
+  //size_t n = elems_count * (name_size + elem_size) + sizeof(Symtable) - FIELD_SIZE(Symtable, contents);
+  //Symtable *p = malloc(n);
+
+  Symtable *p = (Symtable *) malloc (sizeof (Symtable));
+  assert (p);
+  size_t n = elems_count * sizeof (SymtableElem);
+  p->contents = (SymtableElem *) malloc (n);
+  bzero (p->contents, n);
+  p->elems_count = elems_count;
+  p->name_size = name_size;
+  p->elem_size = elem_size;
+  return p;
 }
 
-void symtable_destroy(Symtable *p)
+
+void
+symtable_destroy (Symtable * p)
 {
-       assert(p);
-       free(p);
+  assert (p);
+  for (int i = 0; i > p->elems_count; ++i)
+    {
+      free (p->contents[i].name);
+      free (p->contents[i].value);
+    }
+  free (p->contents);
+  free (p);
 }
 
-static unsigned name2pos(const Symtable *p, const char *name, unsigned namelen)
+
+static unsigned
+name2pos (const Symtable * p, const char *name, unsigned namelen)
 {
-       assert(p);
-       unsigned key = 0;
-       while(namelen--)
-               key = ((key << 1) | (*name++));
-       return key % p->elems_count;
+  assert (p);
+  unsigned key = 0;
+  while (namelen--)
+    key = ((key << 1) | (*name++));
+  return key % p->elems_count;
 }
 
-static char *getsym(const Symtable *p, unsigned pos)
+
+static SymtableElem *
+getsym (const Symtable * p, unsigned pos)
 {
-       //assert(p);   //already checked by caller
-       //assert(pos < p->elems_count);
-       return ((char*)p) + sizeof(Symtable) - FIELD_SIZE(Symtable, contents) + (pos * p->elem_size);
+  //assert(p);   //already checked by caller
+  //assert(pos < p->elems_count);
+  //return ((char*)p) + sizeof(Symtable) - FIELD_SIZE(Symtable, contents) + (pos * p->elem_size);
+  return &p->contents[pos];
 }
 
-void* symtable_lookup2(const Symtable *p, const char *name, unsigned namelen)
-{
-       assert(p);
-       assert(name);
-       assert(namelen > 0);
-       assert(namelen < p->name_size);
-
-       unsigned start = name2pos(p, name, namelen);
-       unsigned pos = start;
-
-       do {
-               char *s = getsym(p, pos);
-               if (!*s)
-                       return NULL;
-               if (!memcmp(name, s, namelen))
-                       return s + p->name_size;
-               if (++pos >= p->elems_count)
-                       pos = 0;
-       } while(pos != start);
 
+// searches for a element in the symbols table and returns its value
+void *
+symtable_lookup2 (const Symtable * p, const char *name, unsigned namelen)
+{
+  assert (p);
+  assert (name);
+  assert (namelen > 0);
+  assert (namelen < p->name_size);
+
+  unsigned start = name2pos (p, name, namelen);
+  unsigned pos = start;
+
+  do
+    {
+      SymtableElem *s = getsym (p, pos);
+      if (!s->name)
        return NULL;
+      if (!memcmp (name, s->name, namelen))
+       return s->value;
+      if (++pos >= p->elems_count)
+       pos = 0;
+    }
+  while (pos != start);
+
+  return NULL;
 }
 
-void* symtable_lookup(const Symtable *p, const char *name)
+
+void *
+symtable_lookup (const Symtable * p, const char *name)
 {
-       assert(name);
-       return symtable_lookup2(p, name, strlen(name));
+  assert (name);
+  return symtable_lookup2 (p, name, strlen (name));
 }
 
-void* symtable_add(Symtable *p, const char *name, void *contents)
+
+void *
+symtable_add (Symtable * p, const char *name, void *value)
 {
-       assert(name);
-       return symtable_add2(p, name, strlen(name), contents);
+  assert (name);
+  return symtable_add2 (p, name, strlen (name), value);
 }
 
-void* symtable_add2(Symtable *p, const char *name, unsigned namelen, void *contents)
+
+void *
+symtable_add2 (Symtable * p, const char *name, unsigned namelen, void *value)
 {
-       assert(p);
-       assert(name);
-       assert(namelen > 0 && namelen < p->name_size);
-       assert(contents);
-
-       unsigned start = name2pos(p, name, namelen);
-       unsigned pos = start;
-
-       do {
-               char *s = getsym(p, pos);
-               if (!*s) {
-                       memcpy(s, name, namelen + 1);
-                       s[namelen] = '\0';
-                       memcpy(s + p->name_size, contents, p->elem_size);
-                       return s + p->name_size;
-               }
-               if (!memcmp(name, s, namelen) && s[namelen] == '\0') {
-                       /* TODO!! report error */
-                       return NULL;  /* ..already added */
-               }
-               if (++pos >= p->elems_count)
-                       pos = 0;
-       } while(pos != start);
-
-       /* TODO!! report overflow */
-       return NULL;
-       /* TODO!!! */
+  assert (p);
+  assert (name);
+  assert (namelen > 0 && namelen < p->name_size);
+  assert (value);
+
+  unsigned start = name2pos (p, name, namelen);
+  unsigned pos = start;
+
+  do
+    {
+      SymtableElem *elem = getsym (p, pos);
+      if (!elem->name)
+       {
+         elem->name = (char *) malloc (namelen + 1);
+         memcpy (elem->name, name, namelen + 1);
+         elem->name[namelen] = '\0';
+         elem->value = malloc (p->elem_size);
+         memcpy (elem->value, value, p->elem_size);
+         return elem;
+       }
+      if (!memcmp (name, elem->name, namelen) && elem->name[namelen] == '\0')
+       {
+         /* TODO!! report error */
+         return NULL;          /* ..already added */
+       }
+      if (++pos >= p->elems_count)
+       pos = 0;
+    }
+  while (pos != start);
+
+  /* TODO!! report overflow */
+  return NULL;
+  /* TODO!!! */
 }
 
-static int sortfunc(const void *a, const void *b)
+
+static int
+sortfunc (const void *a, const void *b)
 {
-       const char *s1 = a;
-       const char *s2 = b;
-       if (!*s1 && !*s2) return  0;
-       if (!*s1)         return  1;
-       if (!*s2)         return -1;
-       return strcmp(s1, s2);
+  const char *s1 = (const char *) a;
+  const char *s2 = (const char *) b;
+  if (!*s1 && !*s2)
+    return 0;
+  if (!*s1)
+    return 1;
+  if (!*s2)
+    return -1;
+  return strcmp (s1, s2);
 }
 
-void symtable_sort(Symtable *p)
+
+void
+symtable_sort (Symtable * p)
 {
-       assert(p);
-       qsort(getsym(p, 0), p->elems_count, p->elem_size + p->name_size, sortfunc);
+  assert (p);
+  qsort (getsym (p, 0), p->elems_count, p->elem_size + p->name_size,
+        sortfunc);
 }
 
 /* END */