4 # Morgan Deters <mdeters@cs.nyu.edu> for CVC4
5 # Copyright (c) 2010-2013 The CVC4 Project
7 # The purpose of this script is to create metakind.h from a template
8 # and a list of theory kinds.
10 # This is kept distinct from kind.h because kind.h is a public header
11 # and metakind.h is intended for the expr package only.
15 # mkmetakind template-file theory-kind-files...
17 # Output is to standard out.
23 /********************* */
26 ** Copyright $copyright New York University and The University of Iowa,
29 ** This header file automatically generated by:
33 ** for the CVC4 project.
44 metakind_constantMaps
=
47 metakind_constPrinters
=
48 metakind_constDeleters
=
51 metakind_operatorKinds
=
54 seen_theory_builtin
=false
59 lineno
=${BASH_LINENO[0]}
62 echo "$kf:$lineno: error: multiple theories defined in one file !?" >&2
66 # this script doesn't care about the theory class information, but
67 # makes does make sure it's there
69 if [ "$1" = THEORY_BUILTIN
]; then
70 if $seen_theory_builtin; then
71 echo "$kf:$lineno: error: \"builtin\" theory redefined" >&2
74 seen_theory_builtin
=true
75 elif [ -z "$1" -o -z "$2" -o -z "$3" ]; then
76 echo "$kf:$lineno: error: \"theory\" directive missing class or header argument" >&2
78 elif ! expr "$2" : '\(::*\)' >/dev
/null
; then
79 echo "$kf:$lineno: warning: theory class \`$1' isn't fully-qualified (e.g., ::CVC4::theory::foo)" >&2
80 elif ! expr "$2" : '\(::CVC4::theory::*\)' >/dev
/null
; then
81 echo "$kf:$lineno: warning: theory class not under ::CVC4::theory namespace" >&2
85 metakind_includes
="${metakind_includes}
86 // #include \"theory/$b/$2\""
90 # alternate ID name T header
92 lineno
=${BASH_LINENO[0]}
95 echo "$kf:$lineno: error: multiple theories defined in one file !?" >&2
106 theory_includes
="${theory_includes}#include \"$theory_header\"
110 function properties
{
112 lineno
=${BASH_LINENO[0]}
118 lineno
=${BASH_LINENO[0]}
123 function enumerator
{
124 # enumerator KIND enumerator-class header
125 lineno
=${BASH_LINENO[0]}
129 function typechecker
{
131 lineno
=${BASH_LINENO[0]}
136 # typerule OPERATOR typechecking-class
137 lineno
=${BASH_LINENO[0]}
142 # construle OPERATOR isconst-checking-class
143 lineno
=${BASH_LINENO[0]}
148 # rewriter class header
149 lineno
=${BASH_LINENO[0]}
154 # sort TYPE cardinality [well-founded ground-term header | not-well-founded] ["comment"]
155 lineno
=${BASH_LINENO[0]}
159 function cardinality
{
160 # cardinality TYPE cardinality-computer [header]
161 lineno
=${BASH_LINENO[0]}
165 function well-founded
{
166 # well-founded TYPE wellfoundedness-computer [header]
167 lineno
=${BASH_LINENO[0]}
172 # variable K ["comment"]
174 lineno
=${BASH_LINENO[0]}
177 register_metakind VARIABLE
"$1" 0
181 # operator K #children ["comment"]
183 lineno
=${BASH_LINENO[0]}
186 register_metakind OPERATOR
"$1" "$2"
189 function parameterized
{
190 # parameterized K1 K2 #children ["comment"]
192 lineno
=${BASH_LINENO[0]}
195 register_metakind PARAMETERIZED
"$1" "$3"
196 if ! expr "$2" : '\[.*\]' &>/dev
/null
; then
197 registerOperatorToKind
"$1" "$2"
202 # constant K T Hasher header ["comment"]
204 lineno
=${BASH_LINENO[0]}
208 if ! expr "$2" : '\(::*\)' >/dev
/null
; then
209 if ! primitive_type
"$2"; then
210 # if there's an embedded space, we're probably doing something
211 # tricky to specify the CONST payload, like "int const*"; in any
212 # case, this warning gives too many false positives, so disable it
213 if ! expr "$2" : '..* ..*' >/dev
/null
; then
214 echo "$kf:$lineno: warning: constant $1 class \`$2' isn't fully-qualified (e.g., ::CVC4::Rational)" >&2
218 if ! expr "$3" : '\(::*\)' >/dev
/null
; then
219 echo "$kf:$lineno: warning: constant $1 hasher \`$3' isn't fully-qualified (e.g., ::CVC4::RationalHashFunction)" >&2
222 # Avoid including the same header multiple times
223 if [ -n "$4" ] && [[ "${metakind_includes}" != *"#include \"$4\""* ]]; then
224 metakind_includes
="${metakind_includes}
227 register_metakind CONSTANT
"$1" 0
228 metakind_getConst_decls
="${metakind_getConst_decls}
230 $2 const& NodeValue::getConst< $2 >() const;
232 metakind_constantMaps_decls
="${metakind_constantMaps_decls}
234 struct ConstantMap< $2 > {
235 // typedef $theory_class OwningTheory;
236 enum { kind = ::CVC4::kind::$1 };
237 };/* ConstantMap< $2 > */
240 struct ConstantMapReverse< ::CVC4::kind::$1 > {
242 };/* ConstantMapReverse< ::CVC4::kind::$1 > */
244 metakind_constantMaps
="${metakind_constantMaps}
245 // The reinterpret_cast of d_children to \"$2 const*\"
246 // flags a \"strict aliasing\" warning; it's okay, because we never access
247 // the embedded constant as a NodeValue* child, and never access an embedded
248 // NodeValue* child as a constant.
249 #pragma GCC diagnostic ignored \"-Wstrict-aliasing\"
252 $2 const& NodeValue::getConst< $2 >() const {
253 AssertArgument(getKind() == ::CVC4::kind::$1, *this,
254 \"Improper kind for getConst<$2>()\");
255 // To support non-inlined CONSTANT-kinded NodeValues (those that are
256 // \"constructed\" when initially checking them against the NodeManager
257 // pool), we must check d_nchildren here.
258 return d_nchildren == 0
259 ? *reinterpret_cast< $2 const* >(d_children)
260 : *reinterpret_cast< $2 const* >(d_children[0]);
263 // re-enable the warning
264 #pragma GCC diagnostic warning \"-Wstrict-aliasing\"
267 metakind_compares
="${metakind_compares}
269 return NodeValueConstCompare< kind::$1, pool >::compare(nv1, nv2);
271 metakind_constHashes
="${metakind_constHashes}
273 return $3()(nv->getConst< $2 >());
275 metakind_constPrinters
="${metakind_constPrinters}
277 out << nv->getConst< $2 >();
280 cname
=`echo "$2" | awk 'BEGIN {FS="::"} {print$NF}'`
281 metakind_constDeleters
="${metakind_constDeleters}
283 std::allocator< $2 >().destroy(reinterpret_cast< $2* >(nv->d_children));
288 function nullaryoperator
{
289 # nullaryoperator K ["comment"]
291 lineno
=${BASH_LINENO[0]}
294 register_metakind NULLARY_OPERATOR
"$1" 0
297 function registerOperatorToKind
{
300 metakind_operatorKinds
="${metakind_operatorKinds}
301 case kind::$applyKind: return kind::$operatorKind;";
304 function register_metakind
{
309 metakind_kinds
="${metakind_kinds} metakind::$mk, /* $k */
312 # figure out the range given by $nc
313 if expr "$nc" : '[0-9][0-9]*$' >/dev
/null
; then
316 elif expr "$nc" : '[0-9][0-9]*:$' >/dev
/null
; then
317 let `echo "$nc" | awk 'BEGIN{FS=":"}{print"lb="$1}'`
318 ub
="expr::NodeValue::MAX_CHILDREN"
319 elif expr "$nc" : '[0-9][0-9]*:[0-9][0-9]*$' >/dev
/null
; then
320 let `echo "$nc" | awk 'BEGIN{FS=":"}{print"lb="$1" ub="$2}'`
321 if [ $ub -lt $lb ]; then
322 echo "$kf:$lineno: error in range \`$nc': LB < UB (in definition of $k)" >&2
326 echo "$kf:$lineno: can't parse range \`$nc' in definition of $k" >&2
330 metakind_lbchildren
="${metakind_lbchildren}
332 metakind_ubchildren
="${metakind_ubchildren}
336 # Returns 0 if arg is a primitive C++ type, or a pointer to same; 1
337 # otherwise. Really all this does is check whether we should issue a
338 # "not fully qualified" warning or not.
339 function primitive_type
{
340 strip
=`expr "$1" : ' *\(.*\)\* *'`
341 if [ -n "$strip" ]; then
342 primitive_type
"$strip" >&2
347 bool|int|size_t|long|void|char|float|double
) return 0;;
352 function check_theory_seen
{
353 if $seen_endtheory; then
354 echo "$kf:$lineno: error: command after \"endtheory\" declaration (endtheory has to be last)" >&2
357 if ! $seen_theory; then
358 echo "$kf:$lineno: error: no \"theory\" declaration found (it has to be first)" >&2
363 function check_builtin_theory_seen
{
364 if ! $seen_theory_builtin; then
365 echo "$me: warning: no declaration for the builtin theory found" >&2
369 while [ $# -gt 0 ]; do
373 b
=$
(basename $
(dirname "$kf"))
374 metakind_kinds
="${metakind_kinds}
377 metakind_operatorKinds
="${metakind_operatorKinds}
381 if ! $seen_theory; then
382 echo "$kf: error: no theory content found in file!" >&2
385 if ! $seen_endtheory; then
386 echo "$kf:$lineno: error: no \"endtheory\" declaration found (it is required at the end)" >&2
391 check_builtin_theory_seen
395 text
=$
(cat "$template")
399 metakind_constantMaps \
400 metakind_constantMaps_decls \
401 metakind_getConst_decls \
403 metakind_constHashes \
404 metakind_constPrinters \
405 metakind_constDeleters \
406 metakind_ubchildren \
407 metakind_lbchildren \
408 metakind_operatorKinds \
411 eval text
="\${text//\\\$\\{$var\\}/\${$var}}"
413 error
=`expr "$text" : '.*\${\([^}]*\)}.*'`
414 if [ -n "$error" ]; then
415 echo "$template:0: error: undefined replacement \${$error}" >&2