Created
June 1, 2020 20:24
-
-
Save stewSquared/b5d3b3439c78fe7294123a7a68f0660e to your computer and use it in GitHub Desktop.
Simple translation to ByteCode example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import scala.collection.mutable.ListBuffer | |
sealed trait ByteCode | |
object ByteCode { | |
case class Push(n: Int) extends ByteCode | |
case object Add extends ByteCode | |
} | |
sealed trait Instruction | |
sealed trait Exp extends Instruction | |
case class Declare(name: String, value: Primitive) extends Instruction | |
case class Add(expa: Exp, expb: Exp) extends Exp | |
case class Read(name: String) extends Exp | |
case class Primitive(n: Int) extends Exp | |
case object Program { | |
import collection.mutable.Map | |
def translate(program: List[Instruction]): List[ByteCode] = { | |
val table: Map[String, Int] = Map.empty | |
val bytecode: ListBuffer[ByteCode] = new ListBuffer | |
def eval(exp: Exp): Unit = exp match { | |
case Primitive(n: Int) => | |
bytecode += ByteCode.Push(n) | |
case Add(a: Exp, b: Exp) => | |
eval(a) | |
eval(b) | |
bytecode += ByteCode.Add | |
case Read(name) => | |
table.get(name).map { value => | |
bytecode += ByteCode.Push(value) | |
}.getOrElse { | |
throw new Exception(s"Compilation error: lookup on undeclared variable: $name") | |
} | |
} | |
program.foreach { | |
case Declare(name, Primitive(n)) => table(name) = n | |
case exp: Exp => eval(exp) | |
} | |
bytecode.toList | |
} | |
} | |
object example extends App { | |
val program = List( | |
Declare("x", Primitive(3)), | |
Declare("y", Primitive(4)), | |
Add(Primitive(8), Add(Read("x"), Read("y"))) | |
) | |
Program.translate(program) foreach println | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment