| 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; |
|---|
| 19 |
|
|---|
| 20 |
import com.sun.fortress.nodes_util.NodeUtil; |
|---|
| 21 |
import java.util.Iterator; |
|---|
| 22 |
import java.util.List; |
|---|
| 23 |
import edu.rice.cs.plt.tuple.Option; |
|---|
| 24 |
|
|---|
| 25 |
import com.sun.fortress.exceptions.FortressException; |
|---|
| 26 |
import com.sun.fortress.interpreter.env.IndirectionCell; |
|---|
| 27 |
import com.sun.fortress.interpreter.evaluator.types.FType; |
|---|
| 28 |
import com.sun.fortress.interpreter.evaluator.types.FTypeTop; |
|---|
| 29 |
import com.sun.fortress.interpreter.evaluator.values.Closure; |
|---|
| 30 |
import com.sun.fortress.interpreter.evaluator.values.FTuple; |
|---|
| 31 |
import com.sun.fortress.interpreter.evaluator.values.FValue; |
|---|
| 32 |
import com.sun.fortress.interpreter.evaluator.values.Parameter; |
|---|
| 33 |
import com.sun.fortress.nodes.NodeAbstractVisitor; |
|---|
| 34 |
import com.sun.fortress.nodes.Expr; |
|---|
| 35 |
import com.sun.fortress.nodes.FnDef; |
|---|
| 36 |
import com.sun.fortress.nodes.IdOrOpOrAnonymousName; |
|---|
| 37 |
import com.sun.fortress.nodes.LValue; |
|---|
| 38 |
import com.sun.fortress.nodes.LValueBind; |
|---|
| 39 |
import com.sun.fortress.nodes.LetExpr; |
|---|
| 40 |
import com.sun.fortress.nodes.LetFn; |
|---|
| 41 |
import com.sun.fortress.nodes.LocalVarDecl; |
|---|
| 42 |
import com.sun.fortress.nodes.Param; |
|---|
| 43 |
import com.sun.fortress.nodes.Type; |
|---|
| 44 |
|
|---|
| 45 |
import static com.sun.fortress.exceptions.ProgramError.error; |
|---|
| 46 |
import static com.sun.fortress.exceptions.ProgramError.errorMsg; |
|---|
| 47 |
|
|---|
| 48 |
public class BuildLetEnvironments extends NodeAbstractVisitor<FValue> { |
|---|
| 49 |
|
|---|
| 50 |
boolean firstPass = true; |
|---|
| 51 |
|
|---|
| 52 |
Environment containing; |
|---|
| 53 |
|
|---|
| 54 |
public BuildLetEnvironments(Environment within) { |
|---|
| 55 |
this.containing = within; |
|---|
| 56 |
} |
|---|
| 57 |
|
|---|
| 58 |
/* (non-Javadoc) |
|---|
| 59 |
* @see com.sun.fortress.interpreter.nodes.NodeVisitor#forLetFn(com.sun.fortress.interpreter.nodes.LetFn) |
|---|
| 60 |
*/ |
|---|
| 61 |
@Override |
|---|
| 62 |
public FValue forLetFn(LetFn x) { |
|---|
| 63 |
List<FnDef> fns = x.getFns(); |
|---|
| 64 |
List<Expr> body = x.getBody(); |
|---|
| 65 |
|
|---|
| 66 |
for (int i = 0; i < fns.size(); i++) { |
|---|
| 67 |
FnDef fn = fns.get(i); |
|---|
| 68 |
|
|---|
| 69 |
IdOrOpOrAnonymousName name = fn.getName(); |
|---|
| 70 |
//Expr expr = fn.getBody(); |
|---|
| 71 |
String fname = NodeUtil.nameString(name); |
|---|
| 72 |
List<Param> params = fn.getParams(); |
|---|
| 73 |
Option<Type> retType = fn.getReturnType(); |
|---|
| 74 |
|
|---|
| 75 |
Closure cl = new Closure(containing, fn); |
|---|
| 76 |
try { |
|---|
| 77 |
containing.putValue(fname, cl); |
|---|
| 78 |
} catch (FortressException pe) { |
|---|
| 79 |
throw pe.setContext(x,containing); |
|---|
| 80 |
} |
|---|
| 81 |
// TODO Local functions cannot be Enclosing, can they? |
|---|
| 82 |
// Local functions cannot be any operator including Enclosing. |
|---|
| 83 |
FType ft = EvalType.getFTypeFromOption(retType,containing, FTypeTop.ONLY); |
|---|
| 84 |
List<Parameter> fparams = EvalType.paramsToParameters(containing, params); |
|---|
| 85 |
cl.setParamsAndReturnType(fparams, ft); |
|---|
| 86 |
} |
|---|
| 87 |
return (new Evaluator(containing)).evalExprList(body, x); |
|---|
| 88 |
} |
|---|
| 89 |
|
|---|
| 90 |
public FValue forLocalVarDecl(LocalVarDecl x) { |
|---|
| 91 |
List<LValue> lhs = x.getLhs(); |
|---|
| 92 |
Option<Expr> rhs = x.getRhs(); |
|---|
| 93 |
List<Expr> body = x.getBody(); |
|---|
| 94 |
//FValue res = Evaluator.evVoid; |
|---|
| 95 |
|
|---|
| 96 |
Evaluator new_eval = new Evaluator(containing); |
|---|
| 97 |
if (rhs.isSome()) { |
|---|
| 98 |
if (lhs.size() == 1) { |
|---|
| 99 |
FValue val = rhs.unwrap().accept(new_eval); |
|---|
| 100 |
LHSEvaluator lhs_eval = new LHSEvaluator(new_eval, val); |
|---|
| 101 |
lhs.get(0).accept(lhs_eval); |
|---|
| 102 |
} else { |
|---|
| 103 |
FValue val = rhs.unwrap().accept(new_eval); |
|---|
| 104 |
|
|---|
| 105 |
if (!(val instanceof FTuple)) { |
|---|
| 106 |
error(x, containing, |
|---|
| 107 |
errorMsg("RHS does not yield a tuple")); |
|---|
| 108 |
} |
|---|
| 109 |
|
|---|
| 110 |
FTuple rTuple = (FTuple) val; |
|---|
| 111 |
Iterator<LValue> i = lhs.iterator(); |
|---|
| 112 |
Iterator<FValue> j = rTuple.getVals().iterator(); |
|---|
| 113 |
while (i.hasNext() && j.hasNext()) { |
|---|
| 114 |
LValue lval = i.next(); |
|---|
| 115 |
FValue rval = j.next(); |
|---|
| 116 |
|
|---|
| 117 |
LHSEvaluator lhs_eval = new LHSEvaluator(new_eval, rval); |
|---|
| 118 |
lval.accept(lhs_eval); |
|---|
| 119 |
} |
|---|
| 120 |
if (i.hasNext()) { |
|---|
| 121 |
LValue lval = i.next(); |
|---|
| 122 |
error(lval, containing, errorMsg("Extra lvalue")); |
|---|
| 123 |
} else if (j.hasNext()) { |
|---|
| 124 |
FValue rval = j.next(); |
|---|
| 125 |
error(rhs.unwrap(), containing, errorMsg("Extra rvalue")); |
|---|
| 126 |
} |
|---|
| 127 |
} |
|---|
| 128 |
} else { |
|---|
| 129 |
EvalType eval_type = new EvalType(containing); |
|---|
| 130 |
for (LValue lval : lhs) { |
|---|
| 131 |
if (lval instanceof LValueBind) { |
|---|
| 132 |
LValueBind lvb = (LValueBind) lval; |
|---|
| 133 |
if (lvb.isMutable() && lvb.getType().isSome()) { |
|---|
| 134 |
FValue fv = lval.accept(new_eval); |
|---|
| 135 |
FType fvt = lvb.getType().unwrap().accept(eval_type); |
|---|
| 136 |
containing.putVariable(fv.getString(),fvt); |
|---|
| 137 |
} else { |
|---|
| 138 |
containing.putValue(lval.accept(new_eval), new IndirectionCell()); |
|---|
| 139 |
|
|---|
| 140 |
} |
|---|
| 141 |
} else { |
|---|
| 142 |
containing.putValue(lval.accept(new_eval), new IndirectionCell()); |
|---|
| 143 |
} |
|---|
| 144 |
} |
|---|
| 145 |
|
|---|
| 146 |
} |
|---|
| 147 |
return new_eval.evalExprList(body, x); |
|---|
| 148 |
} |
|---|
| 149 |
|
|---|
| 150 |
public FValue doLets(LetExpr exp) { |
|---|
| 151 |
return exp.accept(this); |
|---|
| 152 |
} |
|---|
| 153 |
|
|---|
| 154 |
} |
|---|