/* * This file is part of the Jikes RVM project (http://jikesrvm.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. You * may obtain a copy of the License at * * http://www.opensource.org/licenses/eclipse-1.0.php * * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. */ package org.mmtk.harness.lang.type; import java.util.HashMap; import java.util.Map; import org.mmtk.harness.lang.Visitor; import org.mmtk.harness.lang.ast.AST; import org.mmtk.harness.lang.ast.AbstractAST; import org.mmtk.harness.lang.parser.Token; import org.mmtk.harness.lang.runtime.ObjectValue; import org.mmtk.harness.lang.runtime.Value; /** * A user-defined object type */ public class UserTypeImpl extends AbstractType implements UserType { /** The fields of the type */ private final Map<String,Field> fields = new HashMap<String,Field>(); private final AST ast; private int referenceFields = 0; private int dataFields = 0; /** * Create a user-defined type * @param tok Source-code token * @param name Name of the type */ public UserTypeImpl(Token tok, String name) { super(name); this.ast = new AbstractAST(tok); } /** * Define a new field * @param fieldName Name of the field * @param fieldType Type of the field */ public void defineField(String fieldName, Type fieldType) { if (fields.containsKey(fieldName)) { throw new RuntimeException("Type "+getName()+" already contains a field called "+fieldName); } int offset = fieldType.isObject() ? referenceFields++ : dataFields++; Field field = new Field(fieldName,fieldType,offset); fields.put(fieldName, field); } @Override public Value initialValue() { return ObjectValue.NULL; } @Override public Field getField(String name) { return fields.get(name); } /** * @return number of reference fields */ public int referenceFieldCount() { return referenceFields; } /** * @return number of data fields */ public int dataFieldCount() { return dataFields; } @Override public boolean isCompatibleWith(Type rhs) { if (rhs == this || rhs == Type.NULL) { return true; } return false; } @Override public boolean isObject() { return true; } @Override public boolean isUserType() { return true; } /* * Delegate AST-nature to the 'ast' object */ @Override public Object accept(Visitor v) { return v.visit(this); } @Override public int getColumn() { return ast.getColumn(); } @Override public int getLine() { return ast.getLine(); } @Override public String sourceLocation(String prefix) { return ast.sourceLocation(prefix); } @Override public Token getToken() { return ast.getToken(); } }