private LValue constructLVal ( Expr expr , CallStack frame ) { switch ( expr . getOpcode ( ) ) { case EXPR_arrayborrow : case EXPR_arrayaccess : { Expr . ArrayAccess e = ( Expr . ArrayAccess ) expr ; LValue src = constructLVal ( e . getFirstOperand ( ) , frame ) ; RValue . Int index = executeExpression ( INT_T , e . getSecondOperand ( ) , frame ) ; return new LValue . Array ( src , index ) ; } case EXPR_dereference : { Expr . Dereference e = ( Expr . Dereference ) expr ; LValue src = constructLVal ( e . getOperand ( ) , frame ) ; return new LValue . Dereference ( src ) ; } case EXPR_recordaccess : case EXPR_recordborrow : { Expr . RecordAccess e = ( Expr . RecordAccess ) expr ; LValue src = constructLVal ( e . getOperand ( ) , frame ) ; return new LValue . Record ( src , e . getField ( ) ) ; } case EXPR_variablemove : case EXPR_variablecopy : { Expr . VariableAccess e = ( Expr . VariableAccess ) expr ; Decl . Variable decl = e . getVariableDeclaration ( ) ; return new LValue . Variable ( decl . getName ( ) ) ; } } deadCode ( expr ) ; return null ; // deadcode }
This method constructs a mutable representation of the lval . This is a bit strange but is necessary because values in the frame are currently immutable .