1 /* 2 3 This file is part of the Maude 2 interpreter. 4 5 Copyright 1997-2003 SRI International, Menlo Park, CA 94025, USA. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 20 21 */ 22 23 // 24 // Macros for binding stuff in builtins. 25 // 26 #ifndef _bindingMacros_hh_ 27 #define _bindingMacros_hh_ 28 29 // 30 // This needs to be a macro in order to produce constant expressions. 31 // 32 #define CODE(c1, c2) ((c1) + ((c2) << 8)) 33 #define CODE3(c1, c2, c3) ((c1) + ((c2) << 8) + ((c3) << 16)) 34 35 #define BIND_OP(purpose, className, op, data) \ 36 if (strcmp(purpose, #className) == 0) \ 37 { \ 38 if (data.length() == 1) \ 39 { \ 40 const char* opName = (data)[0]; \ 41 if (opName[0] != '\0') \ 42 { \ 43 int t = CODE(opName[0], opName[1]); \ 44 if (op == NONE) \ 45 { \ 46 op = t; \ 47 return true; \ 48 } \ 49 if (op == t) \ 50 return true; \ 51 } \ 52 } \ 53 return false; \ 54 } 55 56 #define BIND_OP3(purpose, className, op, data) \ 57 if (strcmp(purpose, #className) == 0) \ 58 { \ 59 if (data.length() == 1) \ 60 { \ 61 const char* opName = (data)[0]; \ 62 if (opName[0] != '\0') \ 63 { \ 64 int t = (opName[1] == '\0') ? CODE(opName[0], opName[1]) : CODE3(opName[0], opName[1], opName[2]); \ 65 if (op == NONE) \ 66 { \ 67 op = t; \ 68 return true; \ 69 } \ 70 if (op == t) \ 71 return true; \ 72 } \ 73 } \ 74 return false; \ 75 } 76 77 #define NULL_DATA(purpose, className, data) \ 78 if (strcmp(purpose, #className) == 0) \ 79 { \ 80 return data.length() == 0; \ 81 } 82 83 #define BIND_SYMBOL(purpose, symbol, name, type) \ 84 if (strcmp(purpose, #name) == 0) \ 85 { \ 86 if (name != 0) \ 87 return name == symbol; \ 88 name = dynamic_cast<type>(symbol); \ 89 return name != 0; \ 90 } 91 92 #define BIND_TERM(purpose, term, name) \ 93 if (strcmp(purpose, #name) == 0) \ 94 { \ 95 bool r = true; \ 96 if (Term* t = name.getTerm()) \ 97 { \ 98 r = term->equal(t); \ 99 term->deepSelfDestruct(); \ 100 } \ 101 else \ 102 name.setTerm(term); \ 103 return r; \ 104 } 105 106 #define PREPARE_TERM(name) \ 107 if (name.getTerm() != 0) \ 108 { \ 109 (void) name.normalize(); \ 110 name.prepare(); \ 111 } 112 113 #define COPY_SYMBOL(original, name, mapping, type) \ 114 if (name == 0) \ 115 { \ 116 if (type s = original->name) \ 117 name = (mapping == 0) ? s : safeCast(type, mapping->translate(s)); \ 118 } 119 120 #define COPY_TERM(original, name, mapping) \ 121 if (name.getTerm() == 0) \ 122 { \ 123 if (Term* t = original->name.getTerm()) \ 124 name.setTerm(t->deepCopy(mapping)); \ 125 } 126 127 #define APPEND_DATA(purposes, data, name) \ 128 { \ 129 int n = purposes.length(); \ 130 purposes.resize(n + 1); \ 131 purposes[n] = #name; \ 132 data.resize(n + 1); \ 133 } 134 135 #define APPEND_SYMBOL(purposes, symbols, name) \ 136 if (name != 0) \ 137 { \ 138 purposes.append(#name); \ 139 symbols.append(name); \ 140 } 141 142 #define APPEND_TERM(purposes, terms, name) \ 143 if (Term* t = name.getTerm()) \ 144 { \ 145 purposes.append(#name); \ 146 terms.append(t); \ 147 } 148 149 #define CODE_CASE(d, c1, c2, s) \ 150 case CODE(c1, c2): \ 151 { \ 152 d = s; \ 153 break; \ 154 } 155 156 #define CODE_CASE3(d, c1, c2, c3, s) \ 157 case CODE3(c1, c2, c3): \ 158 { \ 159 d = s; \ 160 break; \ 161 } 162 163 #endif 164