From def21c086d7205e8b07ca102abc20e3755748296 Mon Sep 17 00:00:00 2001 From: Guillermo Ramos Date: Mon, 27 May 2013 10:19:59 +0200 Subject: start --- jast.c | 267 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 jast.c (limited to 'jast.c') diff --git a/jast.c b/jast.c new file mode 100644 index 0000000..99d4670 --- /dev/null +++ b/jast.c @@ -0,0 +1,267 @@ +/* + * Jast Another Symbol Table + * Copyright (c) 2012 Guillermo Ramos GutiƩrrez <0xwille@gmail.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +#include +#include +#include +#include +#include +#include "doll.h" +#include "jast.h" + +#define MIN(m,n) ((m) < (n) ? (m) : (n)) +#define MAX(m,n) ((m) > (n) ? (m) : (n)) + + +static struct doll *tables; +static long uniq_count = 1; + + +static char *__jast_alloc_string(char *s) +{ + int copylen = MIN(JAST_MAX_NAMELEN, strlen(s)); + char *copy = malloc((copylen+1) * sizeof(char)); + strncpy(copy, s, copylen); + copy[copylen] = '\0'; + return copy; +} + + +struct jast *jast_creat(char *name) +{ + struct jast *new_tab = malloc(sizeof(struct jast)); + + if (name) { + new_tab->name = __jast_alloc_string(name); + } else { + int len = sizeof(char *)+12; // 12 == length of "[jast@0x]\0" + new_tab->name = malloc(len); + snprintf(new_tab->name, len, "[jast@%p]", (void *)new_tab); + } + + new_tab->entries = doll_new(); + new_tab->children = doll_new(); + + if (tables == NULL) + tables = doll_new(); + doll_append(tables, new_tab); + + return new_tab; +} + + +void jast_destroy(struct jast *tab) +{ + // TODO comprobar que tab existe + struct jast_entry *entry; + doll_foreach(entry, tab->entries) { + free(entry->name); + free(entry->uniq); + } + + doll_remove(tables, tab); + doll_destroy(tab->entries); + doll_destroy(tab->children); + free(tab->name); + free(tab); +} + + +void jast_destroy_all(void) +{ + struct jast *tab; + doll_foreach(tab, tables) + jast_destroy(tab); +} + + +char *jast_uniq(char *begin) +{ + long varlen = strlen(begin) + ceill(log10(uniq_count)+1) + 1; + char *uniqname = malloc(varlen * sizeof(char)); + snprintf(uniqname, varlen, "%s%ld", begin, uniq_count++); + return uniqname; +} + + +struct jast_entry *jast_new_entry(struct jast *tab, char *name) +{ + struct jast_entry *new; + + if (name == NULL || (new = malloc(sizeof(struct jast_entry))) == NULL) + return NULL; + + new->name = __jast_alloc_string(name); + new->uniq = jast_uniq("jast_var_"); + new->tmp = 0; + new->type = JAST_UNDEF_T; + new->datatype = JAST_UNDEF_D; + new->datasize = 0; + new->attribs = NULL; + + if (tab->entries == NULL) + tab->entries = doll_new(); + + doll_append(tab->entries, new); + + return new; +} + + +struct jast_entry *jast_get_entry(struct jast *tab, char *name) +{ + struct jast_entry *entry; + doll_foreach(entry, tab->entries) + if (!strcmp(entry->name, name)) + return entry; + return NULL; +} + +// TODO usar get_entry +enum jast_entry_t jast_entry_gettype(struct jast *tab, char *name) +{ + struct jast_entry *entry; + doll_foreach(entry, tab->entries) + if (!strcmp(entry->name, name)) + return entry->type; + return JAST_ERR; +} + + +void jast_entry_settype(struct jast *tab, char *name, enum jast_entry_t type) +{ + struct jast_entry *entry; + doll_foreach(entry, tab->entries) + if (!strcmp(entry->name, name)) + entry->type = type; +// struct jast_entry *entry = doll_find(tab->entries, name); +// if (entry) +// entry->type = type; +} + + +enum jast_data_t jast_entry_getdatatype(struct jast *tab, char *name) +{ + struct jast_entry *entry; + doll_foreach(entry, tab->entries) + if (!strcmp(entry->name, name)) + return entry->datatype; + return JAST_ERR; +} + +void jast_entry_setdatatype(struct jast *tab, char *name, enum jast_data_t type) +{ + struct jast_entry *entry; + doll_foreach(entry, tab->entries) + if (!strcmp(entry->name, name)) + entry->datatype = type; +} + + +inline void __jast_dump_n_spaces(int spaces, FILE *f) +{ + while (spaces--) putc(' ', f); +} + + +int jast_dump(struct jast *tab, char *filename) +{ + struct jast_entry *entry; + int i; + char *entry_type, *data_type; + FILE *f = fopen(filename, "w"); + char *cols[] = {"name", "type", "data type", "uniq", "data size"}; + int ncols = sizeof(cols)/sizeof(cols[0]); + unsigned collen[ncols]; + unsigned colnamelen[ncols]; + int totallen = (ncols*3)+1; + + if (f == NULL || tab == NULL) // TODO quitar (puesto por warnings) + return -1; + + for (i = 0; i < ncols; i++) + collen[i] = colnamelen[i] = strlen(cols[i]); + + doll_foreach(entry, tab->entries) { + __jast_strentry(entry->type, entry_type); + __jast_strdata(entry->datatype, data_type); + collen[0] = MAX(collen[0], strlen(entry->name)); + collen[1] = MAX(collen[1], strlen(entry_type)); + collen[2] = MAX(collen[2], strlen(data_type)); + collen[3] = MAX(collen[3], strlen(entry->uniq)); + collen[4] = MAX(collen[4], log10(entry->datasize/10) + 2); + } + + for (i = 0; i < ncols; i++) + totallen += collen[i]; + + char interline[totallen - 1]; + memset(interline, '-', totallen-2); + interline[totallen-2] = '\0'; + + fprintf(f, "\n /==# %s (parent: %s)\n", tab->name, + tab->parent ? tab->parent->name : "none"); + fprintf(f, "/%s\\\n|", interline); + for (i = 0; i < ncols; i++) { + __jast_dump_n_spaces(collen[i]-colnamelen[i]+1, f); + fprintf(f, "%s |", cols[i]); + } + fprintf(f, "\n|%s|\n", interline); + doll_foreach(entry, tab->entries) { + putc('|', f); + __jast_strentry(entry->type, entry_type); + __jast_strdata(entry->datatype, data_type); + __jast_dump_n_spaces(collen[0]-strlen(entry->name)+1, f); + fprintf(f, "%s |", entry->name); + __jast_dump_n_spaces(collen[1]-strlen(entry_type)+1, f); + fprintf(f, "%s |", entry_type); + __jast_dump_n_spaces(collen[2]-strlen(data_type)+1, f); + fprintf(f, "%s |", data_type); + __jast_dump_n_spaces(collen[3]-strlen(entry->uniq)+1, f); + fprintf(f, "%s |", entry->uniq); + __jast_dump_n_spaces(collen[4]-log10(entry->datasize/10+3), f); + fprintf(f, "%dB |\n", entry->datasize); + } + fprintf(f, "\\%s/\n\n", interline); + + fclose(f); + return 0; +} + + +void jast_show_all(void) +{ + struct jast *t; + printf("\n-----------------------\n"); + doll_foreach(t, tables) + printf("%s\n", t->name); + printf("-----------------------\n"); +} -- cgit v1.2.3