Files
exercise03/MicroJava Compiler/src/ssw/mj/codegen/Operand.java

153 lines
3.0 KiB
Java

package ssw.mj.codegen;
import ssw.mj.impl.Code;
import ssw.mj.impl.Code.CompOp;
import ssw.mj.impl.Parser;
import ssw.mj.impl.Tab;
import ssw.mj.symtab.Obj;
import ssw.mj.symtab.Struct;
import static ssw.mj.Errors.Message.ILLEGAL_OPERAND_KIND;
public class Operand {
/**
* Possible operands.
*/
public enum Kind {
Con(true),
Local(false),
Static(false),
Stack(true),
Fld(false),
Elem(false),
Meth(true),
Cond(true),
None(true);
public final boolean isReadOnly;
Kind(boolean isReadOnly) {
this.isReadOnly = isReadOnly;
}
}
/**
* Kind of the operand.
*/
public Kind kind;
/**
* The type of the operand (reference to symbol table).
*/
public Struct type;
/**
* Only for Con: Value of the constant.
*/
public int val;
/**
* Only for Local, Static, Fld, Meth: Offset of the element.
*/
public int adr;
/**
* Only for Cond: Relational operator.
*/
public CompOp op;
/**
* Only for Meth: Method object from the symbol table.
*/
public Obj obj;
/**
* Only for Cond: Target for true jumps.
*/
public Label tLabel;
/**
* Only for Cond: Target for false jumps.
*/
public Label fLabel;
/**
* Constructor for named objects: constants, variables, methods
*/
public Operand(Obj o, Parser parser) {
type = o.type;
val = o.val;
adr = o.adr;
switch (o.kind) {
case Con -> kind = Kind.Con;
case Var -> {
if (o.level == 0) {
kind = Kind.Static;
} else {
kind = Kind.Local;
}
}
case Meth -> {
kind = Kind.Meth;
obj = o;
}
default -> {
kind = Kind.None;
parser.error(ILLEGAL_OPERAND_KIND, o.kind);
}
}
}
/**
* Constructor for compare operations
*/
public Operand(CompOp op, Code code) {
this(code);
this.kind = Kind.Cond;
this.op = op;
}
public Operand(Code code) {
tLabel = new Label(code);
fLabel = new Label(code);
}
/**
* Constructor for stack operands
*/
public Operand(Struct type) {
this.kind = Kind.Stack;
this.type = type;
}
/**
* Constructor for integer constants
*/
public Operand(int x) {
kind = Kind.Con;
type = Tab.intType;
val = x;
}
public boolean isReadOnly() {
return kind.isReadOnly;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("Op[");
switch (kind) {
case Con -> {
sb.append(type).append(' ');
sb.append(val);
}
case Local, Static, Fld -> {
sb.append(kind).append(' ');
sb.append(type).append(' ');
sb.append(adr);
}
case Cond -> sb.append(op);
case Meth -> sb.append(obj);
case Elem, Stack -> {
sb.append(kind).append(' ');
sb.append(type);
}
}
return sb.append(']').toString();
}
}