root/trunk/ProjectFortress/src/com/sun/fortress/interpreter/evaluator/values/SingleFcn.java

Revision 2621, 10.9 kB (checked in by sukyoungryu, 2 months ago)

[refactoring] Made the where clause fields of some AST nodes optional so that we can get rid of where clauses with bogus spans.

Line 
1 /*******************************************************************************
2     Copyright 2008 Sun Microsystems, Inc.,
3     4150 Network Circle, Santa Clara, California 95054, U.S.A.
4     All rights reserved.
5
6     U.S. Government Rights - Commercial software.
7     Government users are subject to the Sun Microsystems, Inc. standard
8     license agreement and applicable provisions of the FAR and its supplements.
9
10     Use is subject to license terms.
11
12     This distribution may include materials developed by third parties.
13
14     Sun, Sun Microsystems, the Sun logo and Java are trademarks or registered
15     trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
16  ******************************************************************************/
17
18 package com.sun.fortress.interpreter.evaluator.values;
19
20 import static com.sun.fortress.exceptions.InterpreterBug.bug;
21 import static com.sun.fortress.exceptions.ProgramError.errorMsg;
22
23 import java.util.ArrayList;
24 import java.util.List;
25 import edu.rice.cs.plt.tuple.Option;
26
27 import com.sun.fortress.exceptions.FortressException;
28 import com.sun.fortress.interpreter.evaluator.Environment;
29 import com.sun.fortress.interpreter.evaluator.EvalType;
30 import com.sun.fortress.interpreter.evaluator.types.FType;
31 import com.sun.fortress.interpreter.evaluator.types.FTypeTuple;
32 import com.sun.fortress.interpreter.evaluator.types.SymbolicBool;
33 import com.sun.fortress.interpreter.evaluator.types.SymbolicInstantiatedType;
34 import com.sun.fortress.interpreter.evaluator.types.SymbolicNat;
35 import com.sun.fortress.interpreter.evaluator.types.SymbolicOprType;
36 import com.sun.fortress.nodes.BaseType;
37 import com.sun.fortress.nodes.BoolParam;
38 import com.sun.fortress.nodes.IntParam;
39 import com.sun.fortress.nodes.NatParam;
40 import com.sun.fortress.nodes.OpParam;
41 import com.sun.fortress.nodes.StaticParam;
42 import com.sun.fortress.nodes.TypeAlias;
43 import com.sun.fortress.nodes.TypeParam;
44 import com.sun.fortress.nodes.WhereClause;
45 import com.sun.fortress.nodes.WhereConstraint;
46 import com.sun.fortress.nodes.WhereExtends;
47 import com.sun.fortress.nodes_util.Applicable;
48 import com.sun.fortress.nodes_util.NodeUtil;
49 import com.sun.fortress.useful.HasAt;
50 import com.sun.fortress.useful.Hasher;
51 import com.sun.fortress.useful.MagicNumbers;
52 import com.sun.fortress.useful.NI;
53 import com.sun.fortress.useful.Useful;
54
55 public abstract class SingleFcn extends Fcn implements HasAt {
56
57     public SingleFcn(Environment within) {
58         super(within);
59     }
60
61     abstract public String  at();
62     abstract public List<FType> getDomain();
63     abstract public FType getRange();
64     public boolean isOverride() { return false; }
65
66     /**
67      * For now, prefer to unwrap tuples because that avoid creating
68      * new memo entries for tuple types.
69      * @return
70      */
71     public List<FType> getNormalizedDomain() {
72         List<FType> d = getDomain();
73         if (d.size() == 1) {
74             FType t = d.get(0);
75             if (t  instanceof FTypeTuple) {
76               d = ((FTypeTuple) t).getTypes();
77             }
78         }
79         return d;
80
81     }
82
83     /**
84      * This is just like getNormalizedDomain, except that the method version
85      * of functional methods appends a "nat" Type indicating the position of
86      * the self parameter.
87      * @return
88      */
89     public List<FType> getNormalizedDomainForTables() {
90         return getNormalizedDomain();
91     }
92
93     public List<FValue> fixupArgCount(List<FValue> args) {
94         System.out.println("Naive fixupArgCount "+this+
95                            "("+this.getClass()+")"+
96                            " of "+Useful.listInParens(args));
97         int dsz = getDomain().size();
98         if (args.size() == dsz) return args;
99         return null;
100     }
101
102      // NOTE: I believe it is ok for functions to use object identity for
103     // equals and hashCode().
104
105     static class SignatureEquivalence extends Hasher<SingleFcn> {
106         @Override
107         public long hash(SingleFcn x) {
108             long a = (long) x.asMethodName().hashCode() * MagicNumbers.s;
109             long b =  (long) x.getNormalizedDomainForTables().hashCode() * MagicNumbers.l;
110             // System.err.println("Hash of " + x + " yields " + a + " and " + b);
111
112             return a + b;
113         }
114
115         @Override
116         public boolean equiv(SingleFcn x, SingleFcn y) {
117             List<FType> dx = x.getNormalizedDomainForTables();
118             List<FType> dy = y.getNormalizedDomainForTables();
119             if (dx.size() != dy.size())
120                 return false;
121             if (! x.asMethodName().equals(y.asMethodName()))
122                 return false;
123             for (int i = 0; i < dx.size(); i++) {
124                 if (! dx.get(i).equals(dy.get(i)))
125                     return false;
126             }
127             return true;
128         }
129
130     }
131
132
133     /**
134      * Given a (generic) applicable, an environment for type
135      * evaluation. and a location to which problems can be
136      * attached, create the ordered list of symbolic instantiation
137      * arguments consistent with the type parameters and where
138      * clauses.  The symbolic types so created will be tied to
139      * a newly generated environment so that they do not contaminate
140      * any "real" environments.
141      *
142      * The instantiated generics can be used to allow checks on
143      * overloading.
144      *
145      * @throws Error
146      */
147     static public List<FType> createSymbolicInstantiation(Environment bte, Applicable ap, HasAt location) throws Error {
148         List<StaticParam> tpl = ap.getStaticParams();
149         Option<WhereClause> wcl = ap.getWhere();
150
151         // The (possibly multiple and interrelated) symbolic
152         // types must be created in an environment, but we don't
153         // want to contaminate a "real" environment with these names.
154         // We also don't want "crosstalk" between type parameters
155         // to different overloaded things.
156         Environment ge = bte.extendAt(location);
157
158         // Note that we must arrange for the symbolic things
159         // to meet the constraints required by the object.
160         List<FType> instantiationTypes;
161         try {
162             instantiationTypes = createSymbolicInstantiation(tpl, wcl, ge);
163         } catch (FortressException e) {
164             e.setContext(location,ge);
165             throw e;
166         }
167         return instantiationTypes;
168     }
169
170     static public List<FType> createSymbolicInstantiation(Environment bte,
171                                                           List<StaticParam> tpl,
172                                                           Option<WhereClause> wcl,
173                                                           HasAt location) throws Error {
174         return createSymbolicInstantiation(tpl, wcl, bte.extendAt(location));
175     }
176     /**
177      * @param tpl
178      * @param wcl
179      * @param ge The generic environment that is being populated by this instantiation.
180      * @throws Error
181      */
182     static private List<FType> createSymbolicInstantiation(List<StaticParam> tpl, Option<WhereClause> wcl, Environment ge) throws Error {
183         ArrayList<FType> a = new ArrayList<FType>();
184         for (StaticParam tp: tpl) {
185             String name = NodeUtil.getName(tp);
186             FType t;
187             if (tp instanceof TypeParam) {
188                 t = new SymbolicInstantiatedType(name, ge, tp);
189             } else if (tp instanceof NatParam || tp instanceof IntParam) {
190                 t = new SymbolicNat(name);
191             } else if (tp instanceof BoolParam) {
192                 t = new SymbolicBool(name);
193             } else if (tp instanceof OpParam) {
194                 OpParam op = (OpParam) tp;
195                 t = new SymbolicOprType(name, ge, op);
196             } else {
197                 return bug(tp, errorMsg("Unimplemented symbolic StaticParam ", tp));
198             }
199             ge.putType(name, t);
200             a.add(t);
201         }
202
203         // Expect that where clauses will add names and constraints.
204         if ( wcl.isSome() ) {
205             for (WhereConstraint wc : wcl.unwrap().getConstraints()) {
206                 if (wc instanceof TypeAlias) {
207                     TypeAlias ta = (TypeAlias) wc;
208                     NI.nyi("Where clauses - type alias");
209                 } else if (wc instanceof WhereExtends) {
210                     WhereExtends we = (WhereExtends) wc;
211                     String we_name = we.getName().getText();
212                     // List<Type> we_supers = we.getSupers();
213                     if (ge.getTypeNull(we_name) == null) {
214                         // Add name
215                         SymbolicInstantiatedType st = new SymbolicInstantiatedType(we_name, ge, we);
216                         ge.putType(we_name, st);
217                     }
218                 }
219             }
220         }
221
222         EvalType eval_type = new EvalType(ge);
223
224         // Process constraints
225         for (StaticParam tp: tpl) {
226             String name = NodeUtil.getName(tp);
227             if (tp instanceof TypeParam) {
228                 TypeParam stp = (TypeParam) tp;
229                 String stp_name = NodeUtil.getName(stp);
230                 SymbolicInstantiatedType st = (SymbolicInstantiatedType) ge.getType(stp_name);
231                 List<BaseType> oext = stp.getExtendsClause();
232                 // pass null, no excludes here.
233                 // Note no need to replace environment, these
234                 // are precreated in a fresh environment.
235                 st.setExtendsAndExcludes(eval_type.getFTypeListFromList(oext), null);
236             } else if (tp instanceof NatParam || tp instanceof IntParam ||
237                        tp instanceof OpParam || tp instanceof BoolParam) {
238                 // No constraint handling right now
239             } else {
240                 return bug(tp, errorMsg("Unexpected StaticParam ", tp));
241             }
242         }
243
244         // Expect that where clauses will add names and constraints.
245         if ( wcl.isSome() ) {
246             for (WhereConstraint wc : wcl.unwrap().getConstraints()) {
247                 if (wc instanceof TypeAlias) {
248                     NI.nyi("Where clauses - type alias");
249                     TypeAlias ta = (TypeAlias) wc;
250                 } else if (wc instanceof WhereExtends) {
251                     WhereExtends we = (WhereExtends) wc;
252                     String we_name = we.getName().getText();
253                     List<BaseType> we_supers = we.getSupers();
254                     SymbolicInstantiatedType st = (SymbolicInstantiatedType) ge.getType(we_name);
255                     st.addExtends(eval_type.getFTypeListFromList(we_supers));
256                 }
257             }
258         }
259
260         return a;
261     }
262
263     public static Hasher<SingleFcn> signatureEquivalence = new SignatureEquivalence();
264
265     static class NameEquivalence extends Hasher<SingleFcn> {
266         @Override
267         public long hash(SingleFcn x) {
268             long a = (long) x.getFnName().hashCode() * MagicNumbers.N;
269              return a;
270         }
271
272         @Override
273         public boolean equiv(SingleFcn x, SingleFcn y) {
274             return x.getFnName().equals(y.getFnName());
275         }
276
277     }
278
279     public static Hasher<SingleFcn> nameEquivalence = new NameEquivalence();
280
281
282 }
Note: See TracBrowser for help on using the browser.