/*******************************************************************************
* Copyright (c) 2009-2013 CWI
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* * Jurgen J. Vinju - Jurgen.Vinju@cwi.nl - CWI
* * Mark Hills - Mark.Hills@cwi.nl (CWI)
*******************************************************************************/
package org.rascalmpl.semantics.dynamic;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.rascalmpl.ast.QualifiedName;
import org.rascalmpl.interpreter.IEvaluator;
import org.rascalmpl.interpreter.env.Environment;
import org.rascalmpl.interpreter.result.Result;
import org.rascalmpl.interpreter.staticErrors.UndeclaredType;
import org.rascalmpl.value.IConstructor;
import org.rascalmpl.value.ISourceLocation;
import org.rascalmpl.value.IValue;
import org.rascalmpl.value.type.Type;
public abstract class UserType extends org.rascalmpl.ast.UserType {
static public class Name extends org.rascalmpl.ast.UserType.Name {
public Name(ISourceLocation __param1, IConstructor tree, QualifiedName __param2) {
super(__param1, tree, __param2);
}
@Override
public Type typeOf(Environment __eval, boolean instantiateTypeParameters, IEvaluator<Result<IValue>> eval) {
Environment theEnv = __eval.getHeap().getEnvironmentForName(
getName(), __eval);
String name = org.rascalmpl.interpreter.utils.Names.typeName(this
.getName());
if (theEnv != null) {
Type type = theEnv.lookupAlias(name);
if (type != null) {
return type;
}
Type tree = theEnv.lookupAbstractDataType(name);
if (tree != null) {
return tree;
}
Type symbol = theEnv.lookupConcreteSyntaxType(name);
if (symbol != null) {
return symbol;
}
}
throw new UndeclaredType(name, this);
}
}
static public class Parametric extends
org.rascalmpl.ast.UserType.Parametric {
public Parametric(ISourceLocation __param1, IConstructor tree, QualifiedName __param2,
List<org.rascalmpl.ast.Type> __param3) {
super(__param1, tree, __param2, __param3);
}
@Override
public Type typeOf(Environment __eval, boolean instantiateTypeParameters, IEvaluator<Result<IValue>> eval) {
String name;
Type type = null;
Environment theEnv = __eval.getHeap().getEnvironmentForName(
this.getName(), __eval);
name = org.rascalmpl.interpreter.utils.Names.typeName(this
.getName());
if (theEnv != null) {
type = theEnv.lookupAlias(name);
if (type == null) {
type = theEnv.lookupAbstractDataType(name);
}
}
if (type != null) {
Map<Type, Type> bindings = new HashMap<Type, Type>();
Type[] params = new Type[this.getParameters().size()];
int i = 0;
for (org.rascalmpl.ast.Type param : this.getParameters()) {
params[i++] = param.typeOf(__eval, instantiateTypeParameters, eval);
}
// __eval has side-effects that we might need?
type.getTypeParameters().match(TF.tupleType(params), bindings);
// Instantiate first using the type actually given in the parameter,
// e.g., for T[str], with data T[&U] = ..., instantate the binding
// of &U = str, and then instantate using bindings from the current
// environment (generally meaning we are inside a function with
// type parameters, and those parameters are now bound to real types)
return type.instantiate(bindings).instantiate(__eval.getTypeBindings());
}
throw new UndeclaredType(name, this);
}
}
public UserType(ISourceLocation __param1, IConstructor tree) {
super(__param1, tree);
}
}