/* zweic -- a compiler for zwei
*
* Stephane Micheloud & LAMP
*
* $Id$
*/
package zweic;
import scala.collection.immutable.{Map, ListMap};
/**
* This class provides a representation for symbol table entries.
*/
abstract class Symbol {
def pos: Int;
def name: String;
/**
* Offset of the symbol. For variables, that's the offset
* relative to the frame pointer; for functions that's the PC of
* the first instruction.
*/
var offset: Int = -1;
}
case class ClassSymbol(pos: Int, name: String, superclass: Option[ClassSymbol])
extends Symbol
{
private var fields: Map[String,FieldSymbol] =
superclass match {
case None => ListMap.Empty[String,FieldSymbol]
case Some(s) => s.fields
}
private var methods: Map[String,MethodSymbol] =
superclass match {
case None => ListMap.Empty[String,MethodSymbol]
case Some(s) => s.methods
}
def superclasses: List[ClassSymbol] =
this :: (superclass match {
case None => Nil
case Some(c) => c.superclasses
});
def isSubclassOf(that: ClassSymbol): Boolean =
superclasses.contains(that);
def enterField(f: FieldSymbol): Unit = {
f.offset = fields.size * 4;
fields = fields + f.name -> f;
}
def lookupField(name: String): Option[FieldSymbol] =
fields.get(name);
def enterNewMethod(m: MethodSymbol): Unit = {
m.offset = methods.size * 4;
methods = methods + m.name -> m;
}
def enterMethod(m: MethodSymbol): Unit = {
m.offset = methods(m.name).offset;
methods = methods + m.name -> m;
}
def lookupMethod(name: String): Option[MethodSymbol] =
methods.get(name);
def allFields: List[FieldSymbol] =
fields.values.toList;
def allMethods: List[MethodSymbol] =
methods.values.toList;
override def toString() = "class " + name;
}
case class FieldSymbol(pos: Int, name: String, fieldtype: Type)
extends Symbol
{
override def toString() = "field " + name + ": " + fieldtype;
}
case class MethodSymbol(pos: Int, name: String, paramtypes: List[Type], restype: Type)
extends Symbol
{
var address: Int = _;
override def toString() = "method " + name +
paramtypes.mkString("(", ",", ")") + ": " + restype;
}
case class VarSymbol(pos: Int, name: String, vartype: Type)
extends Symbol
{
override def toString() = "variable " + name + ": " + vartype;
}