Package org.renjin.gcc.translate.expr

Source Code of org.renjin.gcc.translate.expr.ImStringConstant$Substring

package org.renjin.gcc.translate.expr;

import org.renjin.gcc.gimple.expr.GimpleStringConstant;
import org.renjin.gcc.gimple.type.GimplePointerType;
import org.renjin.gcc.jimple.JimpleExpr;
import org.renjin.gcc.translate.FunctionContext;
import org.renjin.gcc.translate.type.ImIndirectType;
import org.renjin.gcc.translate.type.ImPrimitiveType;
import org.renjin.gcc.translate.type.ImType;


public class ImStringConstant extends AbstractImExpr {

  private GimpleStringConstant constant;
  private ImPrimitiveType type;
 
  public ImStringConstant(GimpleStringConstant constant) {
    this.constant = constant;
  }

  @Override
  public ImType type() {
    throw new UnsupportedOperationException();
  }

  @Override
  public String toString() {
    return JimpleExpr.stringLiteral(constant.getValue()).toString();
  }

  @Override
  public ImExpr addressOf() {
    return new Pointer(null);
  }

  @Override
  public ImExpr elementAt(ImExpr index) {
    return new Substring(index);
  }
 
  public class Substring extends AbstractImExpr {
    private ImExpr startIndex;

    public Substring(ImExpr startIndex) {
      this.startIndex = startIndex;
    }

    @Override
    public ImExpr addressOf() {
      return new Pointer(startIndex);
    }

    @Override
    public ImPrimitiveType type() {
      return type;
    }
  }

  public class Pointer extends AbstractImExpr implements ImIndirectExpr {
   
    private ImExpr startIndex;

    public Pointer(ImExpr startIndex) {
      this.startIndex = startIndex;
    }

    @Override
    public ArrayRef translateToArrayRef(FunctionContext context) {
      String stringTmp = context.declareTemp(String.class);
      String arrayTmp = context.declareTemp(char.class);
     
      context.getBuilder().addStatement(stringTmp + " = " +
          JimpleExpr.stringLiteral(constant.getValue()));
      context.getBuilder().addStatement(arrayTmp + " = virtualinvoke " +
              stringTmp + ".<java.lang.String: char[] toCharArray()>()");
     
      JimpleExpr indexExpr;
      if(startIndex == null) {
        indexExpr = JimpleExpr.integerConstant(constant.getType().getLbound());       
      } else {
        indexExpr = subtractLowerBound(context, startIndex);
      }

      return new ArrayRef(new JimpleExpr(arrayTmp), indexExpr);
    }

    private JimpleExpr subtractLowerBound(FunctionContext context, ImExpr expr) {
      if(constant.getType().getLbound() == 0) {
        return startIndex.translateToPrimitive(context, null);
      } else if(expr instanceof ImPrimitiveConstant) {
        Number startIndex = (Number)((ImPrimitiveConstant) expr).getConstantValue();
        return JimpleExpr.integerConstant(startIndex.intValue() - constant.getType().getLbound());
      } else {
        throw new UnsupportedOperationException();
      }
    }

    @Override
    public ImIndirectType type() {
      return ImPrimitiveType.CHAR.pointerType();
    }

    @Override
    public String toString() {
      return "&" + ImStringConstant.this.toString();
    }
  }
}
TOP

Related Classes of org.renjin.gcc.translate.expr.ImStringConstant$Substring

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.