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