C2E

C言語様な言語をML様な言語に変換するプログラムを作ってみました。

package C2E

trait C
case class CInt(a:Int) extends C
case class CId(a:String) extends C
case class CAdd(a:C,b:C) extends C
case class CVal(a:String, b:C) extends C
case class CBlock(a:List[C]) extends C

trait E
case class EInt(a:Int) extends E
case class EAdd(a:E,b:E) extends E
case class ELet(a:String, b:E, c:E) extends E
case class EId(a:String) extends E
object EUnit extends E

object Main {
  def main(argv:Array[String]) {
    test(CInt(1),EInt(1))
    test(CId("a"), EId("a"))
    test(CAdd(CInt(1),CInt(2)), EAdd(EInt(1),EInt(2)))
    test(CVal("a", CInt(1)), ELet("a",EInt(1),EUnit))
    test(CBlock(List()), EUnit)

    test(CBlock(List(CInt(1))),EInt(1))
    test(CBlock(List(CId("a"))), EId("a"))
    test(CBlock(List(CAdd(CInt(1),CInt(2)))), EAdd(EInt(1),EInt(2)))
    test(CBlock(List(CVal("a", CInt(1)))), ELet("a",EInt(1),EUnit))
    test(CBlock(List(CBlock(List()))), EUnit)

    test(CBlock(List(CInt(1),CInt(1))),ELet("_",EInt(1),EInt(1)))
    test(CBlock(List(CInt(1),CInt(2),CInt(3))),ELet("_",EInt(1),ELet("_", EInt(2), EInt(3))))
    test(CBlock(List(CVal("a",CInt(1)),CId("a"))),ELet("a",EInt(1),EId("a")))
    test(CBlock(List(CVal("a",CInt(1)),CVal("b",CInt(2)))),ELet("a",EInt(1),ELet("b",EInt(2),EUnit)))
    // {{ val a = 1}; val b = 2}
    test(CBlock(List(CBlock(List(CVal("a",CInt(1)))),CVal("b",CInt(2)))),ELet("_",ELet("a",EInt(1),EUnit),ELet("b",EInt(2),EUnit)))
  }

  def test(c:C,e:E) {
    val e2 = c2e(c)
    if (e2 != e) throw new Exception("error "+c+"  expected "+e+" but found "+e2)
  }
}

object c2e {
  def apply(c:C):E = {
    c match {
      case CInt(a) => EInt(a)
      case CAdd(a,b) => EAdd(c2e(a), c2e(b))
      case CId(a) => EId(a)
      case CVal(a,b) => ELet(a, c2e(b), EUnit)
      case CBlock(a) => ls(a)
    }
  }
  def ls(l:List[C]):E = {
    l match {
      case List() => EUnit
      case List(a) => c2e(a)
      case CVal(a,b)::c => ELet(a, c2e(b), ls(c))
      case a::b => ELet("_", c2e(a), ls(b))
    }
  }
}