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