/*
* #%~
* The VDM Type Checker
* %%
* Copyright (C) 2008 - 2017 Overture
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #~%
*/
package org.overture.interpreter.utilities.type;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;
import org.overture.ast.analysis.AnalysisException;
import org.overture.ast.analysis.QuestionAnswerAdaptor;
import org.overture.ast.factory.AstFactory;
import org.overture.ast.node.INode;
import org.overture.ast.types.AFunctionType;
import org.overture.ast.types.AOptionalType;
import org.overture.ast.types.AParameterType;
import org.overture.ast.types.AProductType;
import org.overture.ast.types.ASet1SetType;
import org.overture.ast.types.ASetSetType;
import org.overture.ast.types.AUnionType;
import org.overture.ast.types.PType;
import org.overture.ast.types.SMapType;
import org.overture.ast.types.SSeqType;
import org.overture.interpreter.runtime.Context;
import org.overture.interpreter.runtime.VdmRuntimeError;
import org.overture.interpreter.values.ParameterValue;
import org.overture.interpreter.values.Value;
import org.overture.typechecker.assistant.ITypeCheckerAssistantFactory;
/**
* Implement the concrete type of a given type, given a Context with @T parameter definitions.
*
* @author ncb
*/
public class ConcreteTypeInstantiator extends QuestionAnswerAdaptor<Context, PType>
{
protected ITypeCheckerAssistantFactory af;
public ConcreteTypeInstantiator(ITypeCheckerAssistantFactory af)
{
this.af = af;
}
@Override
public PType caseAParameterType(AParameterType type, Context ctxt) throws AnalysisException
{
Value t = ctxt.lookup(type.getName());
if (t == null)
{
VdmRuntimeError.abort(type.getLocation(), 4008,
"No such type parameter @" + type.getName() + " in scope", ctxt);
}
else if (t instanceof ParameterValue)
{
ParameterValue tv = (ParameterValue)t;
return tv.type;
}
else
{
VdmRuntimeError.abort(type.getLocation(), 4009,
"Type parameter/local variable name clash, @" + type.getName(), ctxt);
}
return null;
}
@Override
public PType caseAFunctionType(AFunctionType type, Context ctxt) throws AnalysisException
{
type = AstFactory.newAFunctionType(type.getLocation(), type.getPartial(),
instantiate(type.getParameters(), ctxt), type.getResult().apply(this, ctxt));
type.setInstantiated(true);
return type;
}
@Override
public PType defaultSMapType(SMapType type, Context ctxt) throws AnalysisException
{
return AstFactory.newAMapMapType(type.getLocation(),
type.getFrom().apply(this, ctxt),
type.getTo().apply(this, ctxt));
}
@Override
public PType caseAOptionalType(AOptionalType type, Context ctxt) throws AnalysisException
{
return AstFactory.newAOptionalType(type.getLocation(), type.getType().apply(this, ctxt));
}
@Override
public PType caseAProductType(AProductType type, Context ctxt) throws AnalysisException
{
return AstFactory.newAProductType(type.getLocation(), instantiate(type.getTypes(), ctxt));
}
@Override
public PType defaultSSeqType(SSeqType type, Context ctxt) throws AnalysisException
{
return AstFactory.newASeqSeqType(type.getLocation(), type.getSeqof().apply(this, ctxt));
}
@Override
public PType caseASetSetType(ASetSetType type, Context ctxt) throws AnalysisException
{
return AstFactory.newASetSetType(type.getLocation(), type.getSetof().apply(this, ctxt));
}
@Override
public PType caseASet1SetType(ASet1SetType type, Context ctxt) throws AnalysisException
{
return AstFactory.newASet1SetType(type.getLocation(), type.getSetof().apply(this, ctxt));
}
@Override
public PType caseAUnionType(AUnionType type, Context ctxt) throws AnalysisException
{
return AstFactory.newAUnionType(type.getLocation(), instantiate(type.getTypes(), ctxt));
}
@Override
public PType defaultPType(PType type, Context ctxt) throws AnalysisException
{
return type;
}
private List<PType> instantiate(LinkedList<PType> types, Context ctxt) throws AnalysisException
{
List<PType> instantiated = new Vector<PType>();
for (PType type: types)
{
instantiated.add(type.apply(this, ctxt));
}
return instantiated;
}
@Override
public PType createNewReturnValue(INode node, Context question) throws AnalysisException
{
return null;
}
@Override
public PType createNewReturnValue(Object node, Context question) throws AnalysisException
{
return null;
}
}