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

Revision 2072, 9.2 kB (checked in by dlsmith, 4 months ago)

Updated ASTGen with improved support for custom extensions. Related bug fixes in ASTGen exposed the fact that the Applicable node class doesn't belong in the Node hierarchy -- there are non-node instances that don't support visiting, for example -- so it was moved to nodes_util. Similarly, Fortress.ast was adjusted to be compatible with clarified semantics of ASTGen.

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.error;
22 import static com.sun.fortress.exceptions.ProgramError.errorMsg;
23
24 import java.util.ArrayList;
25 import java.util.Comparator;
26 import java.util.List;
27
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.FTypeTop;
32 import com.sun.fortress.nodes.DimParam;
33 import com.sun.fortress.nodes.FnAbsDeclOrDecl;
34 import com.sun.fortress.nodes.IdOrOpOrAnonymousName;
35 import com.sun.fortress.nodes.NatParam;
36 import com.sun.fortress.nodes.OpParam;
37 import com.sun.fortress.nodes.Param;
38 import com.sun.fortress.nodes.StaticArg;
39 import com.sun.fortress.nodes.StaticParam;
40 import com.sun.fortress.nodes.Type;
41 import com.sun.fortress.nodes.TypeParam;
42 import com.sun.fortress.nodes_util.Applicable;
43 import com.sun.fortress.nodes_util.NodeComparator;
44 import com.sun.fortress.useful.Factory1P;
45 import com.sun.fortress.useful.HasAt;
46 import com.sun.fortress.useful.Memo1P;
47 import com.sun.fortress.useful.Useful;
48
49 import edu.rice.cs.plt.tuple.Option;
50
51 public class GenericMethod extends MethodClosure implements
52         GenericFunctionOrMethod, Factory1P<List<FType>, MethodClosure, HasAt> {
53
54     /* (non-Javadoc)
55      * @see com.sun.fortress.interpreter.evaluator.values.FValue#getString()
56      */
57     @Override
58     public String getString() {
59         return s(getDef());
60     }
61
62     boolean isTraitMethod;
63
64     Environment evaluationEnv;
65
66     protected MethodClosure newClosure(Environment clenv, List<FType> args) {
67         MethodClosure cl;
68         if (!isTraitMethod) {
69             cl = new MethodClosureInstance(getEnv(), clenv, getDef(),
70                                            getDefiner(), args, this);
71         } else if (FType.anyAreSymbolic(args)) {
72             cl = new TraitMethodInstance(getEnv(), clenv, getDef(),
73                                                     getDefiner(), args, this);
74         } else {
75             // TODO Intention is that this is a plain old instantiation,
76             // however there are issues of capturing the evaluation
77             // environment that makes this not work quite right
78             // MethodClosureInstance ought to be MethodClosure, but
79             // isn't, yet.
80             cl = new TraitMethod(getEnv(), clenv, getDef(),
81                                             getDefiner(), args);
82         }
83         cl.finishInitializing();
84         return (MethodClosure) cl;
85     }
86
87     private class Factory implements
88             Factory1P<List<FType>, MethodClosure, HasAt> {
89
90         public MethodClosure make(List<FType> args, HasAt location) {
91             Environment clenv = evaluationEnv.extendAt(location); // TODO is this the right environment?
92             // It looks like it might be, or else good enough.  The disambiguating
93             // pass effectively hides all the names defined in the interior
94             // of the trait.
95             List<StaticParam> params = getDef().getStaticParams();
96             EvalType.bindGenericParameters(params, args, clenv, location,
97                     getDef());
98             clenv.bless();
99             return newClosure(clenv, args);
100         }
101     }
102
103     Memo1P<List<FType>, MethodClosure, HasAt> memo = new Memo1P<List<FType>, MethodClosure, HasAt>(
104             new Factory());
105
106     public MethodClosure make(List<FType> l, HasAt location) {
107         return memo.make(l, location);
108     }
109
110     public GenericMethod(Environment declarationEnv, Environment evaluationEnv,
111             FnAbsDeclOrDecl fndef, FType definer, boolean isTraitMethod) {
112         super(// new SpineEnv(declarationEnv, fndef), // Add an extra scope/layer for the generics.
113                 declarationEnv, // not yet, it changes overloading semantics.
114                 fndef, definer );
115         this.isTraitMethod = isTraitMethod;
116         this.evaluationEnv = evaluationEnv;
117     }
118
119     //    public GenericMethod(Environment declarationEnv, Environment traitEnv, FnAbsDeclOrDecl fndef, String selfName) {
120     //        super(declarationEnv, fndef, selfName);
121     //
122     //    }
123
124     public MethodClosure typeApply(List<StaticArg> args, Environment e, HasAt location) {
125         List<StaticParam> params = getDef().getStaticParams();
126
127         // Evaluate each of the args in e, inject into clenv.
128         if (args.size() != params.size()) {
129             error(location, e,
130                   "Generic instantiation (size) mismatch, expected "
131                   + Useful.listInParens(params)
132                   + " got " + Useful.listInParens(args));
133         }
134         EvalType et = new EvalType(e);
135         // TODO Can combine these two functions if we enhance the memo and factory
136         // to pass two parameters instead of one.
137
138         ArrayList<FType> argValues = et.forStaticArgList(args);
139         return make(argValues, location);
140     }
141
142     public Simple_fcn typeApply(HasAt location, List<FType> argValues) {
143         return make(argValues, location);
144     }
145
146     public void finishInitializing() {
147         Applicable x = getDef();
148         List<Param> params = x.getParams();
149         Option<Type> rt = x.getReturnType();
150         Environment env = getEnv(); // should need this for types,
151         // below.
152         // TODO work in progress
153         // Inject type parameters into environment as symbolics
154         List<StaticParam> tparams = getDef().getStaticParams();
155         for (StaticParam tp : tparams) {
156             if (tp instanceof DimParam) {
157                 DimParam dp = (DimParam) tp;
158             } else if (tp instanceof NatParam) {
159                 NatParam np = (NatParam) tp;
160             } else if (tp instanceof OpParam) {
161                 OpParam op = (OpParam) tp;
162             } else if (tp instanceof TypeParam) {
163                 TypeParam stp = (TypeParam) tp;
164             } else {
165                 bug(tp, errorMsg("Unexpected StaticParam ", tp));
166             }
167         }
168
169         FType ft = EvalType.getFTypeFromOption(rt, env, FTypeTop.ONLY);
170         List<Parameter> fparams = EvalType.paramsToParameters(env, params);
171
172         setParamsAndReturnType(fparams, ft);
173         return;
174     }
175
176     static class GenericComparer implements Comparator<GenericMethod> {
177
178         public int compare(GenericMethod arg0, GenericMethod arg1) {
179             Applicable a0 = arg0.getDef();
180             Applicable a1 = arg1.getDef();
181
182             IdOrOpOrAnonymousName fn0 = a0.getName();
183             IdOrOpOrAnonymousName fn1 = a1.getName();
184             int x = NodeComparator.compare(fn0, fn1);
185             if (x != 0)
186                 return x;
187
188             List<StaticParam> oltp0 = a0.getStaticParams();
189             List<StaticParam> oltp1 = a1.getStaticParams();
190
191             return NodeComparator.compare(oltp0, oltp1);
192
193         }
194
195     }
196
197     static final GenericComparer genComparer = new GenericComparer();
198
199     // static class GenericFullComparer implements Comparator<GenericMethod> {
200
201     //     public int compare(GenericMethod arg0, GenericMethod arg1) {
202     //         return compare(arg0.getDef(), arg1.getDef());
203     //     }
204
205     //     int compare(Applicable left, Applicable right) {
206     //         if (left instanceof FnExpr) {
207     //             int x = Useful.compareClasses(left, right);
208     //             if (x != 0) return x;
209     //             return NodeUtil.nameString(((FnExpr)left).getName())
210     //                 .compareTo(NodeUtil.nameString(((FnExpr)right).getName()));
211     //         } else if (left instanceof FnAbsDeclOrDecl) {
212     //             int x = Useful.compareClasses(left, right);
213     //             if (x != 0) return x;
214     //             return compare(left, (FnAbsDeclOrDecl)right);
215     //         } else if (left instanceof NativeApp) {
216     //             return Useful.compareClasses(left, right);
217     //         } else {
218     //             throw new InterpreterBug(left, "NodeComparator.compare(" +
219     //                                      left.getClass() + ", " + right.getClass());
220     //         }
221     //     }
222
223     // }
224     // static final GenericFullComparer genFullComparer = new GenericFullComparer();
225
226     public IdOrOpOrAnonymousName getName() {
227         return getDef().getName();
228     }
229
230     public List<StaticParam> getStaticParams() {
231         return getDef().getStaticParams();
232     }
233
234     public List<Param> getParams() {
235         return getDef().getParams();
236     }
237
238     public Option<Type> getReturnType() {
239         return getDef().getReturnType();
240     }
241
242
243
244 }
Note: See TracBrowser for help on using the browser.