refactor: abstracted operations, used trait Operand
This commit is contained in:
parent
32622cdd7e
commit
4e58e41a2a
@ -1,17 +1,27 @@
|
|||||||
package wacc
|
package wacc
|
||||||
|
|
||||||
object assemblyIR {
|
object assemblyIR {
|
||||||
|
|
||||||
|
sealed trait Operand
|
||||||
|
|
||||||
|
// did not use option because we'd have to wrap each op around Some(). can refactor
|
||||||
|
case object NoOperand extends Operand {
|
||||||
|
override def toString = ""
|
||||||
|
}
|
||||||
|
sealed trait Src extends Operand // mem location, register and imm value
|
||||||
|
sealed trait Dest extends Operand // mem location and register
|
||||||
enum RegSize {
|
enum RegSize {
|
||||||
case R64
|
case R64
|
||||||
case E32
|
case E32
|
||||||
|
|
||||||
override def toString: String = this match {
|
override def toString = this match {
|
||||||
case R64 => "r"
|
case R64 => "r"
|
||||||
case E32 => "e"
|
case E32 => "e"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum CLibFunc {
|
//arguments
|
||||||
|
enum CLibFunc extends Operand {
|
||||||
case Scanf,
|
case Scanf,
|
||||||
Puts,
|
Puts,
|
||||||
Fflush,
|
Fflush,
|
||||||
@ -20,7 +30,7 @@ object assemblyIR {
|
|||||||
|
|
||||||
private val plt = "@plt"
|
private val plt = "@plt"
|
||||||
|
|
||||||
override def toString: String = this match {
|
override def toString = this match {
|
||||||
case Scanf => "scanf" + plt
|
case Scanf => "scanf" + plt
|
||||||
case Puts => "puts" + plt
|
case Puts => "puts" + plt
|
||||||
case Fflush => "fflush" + plt
|
case Fflush => "fflush" + plt
|
||||||
@ -29,40 +39,59 @@ object assemblyIR {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Register {
|
enum Register extends Dest with Src {
|
||||||
case Named(name: String, size: RegSize)
|
case Named(name: String, size: RegSize)
|
||||||
case Scratch(num: Int, size: RegSize)
|
case Scratch(num: Int, size: RegSize)
|
||||||
override def toString: String = this match {
|
override def toString = this match {
|
||||||
case Named(name, size) => s"${size}${name}"
|
case Named(name, size) => s"${size}${name.toLowerCase()}"
|
||||||
case Scratch(num, size) => s"${size}${num}"
|
case Scratch(num, size) => s"${size}${num}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case class MemLocation(pointer: Long)
|
case class MemLocation(pointer: Long | Register) extends Dest with Src {
|
||||||
case class ImmediateVal(value: Int)
|
override def toString = pointer match {
|
||||||
|
case hex: Long => f"[0x$hex%X]"
|
||||||
|
case reg: Register => s"[$reg]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case class ImmediateVal(value: Int) extends Src {
|
||||||
|
override def toString = s"#${value.toString}"
|
||||||
|
}
|
||||||
|
|
||||||
|
case class LabelArg(name: String) extends Operand {
|
||||||
|
override def toString = name
|
||||||
|
}
|
||||||
|
|
||||||
//TODO Check if dest and src are not both memory locations
|
//TODO Check if dest and src are not both memory locations
|
||||||
sealed trait noDupeMemLoc
|
abstract class Operation(ins: String, op1: Operand = NoOperand, op2: Operand = NoOperand) {
|
||||||
|
override def toString: String = if (op2 == NoOperand) {
|
||||||
|
s"$ins ${op1.toString}"
|
||||||
|
} else {
|
||||||
|
s"$ins ${op1.toString}, ${op2.toString}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case class Add(op1: Dest, op2: Src) extends Operation("add", op1, op2)
|
||||||
|
case class Subtract(op1: Dest, op2: Src) extends Operation("sub", op1, op2)
|
||||||
|
case class Multiply(op1: Src) extends Operation("mul", op1)
|
||||||
|
case class Divide(op1: Src) extends Operation("div", op1)
|
||||||
|
|
||||||
// object noDupeMemLoc {
|
case class And(op1: Dest, op2: Src) extends Operation("and", op1, op2)
|
||||||
// def apply(dest: Register | MemLocation, src: Register | MemLocation | ImmediateVal) : noDupeMemLoc {
|
case class Or(op1: Dest, op2: Src) extends Operation("or", op1, op2)
|
||||||
// require(!(dest.isInstanceOf[MemLocation] && src.isInstanceOf[MemLocation]))
|
case class Compare(op1: Dest, op2: Src) extends Operation("cmp", op1, op2)
|
||||||
// }
|
|
||||||
// }
|
|
||||||
case class Add(dest: Register | MemLocation, src: Register | MemLocation | ImmediateVal) extends noDupeMemLoc
|
|
||||||
case class Subtract(dest: Register | MemLocation, src: Register | MemLocation | ImmediateVal) extends noDupeMemLoc
|
|
||||||
case class Multiply(src: Register)
|
|
||||||
case class Divide(src: Register)
|
|
||||||
|
|
||||||
case class And(dest: Register | MemLocation, src: Register | MemLocation | ImmediateVal) extends noDupeMemLoc
|
//stack operations
|
||||||
case class Or(dest: Register | MemLocation, src: Register | MemLocation | ImmediateVal) extends noDupeMemLoc
|
case class Push(op1: Src) extends Operation("push", op1)
|
||||||
case class Compare(dest: Register | MemLocation, src: Register | MemLocation | ImmediateVal) extends noDupeMemLoc
|
case class Pop(op1: Src) extends Operation("pop", op1)
|
||||||
|
case class Call(op1: CLibFunc) extends Operation("call", op1)
|
||||||
|
|
||||||
case class Call(func: CLibFunc)
|
case class Return() extends Operation("ret")
|
||||||
|
|
||||||
case class Push(src: Register | MemLocation | ImmediateVal)
|
case class Jump(op1: LabelArg) extends Operation("jmp", op1)
|
||||||
case class Pop(src: Register | MemLocation | ImmediateVal)
|
case class JumpIfEqual(op1: LabelArg) extends Operation("je", op1)
|
||||||
|
|
||||||
case class Jump()
|
case class LabelDef(name: String) {
|
||||||
|
override def toString = s"$name:"
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user