scala.tools.nsc.backend.icode.Primitives.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scala-compiler Show documentation
Show all versions of scala-compiler Show documentation
Compiler for the Scala Programming Language
/* NSC -- new scala compiler
* Copyright 2005-2013 LAMP/EPFL
* @author Martin Odersky
*/
package scala.tools.nsc
package backend
package icode;
import java.io.PrintWriter;
trait Primitives { self: 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. */
sealed abstract class TestOp {
/** Returns the negation of this operation. */
def negate(): TestOp
/** Returns a string representation of this operation. */
override def toString(): String
/** used only from GenASM */
def opcodeIF(): Int
/** used only from GenASM */
def opcodeIFICMP(): Int
}
/** An equality test */
case object EQ extends TestOp {
def negate() = NE
override def toString() = "EQ"
override def opcodeIF() = scala.tools.asm.Opcodes.IFEQ
override def opcodeIFICMP() = scala.tools.asm.Opcodes.IF_ICMPEQ
}
/** A non-equality test */
case object NE extends TestOp {
def negate() = EQ
override def toString() = "NE"
override def opcodeIF() = scala.tools.asm.Opcodes.IFNE
override def opcodeIFICMP() = scala.tools.asm.Opcodes.IF_ICMPNE
}
/** A less-than test */
case object LT extends TestOp {
def negate() = GE
override def toString() = "LT"
override def opcodeIF() = scala.tools.asm.Opcodes.IFLT
override def opcodeIFICMP() = scala.tools.asm.Opcodes.IF_ICMPLT
}
/** A greater-than-or-equal test */
case object GE extends TestOp {
def negate() = LT
override def toString() = "GE"
override def opcodeIF() = scala.tools.asm.Opcodes.IFGE
override def opcodeIFICMP() = scala.tools.asm.Opcodes.IF_ICMPGE
}
/** A less-than-or-equal test */
case object LE extends TestOp {
def negate() = GT
override def toString() = "LE"
override def opcodeIF() = scala.tools.asm.Opcodes.IFLE
override def opcodeIFICMP() = scala.tools.asm.Opcodes.IF_ICMPLE
}
/** A greater-than test */
case object GT extends TestOp {
def negate() = LE
override def toString() = "GT"
override def opcodeIF() = scala.tools.asm.Opcodes.IFGT
override def opcodeIFICMP() = scala.tools.asm.Opcodes.IF_ICMPGT
}
/** 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
}