001: package gnu.expr;
002:
003: import gnu.bytecode.*;
004: import gnu.mapping.OutPort;
005:
006: /**
007: * Class used to implement "let" syntax (and variants) for Scheme.
008: * @author Per Bothner
009: */
010:
011: public class LetExp extends ScopeExp {
012: public Expression[] inits;
013: public Expression body;
014:
015: public LetExp(Expression[] i) {
016: inits = i;
017: }
018:
019: public Expression getBody() {
020: return body;
021: }
022:
023: public void setBody(Expression body) {
024: this .body = body;
025: }
026:
027: Method makeBindingMethod = null;
028:
029: /* Recursive helper routine, to store the values on the stack
030: * into the variables in vars, in reverse order. */
031: static void store_rest(Compilation comp, Declaration decl) {
032: if (decl != null) {
033: store_rest(comp, decl.nextDecl());
034: if (decl.needsInit())
035: decl.initBinding(comp);
036: }
037: }
038:
039: public void compile(Compilation comp, Target target) {
040: gnu.bytecode.CodeAttr code = comp.getCode();
041:
042: /*
043: if (comp.usingCPStyle())
044: {
045: for (Declartion decl = firstDecl(); decl != null; decl = decl.nextVar ())
046: {
047: decl.assignField(comp);
048: }
049: }
050: */
051:
052: /* Compile all the initializations, leaving the results
053: on the stack (in reverse order). */
054: Declaration decl = firstDecl();
055: for (int i = 0; i < inits.length; i++, decl = decl.nextDecl()) {
056: Target varTarget;
057: decl.allocateVariable(code);
058: if (!decl.needsInit())
059: varTarget = Target.Ignore;
060: else {
061: Type varType = decl.getType();
062: if (varType == Type.pointer_type)
063: varTarget = Target.pushObject;
064: else
065: varTarget = new StackTarget(varType);
066: }
067: inits[i].compile(comp, varTarget);
068: }
069:
070: code.enterScope(scope);
071:
072: /* Assign the initial values to the proper variables, in reverse order. */
073: store_rest(comp, firstDecl());
074:
075: body.compileWithPosition(comp, target);
076: code.popScope();
077: }
078:
079: public final gnu.bytecode.Type getType() {
080: return body.getType();
081: }
082:
083: protected Expression walk(ExpWalker walker) {
084: return walker.walkLetExp(this );
085: }
086:
087: protected void walkChildren(ExpWalker walker) {
088: inits = walker.walkExps(inits);
089: if (walker.exitValue == null)
090: body = (Expression) body.walk(walker);
091: }
092:
093: public void print(OutPort out) {
094: out.startLogicalBlock("(Let", ")", 2);
095: out.writeSpaceFill();
096: printLineColumn(out);
097: out.startLogicalBlock("(", false, ")");
098: Declaration decl = firstDecl();
099: int i = 0;
100:
101: for (; decl != null; decl = decl.nextDecl()) {
102: if (i > 0)
103: out.writeSpaceLinear();
104: out.print('(');
105: out.print(decl.getName());
106: out.writeSpaceFill();
107: //if (decl.isArtificial ())
108: //out.print ("<artificial>");
109: //else
110: {
111: if (inits[i] == null)
112: out.print("<null>");
113: else
114: inits[i].print(out);
115: i++;
116: }
117: out.print(')');
118: }
119: out.endLogicalBlock(")");
120: out.writeSpaceLinear();
121: body.print(out);
122: out.endLogicalBlock(")");
123: }
124: }
|