diff options
Diffstat (limited to 'src/compiler/scala/tools/nsc/backend/icode/Primitives.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/icode/Primitives.scala | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/Primitives.scala b/src/compiler/scala/tools/nsc/backend/icode/Primitives.scala new file mode 100644 index 0000000000..5cebb0edaf --- /dev/null +++ b/src/compiler/scala/tools/nsc/backend/icode/Primitives.scala @@ -0,0 +1,239 @@ +/* NSC -- new scala compiler + * Copyright 2005 LAMP/EPFL + * @author Martin Odersky + */ + +// $Id$ + +package scala.tools.nsc.backend.icode; + +import java.io.PrintWriter; + +[_trait_] abstract class Primitives: ICodes { + + /** This class represents a primitive operation. */ + class Primitive { + } + + + // type : (type) => type + // range: type <- { BOOL, Ix, Ux, Rx } + // jvm : {i, l, f, d}neg + case class Negation(kind: TypeKind) extends Primitive; + + // type : zero ? (type) => BOOL : (type,type) => BOOL + // range: type <- { BOOL, Ix, Ux, Rx, REF } + // jvm : if{eq, ne, lt, ge, le, gt}, if{null, nonnull} + // if_icmp{eq, ne, lt, ge, le, gt}, if_acmp{eq,ne} + case class Test(op: TestOp, kind: TypeKind, zero: boolean) extends Primitive; + + // type : (type,type) => I4 + // range: type <- { Ix, Ux, Rx } + // jvm : lcmp, {f, d}cmp{l, g} + case class Comparison(op: ComparisonOp, kind: TypeKind) extends Primitive; + + // type : (type,type) => type + // range: type <- { Ix, Ux, Rx } + // jvm : {i, l, f, d}{add, sub, mul, div, rem} + case class Arithmetic(op: ArithmeticOp, kind: TypeKind) extends Primitive; + + // type : (type,type) => type + // range: type <- { BOOL, Ix, Ux } + // jvm : {i, l}{and, or, xor} + case class Logical(op: LogicalOp, kind: TypeKind) extends Primitive; + + // type : (type,I4) => type + // range: type <- { Ix, Ux } + // jvm : {i, l}{shl, ushl, shr} + case class Shift(op: ShiftOp, kind: TypeKind) extends Primitive; + + // type : (src) => dst + // range: src,dst <- { Ix, Ux, Rx } + // jvm : i2{l, f, d}, l2{i, f, d}, f2{i, l, d}, d2{i, l, f}, i2{b, c, s} + case class Conversion(src: TypeKind, dst: TypeKind) extends Primitive; + + // type : (Array[REF]) => I4 + // range: type <- { BOOL, Ix, Ux, Rx, REF } + // jvm : arraylength + case class ArrayLength(kind: TypeKind) extends Primitive; + + // type : (buf,el) => buf + // range: lf,rg <- { BOOL, Ix, Ux, Rx, REF, STR } + // jvm : It should call the appropiate 'append' method on StringBuffer + case class StringConcat(el: TypeKind) extends Primitive; + + /** Signals the beginning of a series of concatenations. + * On the JVM platform, it should create a new StringBuffer + */ + case object StartConcat extends Primitive; + + /** + * type: (buf) => STR + * jvm : It should turn the StringBuffer into a String. + */ + case object EndConcat extends Primitive; + + /** Pretty printer for primitives */ + class PrimitivePrinter(out: PrintWriter) { + + def print(s: String): PrimitivePrinter = { + out.print(s); + this + } + + def print(o: AnyRef): PrimitivePrinter = print(o.toString()); + + def printPrimitive(prim: Primitive) = prim match { + case Negation(kind) => + print("!"); + + case Test(op, kind, zero) => + print(op).print(kind); + + case Comparison(op, kind) => + print(op).print("(").print(kind); + + } + } + + /** This class represents a comparison operation. */ + class ComparisonOp { + + /** Returns a string representation of this operation. */ + override def toString(): String = this match { + case CMPL => "CMPL"; + case CMP => "CMP"; + case CMPG => "CMPG"; + case _ => throw new RuntimeException("ComparisonOp unknown case"); + } + } + + /** A comparison operation with -1 default for NaNs */ + case object CMPL extends ComparisonOp; + + /** A comparison operation with no default for NaNs */ + case object CMP extends ComparisonOp; + + /** A comparison operation with +1 default for NaNs */ + case object CMPG extends ComparisonOp; + + + /** This class represents a test operation. */ + class TestOp { + + /** Returns the negation of this operation. */ + def negate(): TestOp = this match { + case EQ => NE; + case NE => EQ; + case LT => GE; + case GE => LT; + case LE => GT; + case GT => LE; + case _ => throw new RuntimeException("TestOp unknown case"); + } + + /** Returns a string representation of this operation. */ + override def toString(): String = this match { + case EQ => "EQ"; + case NE => "NE"; + case LT => "LT"; + case GE => "GE"; + case LE => "LE"; + case GT => "GT"; + case _ => throw new RuntimeException("TestOp unknown case"); + } + } + /** An equality test */ + case object EQ extends TestOp; + + /** A non-equality test */ + case object NE extends TestOp; + + /** A less-than test */ + case object LT extends TestOp; + + /** A greater-than-or-equal test */ + case object GE extends TestOp; + + /** A less-than-or-equal test */ + case object LE extends TestOp; + + /** A greater-than test */ + case object GT extends TestOp; + + /** This class represents an arithmetic operation. */ + class ArithmeticOp { + + /** Returns a string representation of this operation. */ + override def toString(): String = this match { + case ADD => "ADD"; + case SUB => "SUB"; + case MUL => "MUL"; + case DIV => "DIV"; + case REM => "REM"; + case NOT => "NOT"; + case _ => throw new RuntimeException("ArithmeticOp unknown case"); + } + } + + /** An arithmetic addition operation */ + case object ADD extends ArithmeticOp; + + /** An arithmetic subtraction operation */ + case object SUB extends ArithmeticOp; + + /** An arithmetic multiplication operation */ + case object MUL extends ArithmeticOp; + + /** An arithmetic division operation */ + case object DIV extends ArithmeticOp; + + /** An arithmetic remainder operation */ + case object REM extends ArithmeticOp; + + /** Bitwise negation. */ + case object NOT extends ArithmeticOp; + + /** This class represents a shift operation. */ + class ShiftOp { + + /** Returns a string representation of this operation. */ + override def toString(): String = this match { + case LSL => "LSL"; + case ASR => "ASR"; + case LSR => "LSR"; + case _ => throw new RuntimeException("ShitOp unknown case"); + } + } + + /** A logical shift to the left */ + case object LSL extends ShiftOp; + + /** An arithmetic shift to the right */ + case object ASR extends ShiftOp; + + /** A logical shift to the right */ + case object LSR extends ShiftOp; + + /** This class represents a logical operation. */ + class LogicalOp { + + /** Returns a string representation of this operation. */ + override def toString(): String = this match { + case AND => return "AND"; + case OR => return "OR"; + case XOR => return "XOR"; + case _ => throw new RuntimeException("LogicalOp unknown case"); + } + } + + /** A bitwise AND operation */ + case object AND extends LogicalOp; + + /** A bitwise OR operation */ + case object OR extends LogicalOp; + + /** A bitwise XOR operation */ + case object XOR extends LogicalOp; +} + |