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