1 /****************************************************************************/
2 /* */
3 /* Module: jamstack.c */
4 /* */
5 /* Copyright (C) Altera Corporation 1997 */
6 /* */
7 /* Description: Functions for maintaining the stack */
8 /* */
9 /* Revisions: 1.1 added support for dynamic memory allocation */
10 /* */
11 /****************************************************************************/
12
13 #include "jamexprt.h"
14 #include "jamdefs.h"
15 #include "jamutil.h"
16 #include "jamsym.h"
17 #include "jamstack.h"
18 #include <stdint.h>
19 JAMS_STACK_RECORD *urj_jam_stack = 0;
20
21 /****************************************************************************/
22 /* */
23
24 JAM_RETURN_TYPE
urj_jam_init_stack(void)25 urj_jam_init_stack (void)
26 /* */
27 /* Description: Initialize the stack. The stack is located after the */
28 /* symbol table in the workspace buffer. */
29 /* */
30 /* Returns: JAMC_SUCCESS for success, else appropriate error code */
31 /* */
32 /****************************************************************************/
33 {
34 int index = 0;
35 int size = 0;
36 JAM_RETURN_TYPE return_code = JAMC_SUCCESS;
37 void **symbol_table = NULL;
38
39 if (urj_jam_workspace != NULL)
40 {
41 symbol_table = (void **) urj_jam_workspace;
42 urj_jam_stack =
43 (JAMS_STACK_RECORD *) & symbol_table[JAMC_MAX_SYMBOL_COUNT];
44
45 size = (JAMC_MAX_SYMBOL_COUNT * sizeof (void *)) +
46 (JAMC_MAX_NESTING_DEPTH * sizeof (JAMS_STACK_RECORD));
47
48 if (urj_jam_workspace_size < size)
49 {
50 return_code = JAMC_OUT_OF_MEMORY;
51 }
52 }
53 else
54 {
55 urj_jam_stack =
56 malloc (JAMC_MAX_NESTING_DEPTH * sizeof (JAMS_STACK_RECORD));
57
58 if (urj_jam_stack == NULL)
59 {
60 return_code = JAMC_OUT_OF_MEMORY;
61 }
62 }
63
64 if (return_code == JAMC_SUCCESS)
65 {
66 for (index = 0; index < JAMC_MAX_NESTING_DEPTH; ++index)
67 {
68 urj_jam_stack[index].type = JAM_ILLEGAL_STACK_TYPE;
69 urj_jam_stack[index].iterator = (JAMS_SYMBOL_RECORD *) 0;
70 urj_jam_stack[index].for_position = 0L;
71 urj_jam_stack[index].stop_value = 0L;
72 urj_jam_stack[index].step_value = 0L;
73 urj_jam_stack[index].push_value = 0L;
74 urj_jam_stack[index].return_position = 0L;
75 }
76 }
77
78 return return_code;
79 }
80
81 void
urj_jam_free_stack(void)82 urj_jam_free_stack (void)
83 {
84 if ((urj_jam_stack != NULL) && (urj_jam_workspace == NULL))
85 {
86 free (urj_jam_stack);
87 }
88 }
89
90 /****************************************************************************/
91 /* */
92
93 JAM_RETURN_TYPE
urj_jam_push_stack_record(JAMS_STACK_RECORD * stack_record)94 urj_jam_push_stack_record (JAMS_STACK_RECORD *stack_record)
95 /* */
96 /* Description: Creates a new stack record with the specified */
97 /* attributes. */
98 /* */
99 /* Returns: JAMC_SUCCESS for success, or JAMC_OUT_OF_MEMORY if */
100 /* the stack was already full */
101 /* */
102 /****************************************************************************/
103 {
104 int index = 0;
105 JAM_RETURN_TYPE return_code = JAMC_OUT_OF_MEMORY;
106
107 /*
108 * Find stack top
109 */
110 while ((index < JAMC_MAX_NESTING_DEPTH) &&
111 (urj_jam_stack[index].type != JAM_ILLEGAL_STACK_TYPE))
112 {
113 ++index;
114 }
115
116 /*
117 * Add new stack record
118 */
119 if ((index < JAMC_MAX_NESTING_DEPTH) &&
120 (urj_jam_stack[index].type == JAM_ILLEGAL_STACK_TYPE))
121 {
122 urj_jam_stack[index].type = stack_record->type;
123 urj_jam_stack[index].iterator = stack_record->iterator;
124 urj_jam_stack[index].for_position = stack_record->for_position;
125 urj_jam_stack[index].stop_value = stack_record->stop_value;
126 urj_jam_stack[index].step_value = stack_record->step_value;
127 urj_jam_stack[index].push_value = stack_record->push_value;
128 urj_jam_stack[index].return_position = stack_record->return_position;
129
130 return_code = JAMC_SUCCESS;
131 }
132
133 return return_code;
134 }
135
136 /****************************************************************************/
137 /* */
138
139 JAMS_STACK_RECORD *
urj_jam_peek_stack_record(void)140 urj_jam_peek_stack_record (void)
141 /* */
142 /* Description: Finds the top of the stack */
143 /* */
144 /* Returns: Pointer to the top-most stack record, or NULL if the */
145 /* stack is empty */
146 /* */
147 /****************************************************************************/
148 {
149 int index = 0;
150 JAMS_STACK_RECORD *top = NULL;
151
152 /*
153 * Find stack top
154 */
155 while ((index < JAMC_MAX_NESTING_DEPTH) &&
156 (urj_jam_stack[index].type != JAM_ILLEGAL_STACK_TYPE))
157 {
158 ++index;
159 }
160
161 if ((index > 0) && (index < JAMC_MAX_NESTING_DEPTH))
162 {
163 top = &urj_jam_stack[index - 1];
164 }
165
166 return top;
167 }
168
169 /****************************************************************************/
170 /* */
171
172 JAM_RETURN_TYPE
urj_jam_pop_stack_record(void)173 urj_jam_pop_stack_record (void)
174 /* */
175 /* Description: Deletes the top-most stack record from the stack */
176 /* */
177 /* Returns: JAMC_SUCCESS for success, or JAMC_OUT_OF_MEMORY if the */
178 /* stack was empty */
179 /* */
180 /****************************************************************************/
181 {
182 int index = 0;
183 JAM_RETURN_TYPE return_code = JAMC_OUT_OF_MEMORY;
184
185 /*
186 * Find stack top
187 */
188 while ((index < JAMC_MAX_NESTING_DEPTH) &&
189 (urj_jam_stack[index].type != JAM_ILLEGAL_STACK_TYPE))
190 {
191 ++index;
192 }
193
194 /*
195 * Delete stack record
196 */
197 if ((index > 0) && (index < JAMC_MAX_NESTING_DEPTH))
198 {
199 --index;
200
201 urj_jam_stack[index].type = JAM_ILLEGAL_STACK_TYPE;
202 urj_jam_stack[index].iterator = (JAMS_SYMBOL_RECORD *) 0;
203 urj_jam_stack[index].for_position = 0L;
204 urj_jam_stack[index].stop_value = 0L;
205 urj_jam_stack[index].step_value = 0L;
206 urj_jam_stack[index].push_value = 0L;
207 urj_jam_stack[index].return_position = 0L;
208
209 return_code = JAMC_SUCCESS;
210 }
211
212 return return_code;
213 }
214
215 /****************************************************************************/
216 /* */
217
urj_jam_push_fornext_record(JAMS_SYMBOL_RECORD * iterator,int32_t for_position,int32_t stop_value,int32_t step_value)218 JAM_RETURN_TYPE urj_jam_push_fornext_record
219 (JAMS_SYMBOL_RECORD *iterator,
220 int32_t for_position, int32_t stop_value, int32_t step_value)
221 /* */
222 /* Description: Pushes a FOR/NEXT record onto the stack */
223 /* */
224 /* Returns: JAMC_SUCCESS for success, else appropriate error code */
225 /* */
226 /****************************************************************************/
227 {
228 JAMS_STACK_RECORD stack_record;
229
230 stack_record.type = JAM_STACK_FOR_NEXT;
231 stack_record.iterator = iterator;
232 stack_record.for_position = for_position;
233 stack_record.stop_value = stop_value;
234 stack_record.step_value = step_value;
235 stack_record.push_value = 0L;
236 stack_record.return_position = 0L;
237
238 return urj_jam_push_stack_record (&stack_record);
239 }
240
241 /****************************************************************************/
242 /* */
243
244 JAM_RETURN_TYPE
urj_jam_push_pushpop_record(int32_t value)245 urj_jam_push_pushpop_record (int32_t value)
246 /* */
247 /* Description: Pushes a PUSH/POP record onto the stack */
248 /* */
249 /* Returns: JAMC_SUCCESS for success, else appropriate error code */
250 /* */
251 /****************************************************************************/
252 {
253 JAMS_STACK_RECORD stack_record;
254
255 stack_record.type = JAM_STACK_PUSH_POP;
256 stack_record.iterator = NULL;
257 stack_record.for_position = 0L;
258 stack_record.stop_value = 0L;
259 stack_record.step_value = 0L;
260 stack_record.push_value = value;
261 stack_record.return_position = 0L;
262
263 return urj_jam_push_stack_record (&stack_record);
264 }
265
266 /****************************************************************************/
267 /* */
268
269 JAM_RETURN_TYPE
urj_jam_push_callret_record(int32_t return_position)270 urj_jam_push_callret_record (int32_t return_position)
271 /* */
272 /* Description: Pushes a CALL/RETURN record onto the stack */
273 /* */
274 /* Returns: JAMC_SUCCESS for success, else appropriate error code */
275 /* */
276 /****************************************************************************/
277 {
278 JAMS_STACK_RECORD stack_record;
279
280 stack_record.type = JAM_STACK_CALL_RETURN;
281 stack_record.iterator = NULL;
282 stack_record.for_position = 0L;
283 stack_record.stop_value = 0L;
284 stack_record.step_value = 0L;
285 stack_record.push_value = 0L;
286 stack_record.return_position = return_position;
287
288 return urj_jam_push_stack_record (&stack_record);
289 }
290