// Mike Maxim
// Variable translator

package edu.cmu.cs.l3.translate;

import edu.cmu.cs.l3.general.*;
import edu.cmu.cs.l3.absyn.*;
import edu.cmu.cs.l3.symbol.Symbol;
import edu.cmu.cs.l3.errormsg.*;
import edu.cmu.cs.l3.frame.*;
import edu.cmu.cs.l3.tree.*;
import edu.cmu.cs.l3.semant.*;
import java.util.List;

public class TranslateVariable extends Translate {

    public TranslateVariable(Frame curframe, ErrorMsg m, TranslateEnvironment t) {
	super(curframe,m,t);
    }

    public void visitResponse(String type, Object obj) {

        try {
            if (type.equals("ASSimpleLval")) {
                visitSimpleVar(obj);
            }
            else if (type.equals("ASFieldLval")) {
                visitFieldVar(obj);
            }
            else if (type.equals("ASDerefLval")) {
                visitMemVar(obj);
            }
            else {
                System.out.println("INTERNAL COMPILER ERROR: Skipping: " + type);
            }
        } catch (TranslateException e) {
            System.out.println(e.getMessage());
            System.exit(-1);
        }

    }

    public void visitMemVar(Object v) throws TranslateException {

        ASDerefLval av = (ASDerefLval) v;

        TranslateExpression etran = new TranslateExpressionEx(m_curframe,m_errorMsg,m_table);
        av.getVariableExpression().visit(etran);

        m_var = m_memtran.safeDereference(m_curframe,etran.asExpression(), av.getPosition());
        m_fatptr = etran.asExpression();
    }

    public void visitFieldVar(Object v) throws TranslateException {

        ASFieldLval av = (ASFieldLval) v;
        TranslateVariable vtran = new TranslateVariable(m_curframe,m_errorMsg,m_table);
        TyRecord ty = (TyRecord) av.getRecord().getTypeInfo().getSemantType();
        int i;
        List fields = ty.getFieldNames();

        av.getRecord().visit(vtran);

        for (i = 0; i < fields.size(); i++) {
            String fname = fields.get(i).toString();
            if (fname.equals(av.getField().toString())) {
                break;
            }
        }

        m_var = m_memtran.thinPointerAccess(m_curframe,vtran.getVariable(),new IRConst(i));
    }

    public void visitSimpleVar(Object v) {

	ASSimpleLval av = (ASSimpleLval) v;

	m_var = m_table.getEntry(av.getName());
    }

    public IRExpression getVariable() {
	return m_var;
    }

    public IRExpression getFatPointer() {
        return m_fatptr;
    }

    private IRExpression m_var, m_fatptr;
    private Symbol m_symbol;
}
