1 |
/* ASCEND modelling environment |
2 |
Copyright (C) 2007 Carnegie Mellon University |
3 |
|
4 |
This program is free software; you can redistribute it and/or modify |
5 |
it under the terms of the GNU General Public License as published by |
6 |
the Free Software Foundation; either version 2, or (at your option) |
7 |
any later version. |
8 |
|
9 |
This program is distributed in the hope that it will be useful, |
10 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 |
GNU General Public License for more details. |
13 |
|
14 |
You should have received a copy of the GNU General Public License |
15 |
along with this program; if not, write to the Free Software |
16 |
Foundation, Inc., 59 Temple Place - Suite 330, |
17 |
Boston, MA 02111-1307, USA. |
18 |
*//** @file |
19 |
The following functions give an automatic, default form for the |
20 |
'default_all' and 'default_self' methods usually written as explicit |
21 |
METHODs in a model. EXPERIMENTAL. |
22 |
*//* |
23 |
by John Pye, 15 Feb 2007. |
24 |
*/ |
25 |
|
26 |
#include <packages/defaultall.h> |
27 |
|
28 |
#include <compiler/proc.h> |
29 |
#include <compiler/name.h> |
30 |
|
31 |
#include <utilities/ascConfig.h> |
32 |
#include <utilities/ascPrint.h> |
33 |
#include <utilities/ascPanic.h> |
34 |
|
35 |
#include <compiler/instquery.h> |
36 |
#include <compiler/child.h> |
37 |
#include <compiler/type_desc.h> |
38 |
#include <compiler/symtab.h> |
39 |
#include <compiler/atomvalue.h> |
40 |
#include <compiler/visitinst.h> |
41 |
#include <compiler/parentchild.h> |
42 |
#include <compiler/library.h> |
43 |
#include <compiler/watchpt.h> |
44 |
#include <compiler/initialize.h> |
45 |
|
46 |
/* #define DEFAULT_DEBUG */ |
47 |
|
48 |
/** |
49 |
Find atom children in the present model and set them to their ATOM DEFAULT |
50 |
values. |
51 |
*/ |
52 |
static |
53 |
int Asc_DefaultSelf1(struct Instance *inst){ |
54 |
int i,n; |
55 |
struct Instance *c; |
56 |
struct TypeDescription *type; |
57 |
|
58 |
/* default any child atoms' values */ |
59 |
n = NumberChildren(inst); |
60 |
for(i = 1; i <= n; ++i){ |
61 |
#ifdef DEFAULT_DEBUG |
62 |
CONSOLE_DEBUG("Child %d...", i); |
63 |
#endif |
64 |
c = InstanceChild(inst,i); |
65 |
if(c==NULL)continue; |
66 |
|
67 |
type = InstanceTypeDesc(c); |
68 |
if(BaseTypeIsAtomic(type)){ |
69 |
if(!AtomDefaulted(type))continue; |
70 |
switch(GetBaseType(type)){ |
71 |
case real_type: SetRealAtomValue(c, GetRealDefault(type), 0); break; |
72 |
case integer_type: SetIntegerAtomValue(c, GetIntDefault(type), 0); break; |
73 |
case boolean_type: SetBooleanAtomValue(c, GetBoolDefault(type), 0); break; |
74 |
case symbol_type: SetSymbolAtomValue(c, GetSymDefault(type)); break; |
75 |
case set_type: /* what is the mechanism for defaulting of sets? */ |
76 |
default: ASC_PANIC("invalid type"); |
77 |
} |
78 |
#ifdef DEFAULT_DEBUG |
79 |
CONSOLE_DEBUG("Reset atom to default value"); |
80 |
#endif |
81 |
}else if(GetBaseType(type)==array_type){ |
82 |
/* descend into arrays */ |
83 |
Asc_DefaultSelf1(c); |
84 |
} |
85 |
} |
86 |
return 0; |
87 |
} |
88 |
|
89 |
struct DefaultAll_data{ |
90 |
symchar *default_all; |
91 |
}; |
92 |
|
93 |
/** |
94 |
Find child models in the present model and run their 'default_all' methods |
95 |
*/ |
96 |
static |
97 |
int Asc_DefaultAll1(struct Instance *inst, struct DefaultAll_data *data){ |
98 |
int i, n, err = 0; |
99 |
struct Instance *c; |
100 |
struct TypeDescription *type; |
101 |
struct InitProcedure *method; |
102 |
enum Proc_enum pe; |
103 |
|
104 |
type = InstanceTypeDesc(inst); |
105 |
|
106 |
/* loop through child atoms */ |
107 |
n = NumberChildren(inst); |
108 |
for(i = 1; i <= n; ++i){ |
109 |
c = InstanceChild(inst,i); |
110 |
if(c==NULL)continue; |
111 |
|
112 |
type = InstanceTypeDesc(c); |
113 |
if(model_type == GetBaseType(type)){ |
114 |
/* run 'default_all' for all child models */ |
115 |
method = FindMethod(type,data->default_all); |
116 |
if(method){ |
117 |
#ifdef DEFAULT_DEBUG |
118 |
CONSOLE_DEBUG("Running default_all on '%s'",SCP(GetName(type))); |
119 |
#endif |
120 |
pe = Initialize(c , CreateIdName(ProcName(method)), "__not_named__" |
121 |
,ASCERR |
122 |
,0, NULL, NULL |
123 |
); |
124 |
if(pe!=Proc_all_ok)err += 1; |
125 |
}else{ |
126 |
#ifdef DEFAULT_DEBUG |
127 |
CONSOLE_DEBUG("Recursing into array..."); |
128 |
#endif |
129 |
ERROR_REPORTER_HERE(ASC_PROG_ERR,"No 'default_all' found for type '%s'",SCP(GetName(type))); |
130 |
return 1; |
131 |
} |
132 |
}else if(array_type == GetBaseType(type)){ |
133 |
if(Asc_DefaultAll1(c,data))err += 1; |
134 |
} |
135 |
} |
136 |
|
137 |
return err; |
138 |
} |
139 |
|
140 |
int Asc_DefaultSelf(struct Instance *root, struct gl_list_t *arglist, void *userdata){ |
141 |
/* arglist is a list of gllist of instances */ |
142 |
if (arglist == NULL || |
143 |
gl_length(arglist) == 0L || |
144 |
gl_length((struct gl_list_t *)gl_fetch(arglist,1)) != 1 || |
145 |
gl_fetch((struct gl_list_t *)gl_fetch(arglist,1),1) == NULL) { |
146 |
return Asc_DefaultSelf1(root); |
147 |
}else{ |
148 |
return Asc_DefaultSelf1((struct Instance *)gl_fetch( (struct gl_list_t *)gl_fetch(arglist,1),1 )); |
149 |
} |
150 |
} |
151 |
|
152 |
int Asc_DefaultAll(struct Instance *root, struct gl_list_t *arglist, void *userdata){ |
153 |
struct DefaultAll_data data; |
154 |
data.default_all = AddSymbol("default_all"); |
155 |
|
156 |
/* arglist is a list of gllist of instances */ |
157 |
if (arglist == NULL || |
158 |
gl_length(arglist) == 0L || |
159 |
gl_length((struct gl_list_t *)gl_fetch(arglist,1)) != 1 || |
160 |
gl_fetch((struct gl_list_t *)gl_fetch(arglist,1),1) == NULL) { |
161 |
return Asc_DefaultAll1(root,&data); |
162 |
}else{ |
163 |
return Asc_DefaultAll1((struct Instance *)gl_fetch( (struct gl_list_t *)gl_fetch(arglist,1),1 ) |
164 |
, &data |
165 |
); |
166 |
} |
167 |
} |