/[ascend]/trunk/ascend/compiler/proc.c
ViewVC logotype

Contents of /trunk/ascend/compiler/proc.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2318 - (show annotations) (download) (as text)
Tue Dec 14 06:27:47 2010 UTC (11 years, 6 months ago) by jpye
File MIME type: text/x-csrc
File size: 7960 byte(s)
removing some unneeded #includes of 'slist.h'.
1 /*
2 * Procedure Data Structure Implementation
3 * by Tom Epperly
4 * Created: 1/10/90
5 * Version: $Revision: 1.18 $
6 * Version control file: $RCSfile: proc.c,v $
7 * Date last modified: $Date: 1998/04/11 01:31:21 $
8 * Last modified by: $Author: ballan $
9 *
10 * This file is part of the Ascend Language Interpreter.
11 *
12 * Copyright (C) 1990, 1993, 1994 Thomas Guthrie Epperly
13 * Copyright (C) 1998 Carnegie Mellon University
14 *
15 * The Ascend Language Interpreter is free software; you can redistribute
16 * it and/or modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of the
18 * License, or (at your option) any later version.
19 *
20 * The Ascend Language Interpreter is distributed in hope that it will be
21 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with the program; if not, write to the Free Software Foundation,
27 * Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named
28 * COPYING.
29 *
30 */
31
32 #include "proc.h"
33
34 #include <ascend/utilities/ascConfig.h>
35 #include <ascend/utilities/ascMalloc.h>
36
37 #include "symtab.h"
38 #include "instance_enum.h"
39 #include "cmpfunc.h"
40 #include <ascend/general/list.h>
41
42
43 #include "functype.h"
44 #include "expr_types.h"
45 #include "stattypes.h"
46 #include "statement.h"
47
48 #define PMALLOC(x) x = ASC_NEW(struct InitProcedure)
49 /*
50 * UNIVERSAL method list for all models.
51 * If a method lookup fails, this list is consulted.
52 * more or less this exists because there isn't an
53 * explicit root MODEL in the implementation.
54 */
55 static struct gl_list_t *g_model_definition_methods = NULL;
56 #define GMDM g_model_definition_methods
57
58 struct InitProcedure *CreateProcedure(symchar *name,
59 struct StatementList *stats)
60 {
61 register struct InitProcedure *result;
62 assert(AscFindSymbol(name)!=NULL);
63 PMALLOC(result);
64 assert(result!=NULL);
65 result->name = name;
66 result->slist = stats;
67 result->parse_id = 0;
68 if (stats!=NULL) AddContext(stats,context_METH);
69 return result;
70 }
71
72 struct InitProcedure *CopyProcedure(struct InitProcedure *p)
73 {
74 register struct InitProcedure *result;
75 assert(p!=NULL);
76 PMALLOC(result);
77 assert(result!=NULL);
78 result->name = p->name;
79 result->parse_id = p->parse_id;
80 result->slist = CopyStatementList(p->slist);
81 return result;
82 }
83
84 struct InitProcedure *CopyProcToModify(struct InitProcedure *p)
85 {
86 register struct InitProcedure *result;
87 assert(p!=NULL);
88 PMALLOC(result);
89 assert(result!=NULL);
90 result->name = p->name;
91 result->parse_id = 0;
92 result->slist = CopyListToModify(p->slist);
93 return result;
94 }
95
96 struct gl_list_t *MergeProcedureLists(struct gl_list_t *old,
97 struct gl_list_t *new)
98 {
99 register struct gl_list_t *result;
100 register struct InitProcedure *proc;
101 register unsigned long c,len;
102 register unsigned long refproc;
103 if (old==NULL) {
104 return new;
105 }
106 result = gl_create(gl_length(old)+gl_safe_length(new));
107 if (new!=NULL){
108 len = gl_length(new);
109 for(c=1;c<=len;c++){
110 proc = (struct InitProcedure *)gl_fetch(new,c);
111 gl_append_ptr(result,(VOIDPTR)proc);
112 } /* dont destroy the list yet */
113 }
114 len = gl_length(old);
115 /* this is where method inheritance rules occur. We keep all the
116 * methods from the new in result, then we search for any method in
117 * the old list which does not have an identically named
118 * counterpart in the new list and add it to the result.
119 * Methods in the old result which have be redefined in the new
120 * list given are ignored.
121 *
122 * Once a result list is achieved the new list (but not the methods
123 * in it) may be destroyed since the methods are all stored in result.
124 */
125 if (new!=NULL) {
126 for(c=1;c<=len;c++) {
127 proc = (struct InitProcedure *)gl_fetch(old,c);
128 refproc = gl_search(new,proc,(CmpFunc)CmpProcs);
129 /* refproc will be 0 if no match */
130 if (refproc==0) {
131 /* hence append to result */
132 gl_append_ptr(result,(VOIDPTR)CopyProcedure(proc));
133 }
134 }
135 gl_destroy(new);
136 } else {
137 for(c=1;c<=len;c++){
138 proc = (struct InitProcedure *)gl_fetch(old,c);
139 gl_append_ptr(result,(VOIDPTR)CopyProcedure(proc));
140 }
141 }
142 gl_sort(result,(CmpFunc)CmpProcs);
143 return result;
144 }
145
146 void DestroyProcedure(struct InitProcedure *p)
147 {
148 if (p!=NULL){
149 /* the following only destroys a reference to p->slist
150 * unless of course it is the last reference to p->slist.
151 * The name of the method belongs to the symbol table so must
152 * not be destroyed here.
153 */
154 DestroyStatementList(p->slist);
155 p->parse_id = -1;
156 ascfree((char *)p);
157 }
158 }
159
160 void DestroyProcedureList(struct gl_list_t *pl)
161 {
162 if (pl!=NULL){
163 gl_iterate(pl,(void (*)(VOIDPTR))DestroyProcedure);
164 gl_destroy(pl);
165 }
166 }
167
168 /*
169 * Returns the list of methods defined for all MODELs
170 * unless they redefine the methods themselves.
171 */
172 struct gl_list_t *GetUniversalProcedureList(void)
173 {
174 return GMDM;
175 }
176
177 /*
178 * Sets the list of procedures defined for all MODELs.
179 * If a UPL already exists, it will be destroyed unless it
180 * is the same. If the same, it is resorted.
181 */
182 void SetUniversalProcedureList(struct gl_list_t *upl)
183 {
184 if (GMDM != upl) {
185 DestroyProcedureList(GMDM);
186 GMDM = upl;
187 }
188 if (GMDM != NULL) {
189 gl_sort(GMDM,(CmpFunc)CmpProcs);
190 }
191 return;
192 }
193
194 symchar *ProcNameF(CONST struct InitProcedure *p)
195 {
196 assert(p!=NULL);
197 return p->name;
198 }
199
200 struct StatementList *ProcStatementListF(CONST struct InitProcedure *p)
201 {
202 assert(p!=NULL);
203 return p->slist;
204 }
205
206 long GetProcParseIdF(CONST struct InitProcedure *p)
207 {
208 assert(p!=NULL);
209 return p->parse_id;
210 }
211
212 void SetProcParseIdF(struct InitProcedure *p, long id)
213 {
214 assert(p!=NULL);
215 p->parse_id = id;
216 }
217
218 int CmpProcs(CONST struct InitProcedure *p1, CONST struct InitProcedure *p2)
219 {
220 assert(p1 && p2);
221 return CmpSymchar(p1->name,p2->name);
222 }
223
224
225 int CompareProcedureLists(struct gl_list_t *pl1, struct gl_list_t *pl2,
226 unsigned long *n)
227 {
228 CONST struct InitProcedure *proc1, *proc2;
229 CONST struct StatementList *sl1, *sl2;
230 unsigned long c,len, len1, len2, diff;
231
232 assert (n != NULL);
233
234 /* compare ptrs */
235 if (pl1==pl2) {
236 return 0;
237 }
238
239 /* check for nulls */
240 if ( (pl1==NULL) || (pl2==NULL) ) {
241 *n = 1;
242 return 1;
243 }
244
245 /* length of each procedure list */
246 len1 = gl_length(pl1);
247 len2 = gl_length(pl2);
248
249 /*
250 * if len1 and len2 are different from each other , we will return 1,
251 * but we still need to find the index of the first different procedure.
252 * So, get the number of elements of the shorthest list and compare
253 * that number of procedures in the lists
254 */
255 if (len1 == len2) {
256 len = len1;
257 } else {
258 if (len1 < len2) {
259 len = len1;
260 } else {
261 len = len2;
262 }
263 }
264
265 /* analyze the list of procedures */
266 for(c=1;c<=len;c++){
267 proc1 = (struct InitProcedure *)gl_fetch(pl1,c);
268 proc2 = (struct InitProcedure *)gl_fetch(pl2,c);
269
270 /*
271 * compare names
272 */
273 if (CmpProcs(proc1,proc2)) {
274 *n = c;
275 return 1;
276 }
277 /*
278 * compare statement lists
279 * if lists are different, diff will contain the index of the first
280 * different statement. Use it if necessary
281 */
282 sl1 = ProcStatementList(proc1);
283 sl2 = ProcStatementList(proc2);
284 if (CompareStatementLists(sl1,sl2,&diff)) {
285 *n = c;
286 return 1;
287 }
288 }
289
290 /*
291 * If we get here and the number of elements in the list are equal,
292 * then the procedures are equal,
293 * else the index of the first different procedure is len + 1
294 */
295 if (len1 == len2) {
296 return 0;
297 } else {
298 *n = len+1;
299 return 1;
300 }
301
302 /* parse_id are not for comparison */
303 }

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22