/* * Copyright (c)2004 Cat's Eye Technologies. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 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. * * Neither the name of Cat's Eye Technologies 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 THE * 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. */ /* * symbol.c * Symbol and symbol table housekeeping and manipulation for 2Iota. * $Id: symbol.c 518 2010-04-28 17:48:38Z cpressey $ */ #include #include #include #include #include "symbol.h" #include "alphabet.h" #include "2iota.h" struct symbol_table * symbol_table_new(void) { struct symbol_table *stab; MALLOC(stab, symbol_table, "symbol table"); stab->head = NULL; return(stab); } /* * Intended to be called on the symbol tables of * events (representing their local parameters,) * and causes all the local parameters to become * unbound. */ void symbol_table_unbind(struct symbol_table *stab) { struct symbol *sym; for (sym = stab->head; sym != NULL; sym = sym->next) { symstr_free(sym->data); sym->data = NULL; } } /* assumed: preceding call to symbol_lookup failed. */ struct symbol * symbol_define(struct symbol_table *stab, char *token, int type) { struct symbol *new_sym; MALLOC(new_sym, symbol, "symbol"); new_sym->token = malloc(strlen(token) + 1); if (new_sym->token == NULL) errx(1, "Could not allocate symbol lexeme"); strcpy(new_sym->token, token); new_sym->type = type; new_sym->next = stab->head; stab->head = new_sym; new_sym->alpha = NULL; new_sym->data = NULL; return(new_sym); } struct symbol * symbol_lookup(struct symbol_table *stab, char *s) { struct symbol *sym; for (sym = stab->head; sym != NULL; sym = sym->next) if (!strcmp(s, sym->token)) return(sym); return(NULL); } struct symbol * symbol_next(struct symbol *sym, struct alphabet *alpha) { struct alpha_entry *entry; if ((entry = alphabet_lookup(alpha, sym)) != NULL) if (entry->next != NULL) return(entry->next->sym); return(NULL); } struct symbol * symbol_prev(struct symbol *sym, struct alphabet *alpha) { struct alpha_entry *entry; if ((entry = alphabet_lookup(alpha, sym)) != NULL) if (entry->prev != NULL) return(entry->prev->sym); return(NULL); } void symbol_table_dump(int indent, struct symbol_table *stab) { struct symbol *sym; for (sym = stab->head; sym != NULL; sym = sym->next) symbol_dump(indent, sym); } void symbol_print(struct symbol *sym) { if (sym != NULL) fprintf(stderr, "%s", sym->token); else fprintf(stderr, "*SYMNULL*"); } void symbol_dump(int indent, struct symbol *sym) { const char *ty; int i; for (i = 0; i < indent; i++) fprintf(stderr, "\t"); if (sym == NULL) { fprintf(stderr, "*NULLSYM*\n"); return; } switch (sym->type) { case SYM_TYPE_LITERAL: ty = "literal"; break; case SYM_TYPE_ALPHABET: ty = "alphabet"; break; case SYM_TYPE_SYMBOL: ty = "symbol"; break; case SYM_TYPE_PARAMETER: ty = "parameter"; break; default: ty = "?"; break; } fprintf(stderr, "%-30s %-10s", sym->token, ty); if (sym->type == SYM_TYPE_ALPHABET) { struct alpha_entry *entry; fprintf(stderr, " ->\n"); for (entry = sym->alpha->head; entry != NULL; entry = entry->next) { symbol_dump(indent + 1, entry->sym); } } else if (sym->type == SYM_TYPE_PARAMETER) { fprintf(stderr, " = "); symstr_dump(sym->data); fprintf(stderr, "\n"); } else { fprintf(stderr, "\n"); } }