トランスレータ

上は、チェックのみだったのですが、下はscalaで書いた、トランスレータです。
mttというのか、どうかが分からないんで誰か助けて〜っていうかんじです。

abstract sealed class Exp
case class Add(l:Exp,r:Exp) extends Exp
case class Mul(l:Exp,r:Exp) extends Exp
case class Id(op:String) extends Exp
case class Num(op:Int) extends Exp
case class If(c:Exp, l:Exp, r:Exp) extends Exp
case class Nil extends Exp
case class C(l:Exp,r:Exp) extends Exp
case class Arr(l:Exp, r:Exp) extends Exp
case class Assign(l:Exp, r:Exp) extends Exp
case class Err(err:String,e:Any) extends Exp

object mtt extends Application {
	def trans(data:Any):Exp = {
		statement(data)
	}
	def statement(data:Any):Exp = {
		data match {
		case (l, "if", r)  => val c=exp(l); val (l2,r2)=else_(r); If(c, l2, r2)
		case (l, "@",  r)  => C(statement(l), statement(r))
		case _             => exp(data)
		}
	}
	def else_(data:Any):(Exp,Exp) = {
		data match {
		case (l,"else",r) => (exp(l), exp(r))
		case _            => (exp(data), Nil())
		}
	}

	def id(data:Any):Exp = {
		data match {
		case d:Int    => Num(d)
		case d:String => Id(d)
		case _        => Err("exprected id.",data)
		}
	}
	def assignLeft(data:Any):Exp = {
		data match {
		case (_,"[]",_) => arr(data)
		case _          => id(data)
		}
	}
	def arr(data:Any):Exp = {
		data match {
		case (l,"[]",r) => Arr(assignLeft(l), exp(r))
		case _          => Err("exptected arr", data)
		}
	}
	def exp(data:Any):Exp = {
		data match {
		case (l,"=",r) => Assign(assignLeft(l), exp(r))
		case (l,"+",r) => Add(exp(l), exp(r))
		case (l,"*",r) => Mul(exp(l), exp(r))
		case _         => id(data)
		}
	}

	def test(data:Any) {
		try {
			println(trans(data))
		} catch {
		case e => println(e+" "+data)
		}
	}

	test((1,"+", (2, "*", 3)));
	test((1,"*", (2, "+", 3)));
	test((1,"if", (2, "else", 3)));
	test((1,"if", (2, "els", 3)));
	test((1,"if", (2, "else", (3,"else",4) )));
	test((1,"if", 3));
	test((1,"@",(1,"if", 3)));
	test((1,"else",2));
	test(("a","=",2));
	test((("a","=","b"),"=",2));
	test(("a","=",("b","=",2)));
	test((("a","[]",2),"=",2));
	test((("a","[]",("a","=","b")),"=",2));
}