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 // Implementation for class LoopSymbol.
25 //
26
27 // utility stuff
28 #include "macros.hh"
29 #include "vector.hh"
30 //#include "stringTable.hh"
31
32 // forward declarations
33 #include "interface.hh"
34 #include "core.hh"
35 #include "freeTheory.hh"
36 #include "AU_Theory.hh"
37 #include "NA_Theory.hh"
38 #include "mixfix.hh"
39
40 // interface class definitions
41 #include "symbol.hh"
42 #include "dagNode.hh"
43 #include "rawDagArgumentIterator.hh"
44 #include "rawArgumentIterator.hh"
45 #include "term.hh"
46
47 // core class definitions
48 #include "dagArgumentIterator.hh"
49 #include "argumentIterator.hh"
50 #include "substitution.hh"
51 #include "rewritingContext.hh"
52 #include "symbolMap.hh"
53
54 // free theory class definitions
55 #include "freeDagNode.hh"
56
57 // AU theory class definitions
58 #include "AU_Symbol.hh"
59 #include "AU_DagNode.hh"
60
61 // built in class definitions
62 #include "bindingMacros.hh"
63
64 // front end class definitions
65 #include "token.hh"
66 #include "quotedIdentifierSymbol.hh"
67 #include "quotedIdentifierDagNode.hh"
68 #include "loopSymbol.hh"
69 #include "token.hh"
70
71 const Vector<int> LoopSymbol::eagerStrategy;
72
LoopSymbol(int id)73 LoopSymbol::LoopSymbol(int id)
74 : FreeSymbol(id, 3, eagerStrategy)
75 {
76 qidSymbol = 0;
77 nilQidListSymbol = 0;
78 qidListSymbol = 0;
79 }
80
81 bool
attachData(const Vector<Sort * > & opDeclaration,const char * purpose,const Vector<const char * > & data)82 LoopSymbol::attachData(const Vector<Sort*>& opDeclaration,
83 const char* purpose,
84 const Vector<const char*>& data)
85 {
86 if (strcmp(purpose, "LoopSymbol") == 0)
87 return data.length() == 0;
88 return FreeSymbol::attachData(opDeclaration, purpose, data);
89 }
90
91 bool
attachSymbol(const char * purpose,Symbol * symbol)92 LoopSymbol::attachSymbol(const char* purpose, Symbol* symbol)
93 {
94 BIND_SYMBOL(purpose, symbol, qidSymbol, QuotedIdentifierSymbol*);
95 BIND_SYMBOL(purpose, symbol, nilQidListSymbol, Symbol*);
96 BIND_SYMBOL(purpose, symbol, qidListSymbol, AU_Symbol*);
97 return FreeSymbol::attachSymbol(purpose, symbol);
98 }
99
100 void
copyAttachments(Symbol * original,SymbolMap * map)101 LoopSymbol::copyAttachments(Symbol* original, SymbolMap* map)
102 {
103 LoopSymbol* orig = safeCast(LoopSymbol*, original);
104 COPY_SYMBOL(orig, qidSymbol, map, QuotedIdentifierSymbol*);
105 COPY_SYMBOL(orig, nilQidListSymbol, map, Symbol*);
106 COPY_SYMBOL(orig, qidListSymbol, map, AU_Symbol*);
107 FreeSymbol::copyAttachments(original, map);
108 }
109
110 void
getDataAttachments(const Vector<Sort * > & opDeclaration,Vector<const char * > & purposes,Vector<Vector<const char * >> & data)111 LoopSymbol::getDataAttachments(const Vector<Sort*>& opDeclaration,
112 Vector<const char*>& purposes,
113 Vector<Vector<const char*> >& data)
114 {
115 APPEND_DATA(purposes, data, LoopSymbol);
116 FreeSymbol::getDataAttachments(opDeclaration, purposes, data);
117 }
118
119 void
getSymbolAttachments(Vector<const char * > & purposes,Vector<Symbol * > & symbols)120 LoopSymbol::getSymbolAttachments(Vector<const char*>& purposes,
121 Vector<Symbol*>& symbols)
122 {
123 APPEND_SYMBOL(purposes, symbols, qidSymbol);
124 APPEND_SYMBOL(purposes, symbols, nilQidListSymbol);
125 APPEND_SYMBOL(purposes, symbols, qidListSymbol);
126 FreeSymbol::getSymbolAttachments(purposes, symbols);
127 }
128
129 DagNode*
injectInput(DagNode * loopNode,const Vector<Token> & bubble)130 LoopSymbol::injectInput(DagNode* loopNode, const Vector<Token>& bubble)
131 {
132 static Vector<DagNode*> args(3);
133
134 FreeDagNode* f = static_cast<FreeDagNode*>(loopNode);
135 args[0] = createQidList(bubble);
136 args[1] = f->getArgument(1);
137 args[2] = new FreeDagNode(nilQidListSymbol);
138 return makeDagNode(args);
139 }
140
141 DagNode*
createQidList(const Vector<Token> & ids)142 LoopSymbol::createQidList(const Vector<Token>& ids)
143 {
144 int nrIds = ids.length();
145 if (nrIds == 0)
146 return new FreeDagNode(nilQidListSymbol);
147 if (nrIds == 1)
148 return new QuotedIdentifierDagNode(qidSymbol, ids[0].code());
149 Vector<DagNode*> args(nrIds);
150 for (int i = 0; i < nrIds; i++)
151 args[i] = new QuotedIdentifierDagNode(qidSymbol, Token::backQuoteSpecials(ids[i].code()));
152 return qidListSymbol->makeDagNode(args);
153 }
154
155 bool
extractOutput(DagNode * loopNode,Vector<int> & bubble)156 LoopSymbol::extractOutput(DagNode* loopNode, Vector<int>& bubble)
157 {
158 FreeDagNode* f = static_cast<FreeDagNode*>(loopNode);
159 return extractQidList(f->getArgument(2), bubble);
160 }
161
162 bool
extractQid(DagNode * metaQid,int & id)163 LoopSymbol::extractQid(DagNode* metaQid, int& id)
164 {
165 if (metaQid->symbol() == qidSymbol)
166 {
167 id =
168 Token::unBackQuoteSpecials(static_cast<QuotedIdentifierDagNode*>(metaQid)->getIdIndex());
169 return true;
170 }
171 return false;
172 }
173
174 bool
extractQidList(DagNode * metaQidList,Vector<int> & ids)175 LoopSymbol::extractQidList(DagNode* metaQidList, Vector<int>& ids)
176 {
177 ids.contractTo(0);
178 Symbol* mq = metaQidList->symbol();
179 int id;
180 if (mq == qidListSymbol)
181 {
182 for (DagArgumentIterator i(metaQidList); i.valid(); i.next())
183 {
184 if (!extractQid(i.argument(), id))
185 return false;
186 ids.append(id);
187 }
188 }
189 else if (extractQid(metaQidList, id))
190 ids.append(id);
191 else if (mq != nilQidListSymbol)
192 return false;
193 return true;
194 }
195