package me.august.lumen.compile.parser.ast.expr;
import me.august.lumen.common.BytecodeUtil;
import me.august.lumen.compile.analyze.var.VariableReference;
import me.august.lumen.compile.codegen.BuildContext;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;
import java.util.function.Consumer;
public class ArrayAccessExpr implements Expression, VariableExpression, VariableReference {
private Expression value;
private Expression index;
public ArrayAccessExpr(Expression value, Expression index) {
this.value = value;
this.index = index;
}
@Override
public Type expressionType() {
if (value == null || value.expressionType() == null)
return null;
return BytecodeUtil.componentType(value.expressionType());
}
@Override
public void generate(MethodVisitor visitor, BuildContext context) {
value.generate(visitor, context);
index.generate(visitor, context);
int opcode = BytecodeUtil.arrayLoadOpcode(expressionType());
visitor.visitInsn(opcode);
}
@Override
public Expression[] getChildren() {
return new Expression[]{value, index};
}
@Override
public VariableReference getVariableReference() {
return this;
}
@Override
public Type getType() {
return expressionType();
}
@Override
public void generateGetCode(MethodVisitor m) {
generate(m, null);
}
@Override
public void generateSetCode(MethodVisitor m, Consumer<MethodVisitor> insn) {
value.generate(m, null);
index.generate(m, null);
insn.accept(m);
// stack = array ref, index, value
int opcode = BytecodeUtil.arrayStoreOpcode(expressionType());
m.visitInsn(opcode);
}
}