4 # Morgan Deters <mdeters@cs.nyu.edu> for cvc5
5 # Copyright (c) 2010-2013 The cvc5 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 /******************************************************************************
24 * This file is part of the cvc5 project.
26 * Copyright (c) $copyright by the authors listed in the file AUTHORS
27 * in the top-level source directory and their institutional affiliations.
28 * All rights reserved. See the file COPYING in the top-level source
29 * directory for licensing information.
30 * ****************************************************************************
32 * This header file was automatically generated by:
36 * for the cvc5 project.
48 metakind_constantMaps
=
51 metakind_constPrinters
=
52 metakind_constDeleters
=
55 metakind_operatorKinds
=
58 seen_theory_builtin
=false
66 for e
in "${arr[@]}"; do
67 [[ "$e" == "$elem" ]] && return 0
75 lineno
=${BASH_LINENO[0]}
78 echo "$kf:$lineno: error: multiple theories defined in one file !?" >&2
82 # this script doesn't care about the theory class information, but
83 # makes does make sure it's there
85 if [ "$1" = THEORY_BUILTIN
]; then
86 if $seen_theory_builtin; then
87 echo "$kf:$lineno: error: \"builtin\" theory redefined" >&2
90 seen_theory_builtin
=true
91 elif [ -z "$1" -o -z "$2" -o -z "$3" ]; then
92 echo "$kf:$lineno: error: \"theory\" directive missing class or header argument" >&2
94 elif ! expr "$2" : '\(::*\)' >/dev
/null
; then
95 echo "$kf:$lineno: warning: theory class \`$1' isn't fully-qualified (e.g., ::cvc5::theory::foo)" >&2
96 elif ! expr "$2" : '\(::cvc5::theory::*\)' >/dev
/null
; then
97 echo "$kf:$lineno: warning: theory class not under ::cvc5::theory namespace" >&2
101 metakind_includes
="${metakind_includes}
102 // #include \"theory/$b/$2\""
106 # alternate ID name T header
108 lineno
=${BASH_LINENO[0]}
110 if $seen_theory; then
111 echo "$kf:$lineno: error: multiple theories defined in one file !?" >&2
122 theory_includes
="${theory_includes}#include \"$theory_header\"
126 function properties
{
128 lineno
=${BASH_LINENO[0]}
134 lineno
=${BASH_LINENO[0]}
139 function enumerator
{
140 # enumerator KIND enumerator-class header
141 lineno
=${BASH_LINENO[0]}
145 function typechecker
{
147 lineno
=${BASH_LINENO[0]}
152 # typerule OPERATOR typechecking-class
153 lineno
=${BASH_LINENO[0]}
158 # construle OPERATOR isconst-checking-class
159 lineno
=${BASH_LINENO[0]}
164 # rewriter class header
165 lineno
=${BASH_LINENO[0]}
170 # sort TYPE cardinality [well-founded ground-term header | not-well-founded] ["comment"]
171 lineno
=${BASH_LINENO[0]}
175 function cardinality
{
176 # cardinality TYPE cardinality-computer [header]
177 lineno
=${BASH_LINENO[0]}
181 function well-founded
{
182 # well-founded TYPE wellfoundedness-computer [header]
183 lineno
=${BASH_LINENO[0]}
188 # variable K ["comment"]
190 lineno
=${BASH_LINENO[0]}
193 register_metakind VARIABLE
"$1" 0
197 # operator K #children ["comment"]
199 lineno
=${BASH_LINENO[0]}
202 register_metakind OPERATOR
"$1" "$2"
205 function parameterized
{
206 # parameterized K1 K2 #children ["comment"]
208 lineno
=${BASH_LINENO[0]}
211 register_metakind PARAMETERIZED
"$1" "$3"
212 if ! expr "$2" : '\[.*\]' &>/dev
/null
; then
213 registerOperatorToKind
"$1" "$2"
218 # constant K F T Hasher header ["comment"]
220 lineno
=${BASH_LINENO[0]}
224 if ! expr "$4" : '\(::*\)' >/dev
/null
; then
225 echo "$kf:$lineno: warning: constant $1 hasher \`$4' isn't fully-qualified (e.g., ::cvc5::RationalHashFunction)" >&2
228 if [[ "$3" =~
'+'$
]]; then
229 # Remove last character
237 if contains
"${class}" "${payloads_seen[@]}"; then
241 payloads_seen
=(${payloads_seen[@]} "${class}")
244 if [[ "$2" != "skip" ]]; then
245 metakind_fwd_decls
="${metakind_fwd_decls}
249 # Avoid including the same header multiple times
250 if [ -n "$5" ] && [[ "${metakind_includes}" != *"#include \"$5\""* ]]; then
251 metakind_includes
="${metakind_includes}
254 register_metakind CONSTANT
"$1" 0
256 if [[ "${payload_seen}" != true
]]; then
257 metakind_getConst_decls
="${metakind_getConst_decls}
259 ${class} const& NodeValue::getConst< ${class} >() const;
262 metakind_constantMaps
="${metakind_constantMaps}
263 // The reinterpret_cast of d_children to \"${class} const*\"
264 // flags a \"strict aliasing\" warning; it's okay, because we never access
265 // the embedded constant as a NodeValue* child, and never access an embedded
266 // NodeValue* child as a constant.
267 #pragma GCC diagnostic ignored \"-Wstrict-aliasing\"
270 ${class} const& NodeValue::getConst< ${class} >() const {
271 AssertArgument(getKind() == ::cvc5::kind::$1, *this,
272 \"Improper kind for getConst<${class}>()\");
273 // To support non-inlined CONSTANT-kinded NodeValues (those that are
274 // \"constructed\" when initially checking them against the NodeManager
275 // pool), we must check d_nchildren here.
276 return d_nchildren == 0
277 ? *reinterpret_cast< ${class} const* >(d_children)
278 : *reinterpret_cast< ${class} const* >(d_children[0]);
281 // re-enable the warning
282 #pragma GCC diagnostic warning \"-Wstrict-aliasing\"
287 if [ "${skip_const_map}" != true
]; then
288 metakind_constantMaps_decls
="${metakind_constantMaps_decls}
290 struct ConstantMap< ${class} > {
291 static constexpr Kind kind = ::cvc5::kind::$1;
292 };/* ConstantMap< ${class} > */
296 metakind_constantMaps_decls
="${metakind_constantMaps_decls}
298 struct ConstantMapReverse< ::cvc5::kind::$1 > {
300 };/* ConstantMapReverse< ::cvc5::kind::$1 > */
303 metakind_compares
="${metakind_compares}
305 return NodeValueConstCompare< kind::$1, pool >::compare(nv1, nv2);
307 metakind_constHashes
="${metakind_constHashes}
309 return $4()(nv->getConst< ${class} >());
311 metakind_constPrinters
="${metakind_constPrinters}
313 out << nv->getConst< ${class} >();
316 cname
=`echo "${class}" | awk 'BEGIN {FS="::"} {print$NF}'`
317 metakind_constDeleters
="${metakind_constDeleters}
319 std::destroy_at(reinterpret_cast< ${class}* >(nv->d_children));
324 function nullaryoperator
{
325 # nullaryoperator K ["comment"]
327 lineno
=${BASH_LINENO[0]}
330 register_metakind NULLARY_OPERATOR
"$1" 0
333 function registerOperatorToKind
{
336 metakind_operatorKinds
="${metakind_operatorKinds}
337 case kind::$applyKind: return kind::$operatorKind;";
340 function register_metakind
{
345 metakind_kinds
="${metakind_kinds} metakind::$mk, /* $k */
348 # figure out the range given by $nc
349 if expr "$nc" : '[0-9][0-9]*$' >/dev
/null
; then
352 elif expr "$nc" : '[0-9][0-9]*:$' >/dev
/null
; then
353 let `echo "$nc" | awk 'BEGIN{FS=":"}{print"lb="$1}'`
354 ub
="expr::NodeValue::MAX_CHILDREN"
355 elif expr "$nc" : '[0-9][0-9]*:[0-9][0-9]*$' >/dev
/null
; then
356 let `echo "$nc" | awk 'BEGIN{FS=":"}{print"lb="$1" ub="$2}'`
357 if [ $ub -lt $lb ]; then
358 echo "$kf:$lineno: error in range \`$nc': LB < UB (in definition of $k)" >&2
362 echo "$kf:$lineno: can't parse range \`$nc' in definition of $k" >&2
366 metakind_lbchildren
="${metakind_lbchildren}
368 metakind_ubchildren
="${metakind_ubchildren}
372 # Returns 0 if arg is a primitive C++ type, or a pointer to same; 1
373 # otherwise. Really all this does is check whether we should issue a
374 # "not fully qualified" warning or not.
375 function primitive_type
{
376 strip
=`expr "$1" : ' *\(.*\)\* *'`
377 if [ -n "$strip" ]; then
378 primitive_type
"$strip" >&2
383 bool|int|size_t|long|void|char|float|double
) return 0;;
388 function check_theory_seen
{
389 if $seen_endtheory; then
390 echo "$kf:$lineno: error: command after \"endtheory\" declaration (endtheory has to be last)" >&2
393 if ! $seen_theory; then
394 echo "$kf:$lineno: error: no \"theory\" declaration found (it has to be first)" >&2
399 function check_builtin_theory_seen
{
400 if ! $seen_theory_builtin; then
401 echo "$me: warning: no declaration for the builtin theory found" >&2
405 while [ $# -gt 0 ]; do
409 b
=$
(basename $
(dirname "$kf"))
410 metakind_kinds
="${metakind_kinds}
413 metakind_operatorKinds
="${metakind_operatorKinds}
417 if ! $seen_theory; then
418 echo "$kf: error: no theory content found in file!" >&2
421 if ! $seen_endtheory; then
422 echo "$kf:$lineno: error: no \"endtheory\" declaration found (it is required at the end)" >&2
427 check_builtin_theory_seen
431 text
=$
(cat "$template")
436 metakind_constantMaps \
437 metakind_constantMaps_decls \
438 metakind_getConst_decls \
440 metakind_constHashes \
441 metakind_constPrinters \
442 metakind_constDeleters \
443 metakind_ubchildren \
444 metakind_lbchildren \
445 metakind_operatorKinds \
448 eval text
="\${text//\\\$\\{$var\\}/\${$var}}"
450 error
=`expr "$text" : '.*\${\([^}]*\)}.*'`
451 if [ -n "$error" ]; then
452 echo "$template:0: error: undefined replacement \${$error}" >&2