1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
|
/* Copyright David Leonard and Andrew Janke, 2000. All rights reserved. */
#include <stdio.h>
#include <stdlib.h>
#include "node.h"
#define NEW_SCOPE (-1)
typedef enum {SYM_UNKNOWN, SYM_SCALAR, SYM_VECTOR} sym_type_t;
struct sym {
ident_t ident;
sym_type_t type;
scalar_t scalar;
vector_t vector;
sym_t next;
};
static sym_t new_sym(ident_t id, sym_t sym){
sym_t newsym;
newsym = malloc(sizeof *newsym);
newsym->ident = id;
newsym->type = SYM_UNKNOWN;
/* We put new scope nodes at the head of the list. For regular symbols,
we add the symbol to the head of the list only in the case where
the head of the current symbol table is not a new scope. */
if ((id == NEW_SCOPE) || (sym==NULL) || (sym->ident != NEW_SCOPE)) {
newsym->next = sym;
}
/* Usually for regular symbols, we add the symbol to an existing scope,
so we put it as the second element of the list and return the
head of the list. */
else {
newsym->next = sym->next;
sym->next = newsym;
}
return newsym;
}
sym_t sym_enter_scope(sym_t sym) {
sym_t newsym = new_sym(NEW_SCOPE, sym);
return newsym;
}
void sym_leave_scope(sym_t sym) {
sym_t osym;
if (sym==NULL) return;
do {
osym = sym->next;
if (sym->type == SYM_VECTOR) {
vector_free(sym->vector);
}
free(sym);
sym = osym;
} while ((sym != NULL) && (sym->ident != NEW_SCOPE));
return;
}
void sym_declare_ident(ident_t id, sym_t sym) {
(void) new_sym(id, sym);
return;
}
static sym_t sym_lookup(ident_t id, sym_t sym){
while (sym) {
if (sym->ident == id)
break;
sym = sym->next;
}
return sym;
}
void sym_set_scalar(int width, int *eval_flags,
scalar_t sc, ident_t id, sym_t sym){
int ivalue;
/* Find the symbol - it is does not exist make a new one */
sym_t newsym = sym_lookup(id, sym);
if (newsym == NULL) {
newsym = new_sym(id, sym);
}
/* Make sure that any existing one is of the right type */
if (newsym->type == SYM_VECTOR) {
/* errx(1, "%s is not a scalar", ident_str(id)); */
fprintf(stderr, "%s is not a scalar(lowercase)\n", ident_str(id));
exit(1);
}
/* Create a new scalar if needed */
if (newsym->type == SYM_UNKNOWN || newsym->scalar->width < width) {
if (newsym->type == SYM_SCALAR)
scalar_free(newsym->scalar);
newsym->type = SYM_SCALAR;
newsym->scalar = new_scalar(width);
}
/* Copy in the values */
for (ivalue=0; ivalue < width; ivalue++) {
if (eval_flags != NULL && !eval_flags[ivalue]) continue;
newsym->scalar->vals[ivalue] = sc->vals[ivalue];
}
return;
}
void sym_set_vector(int width, int *eval_flags,
vector_t v, ident_t id, sym_t sym){
int ivalue, iel;
scalar_t sc;
/* Find the symbol - it is does not exist make a new one */
sym_t newsym = sym_lookup(id, sym);
if (newsym == NULL) {
newsym = new_sym(id, sym);
}
/* Make sure that any existing one is of the right type */
if (newsym->type == SYM_SCALAR) {
/* errx(1, "%s is not a vector", ident_str(id)); */
fprintf(stderr, "%s is not a vector\n", ident_str(id));
exit(1);
}
/* Create a new vector if needed - either it does not exist or the
length is changing or the width is increasing*/
if (newsym->type == SYM_UNKNOWN || newsym->vector->len != v->len ||
(newsym->vector->len > 0 && newsym->vector->el[0]->width < width) ) {
/* Free an existing vector. If eval_flags is set, then we cannot
change the length of the vector */
if (newsym->type == SYM_VECTOR) {
if (eval_flags != NULL && newsym->vector->len != v->len) {
/* errx(1, "assigned vector must match length of %s in if",
ident_str(id)); */
fprintf(stderr, "assigned vector must match length of %s in if",
ident_str(id));
exit(1);
}
vector_free(newsym->vector);
}
newsym->type = SYM_VECTOR;
newsym->vector = new_vector();
for (iel=0; iel < v->len; iel++) {
sc = new_scalar(width);
vector_append(newsym->vector, sc);
scalar_free(sc);
}
}
/* Copy in the values */
for (ivalue=0; ivalue < width; ivalue++) {
if (eval_flags != NULL && !eval_flags[ivalue]) continue;
for (iel=0; iel < v->len; iel++) {
newsym->vector->el[iel]->vals[ivalue] = v->el[iel]->vals[ivalue];
}
}
return;
}
scalar_t sym_lookup_scalar(ident_t id, sym_t sym){
sym_t s = sym_lookup(id, sym);
if (!s) {
/* errx(1, "%s undefined", ident_str(id)); */
fprintf(stderr, "%s undefined\n", ident_str(id));
exit(1);
}
if (s->type != SYM_SCALAR) {
/* errx(1, "%s is not scalar (lowercase)", ident_str(id)); */
fprintf(stderr, "%s is not scalar (lowercase)\n", ident_str(id));
exit(1);
}
return s->scalar;
}
vector_t sym_lookup_vector(ident_t id, sym_t sym){
sym_t s = sym_lookup(id, sym);
if (!s) {
/* errx(1, "%s undefined", ident_str(id)); */
fprintf(stderr, "%s undefined\n", ident_str(id));
exit(1);
}
if (s->type != SYM_VECTOR)
return NULL;
return s->vector;
}
|