File: sym.c

package info (click to toggle)
minc 2.1.10-1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 8,160 kB
  • sloc: ansic: 82,507; sh: 10,666; yacc: 1,187; perl: 612; makefile: 586; lex: 319
file content (191 lines) | stat: -rw-r--r-- 5,322 bytes parent folder | download | duplicates (6)
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;
}