package s3.services.simplejit.bytecode;

import ovm.core.domain.Blueprint;
import ovm.core.domain.Domain;
import ovm.core.domain.LinkageException;
import ovm.core.domain.Type;
import ovm.core.repository.TypeCodes;
import ovm.util.OVMError;
import s3.services.simplejit.bytecode.SimpleJITValue.SimpleJITArray;
import s3.services.simplejit.bytecode.SimpleJITValue.SimpleJITDouble;
import s3.services.simplejit.bytecode.SimpleJITValue.SimpleJITFloat;
import s3.services.simplejit.bytecode.SimpleJITValue.SimpleJITInt;
import s3.services.simplejit.bytecode.SimpleJITValue.SimpleJITLong;
import s3.services.simplejit.bytecode.SimpleJITValue.SimpleJITReference;

public class SimpleJITEphemeralTypeMap 
    extends EphemeralTypeMap {

    public SimpleJITEphemeralTypeMap(Domain dom) {
	super(dom);
    }

    private Blueprint blueprintFor(Domain domain, 
				   Type.Compound n) {
	try {
	    return domain.blueprintFor(n);
	} catch (LinkageException e) {
	    return null;
	}
    }

    private SimpleJITValue valueFromType(Type in) {
	char tag = in.getUnrefinedName().getTypeTag();
	switch(tag) {
	case TypeCodes.INT:
	    return new SimpleJITInt();
	case TypeCodes.FLOAT:
	    return new SimpleJITFloat();
	case TypeCodes.LONG:
	    return new SimpleJITLong();
	case TypeCodes.DOUBLE:
	    return new SimpleJITDouble();
	case TypeCodes.OBJECT:
	    return new SimpleJITReference
		(blueprintFor(dom, in.asCompound()));
	case TypeCodes.ARRAY:
	    return new SimpleJITArray
		(blueprintFor(dom, in.asCompound())
		 .asArray());
	default:
	    throw new OVMError
		("Unexpected type tag : " + tag);
	}
    }

    public SimpleJITValue map(SimpleJITValue in) {
	String name = in.getName();
	if (name != null) {
	    Type t = 
		map(typeFor(name));
	    if (t != null) {
		return valueFromType(t);
	    }
	}
	return in;
    }
}
