summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/backend/icode/Primitives.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/tools/nsc/backend/icode/Primitives.scala')
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Primitives.scala239
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;
+}
+