Package org.renjin.compiler.ir.tac.functions

Source Code of org.renjin.compiler.ir.tac.functions.AssignLeftTranslator

package org.renjin.compiler.ir.tac.functions;


import org.renjin.compiler.ir.tac.IRBodyBuilder;
import org.renjin.compiler.ir.tac.expressions.*;
import org.renjin.compiler.ir.tac.statements.Assignment;
import org.renjin.eval.EvalException;
import org.renjin.sexp.FunctionCall;
import org.renjin.sexp.SEXP;
import org.renjin.sexp.StringVector;
import org.renjin.sexp.Symbol;


public class AssignLeftTranslator extends FunctionCallTranslator {

  @Override
  public Expression translateToExpression(IRBodyBuilder builder, TranslationContext context, FunctionCall call) {


    Expression rhs = builder.translateExpression(context, call.getArgument(1));

    // since the rhs will be used as this expression's value,
    // we need to assure that it is not evaluated twice
    if(!(rhs instanceof Constant)) {
      // avoid evaluating RHS twice
      Temp temp = builder.newTemp();
      builder.addStatement(new Assignment(temp, rhs));
      rhs = temp;
    }
   
    addAssignment(builder, context, call, rhs);
    return rhs;
  }
 
  @Override
  public void addStatement(IRBodyBuilder builder, TranslationContext context, FunctionCall assignment) {
    Expression rhs = builder.translateExpression(context, assignment.getArgument(1));

    addAssignment(builder, context, assignment, rhs);
  }
 
  private void addAssignment(IRBodyBuilder builder, TranslationContext context, FunctionCall assignment,
      Expression rhs) {
    // this loop handles nested, complex assignments, such as:
    // class(x) <- "foo"
    // x$a[3] <- 4
    // class(x$a[3]) <- "foo"

    SEXP lhs = assignment.getArgument(0);
   
    while(lhs instanceof FunctionCall) {
      FunctionCall call = (FunctionCall) lhs;
     
      rhs = builder.translateSetterCall(context, call, rhs);
      lhs = call.getArgument(0);
    }

    LValue target;
    if( lhs instanceof Symbol) {
      target = new EnvironmentVariable((Symbol) lhs);
    } else if(lhs instanceof StringVector) {
      target =  new EnvironmentVariable( Symbol.get(((StringVector) lhs).getElementAsString(0)) );
    } else {
      throw new EvalException("cannot assign to value of type " + lhs.getTypeName());
    }

    doAssignment(builder, target, rhs);
   
  }

  protected void doAssignment(IRBodyBuilder builder, LValue target, Expression rhs) {
    // make the final assignment to the target symbol
    builder.addStatement(new Assignment(target, rhs));
  }

  @Override
  public Symbol getName() {
    return Symbol.get("<-");
  }
}
TOP

Related Classes of org.renjin.compiler.ir.tac.functions.AssignLeftTranslator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.