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

Revision 4002, 9.9 KB (checked in by sukyoungryu, 4 months ago)

[copyright] Fixed copyright notices.

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