aboutsummaryrefslogtreecommitdiff
path: root/core/bgdc/src/identifier.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/bgdc/src/identifier.c')
-rw-r--r--core/bgdc/src/identifier.c255
1 files changed, 255 insertions, 0 deletions
diff --git a/core/bgdc/src/identifier.c b/core/bgdc/src/identifier.c
new file mode 100644
index 0000000..8ecaf23
--- /dev/null
+++ b/core/bgdc/src/identifier.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright © 2006-2016 SplinterGU (Fenix/Bennugd)
+ * Copyright © 2002-2006 Fenix Team (Fenix)
+ * Copyright © 1999-2002 José Luis Cebrián Pagüe (Fenix)
+ *
+ * This file is part of Bennu - Game Development
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ *
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ *
+ * 3. This notice may not be removed or altered from any source
+ * distribution.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "token.h"
+#include "identifiers.h"
+#include "compiler.h"
+
+/* ---------------------------------------------------------------------- */
+/* Gestor de identificadores */
+/* ---------------------------------------------------------------------- */
+
+static identifier * identifier_hash[64] ;
+static int identifier_code = 1 ;
+int identifier_count = 0 ;
+
+int identifier_hash_value(const char * string)
+{
+ int t = 0 ;
+ const char * ptr = string ;
+
+/* while (*ptr) t = (t << 1) | *ptr++ ; */
+ while (*ptr) t = (t << 3) | ( (*ptr++) & 0x07 ) ; /* Mejor dispersion en el hashing */
+
+ return (t & 63) ;
+}
+
+identifier * identifier_first()
+{
+ int n ;
+
+ for (n = 0 ; n < 64 ; n++)
+ {
+ if (identifier_hash[n])
+ return identifier_hash[n] ;
+ }
+ return 0 ;
+}
+
+identifier * identifier_next(identifier * id)
+{
+ int n ;
+
+ if (id->next) return id->next ;
+
+ n = identifier_hash_value(id->name) ;
+ for (n++ ; n < 64 ; n++)
+ {
+ if (identifier_hash[n])
+ return identifier_hash[n] ;
+ }
+ return 0 ;
+}
+
+void identifier_init()
+{
+ int i ;
+
+ for (i = 0 ; i < 64 ; i++) identifier_hash[i] = 0 ;
+
+ identifier_count = 0 ;
+ identifier_code = 1 ;
+}
+
+void identifier_dump()
+{
+ int i, ii ;
+ identifier * ptr ;
+
+ printf("\n---- %d identifiers ----\n\n", identifier_count) ;
+ for (i = 0 ; i < 64 ; i++)
+ {
+ ptr = identifier_hash[i] ;
+ ii = 0;
+ while (ptr)
+ {
+ ii++;
+ printf("%4d: %-32s [%04d] [%3d]\n", ptr->code, ptr->name, i, ii) ;
+ ptr = ptr->next ;
+ }
+ }
+}
+
+int identifier_add_as(const char * string, int code)
+{
+ int hash = identifier_hash_value(string) ;
+ identifier * w = (identifier *)calloc(1, sizeof(identifier)) ;
+
+ if (!w)
+ {
+ fprintf(stdout, "identifier_add: out of memory\n") ;
+ exit(1);
+ }
+
+ w->name = strdup(string) ;
+ if (!w->name)
+ {
+ fprintf(stdout, "identifier_add: out of memory\n") ;
+ exit(1);
+ }
+ w->line = line_count ; /* Save First appearance */
+ w->f = current_file ; /* Save File info */
+ w->code = code ;
+ w->next = identifier_hash[hash] ;
+ identifier_hash[hash] = w ;
+ identifier_count++ ;
+
+ return 1 ;
+}
+
+int identifier_add(const char * string)
+{
+ int code = identifier_code++ ;
+ if (!identifier_add_as(string, code)) return 0 ;
+ return code ;
+}
+
+int identifier_search(const char * string)
+{
+ int hash = identifier_hash_value(string) ;
+ identifier * ptr = identifier_hash[hash] ;
+
+ while (ptr)
+ {
+ if (!ptr->name) return 0;
+ if (ptr->name[0] == *string)
+ {
+ if (strcmp(string, ptr->name) == 0) break ;
+ }
+ ptr = ptr->next ;
+ }
+ return ptr ? ptr->code : 0 ;
+}
+
+/* Return line for the identifier */
+int identifier_line(int code)
+{
+ int i ;
+ identifier * ptr ;
+
+ for (i = 0 ; i < 64 ; i++)
+ {
+ ptr = identifier_hash[i] ;
+ while (ptr)
+ {
+ if (ptr->code == code) {
+ return ptr->line ;
+ }
+ ptr = ptr->next ;
+ }
+ }
+ return 0 ;
+}
+
+/* Return file for the identifier */
+int identifier_file(int code)
+{
+ int i ;
+ identifier * ptr ;
+
+ for (i = 0 ; i < 64 ; i++)
+ {
+ ptr = identifier_hash[i] ;
+ while (ptr)
+ {
+ if (ptr->code == code) {
+ return ptr->f ;
+ }
+ ptr = ptr->next ;
+ }
+ }
+ return 0 ;
+}
+
+const char * identifier_name(int code)
+{
+ int i ;
+ identifier * ptr ;
+
+ for (i = 0 ; i < 64 ; i++)
+ {
+ ptr = identifier_hash[i] ;
+ while (ptr)
+ {
+ if (ptr->code == code) {
+ return ptr->name ;
+ }
+ ptr = ptr->next ;
+ }
+ }
+ return 0 ;
+}
+
+int identifier_search_or_add(const char * string)
+{
+ int result ;
+
+ result = identifier_search(string) ;
+ return result ? result : identifier_add(string) ;
+}
+
+int identifier_next_code()
+{
+ return identifier_code ;
+}
+
+int identifier_is_basic_type(int id)
+{
+ return (
+ id == identifier_int ||
+ id == identifier_short ||
+ id == identifier_char ||
+ id == identifier_dword ||
+ id == identifier_word ||
+ id == identifier_byte ||
+ id == identifier_signed ||
+ id == identifier_unsigned ||
+ id == identifier_float ||
+ id == identifier_string
+ );
+}
+
+int identifier_is_type(int id)
+{
+ return identifier_is_basic_type(id) || segment_by_name(id) != NULL;
+}
+