暗黙的型変換

ここの所は、夏の疲れがまだ取れないって感じなのですが、ちょっとだけ進めました。
この間のソースはコンパイルすら通らないという、どんだけやる気なかったのかと思ったりします。
思ったりするけど、まぁ、何も書かないよりは良い。ちょっとでも進み続ける。コレ大事だと思うのでした。
とりあえず、最後のコードが通ってないのと例外投げまくりなのが問題なのでなんとかしないとなっと。

package type5;

object Main {

  trait TType
  case class TFloat() extends TType
  case class TInt() extends TType
  case class TNone() extends TType
  case class TStr() extends TType
  case class TFun(prms:List[TType],rc:TType) extends TType
  sealed abstract case class E(t:TType)
  case class EId(s:String) extends E(TStr())
  case class ECast(override val t:TType, a:E) extends E(t)
  case class EInt(override val t:TType, a:scala.Int) extends E(t)
  case class EFloat(override val t:TType, a:Double) extends E(t)
  case class ECall(override val t:TType, f:E, a:List[E]) extends E(t)

  def main(argv:Array[String]) {
    println("*"+f(ECall(TNone(),EId("add"),List(EFloat(TFloat(),1),EInt(TInt(),2)))))
    println("*"+f(ECall(TNone(),EId("add"),List(EInt(TInt(),1),EInt(TInt(),2)))))
    println("*"+f(ECall(TNone(),EId("add"), List(ECall(TNone(),EId("add"),List(EFloat(TFloat(),1),EInt(TInt(),1))),EInt(TInt(),2)))))
  }

  def f(e:E):E = e match {
    case ECast(t,a) => ECast(t, f(a))
    case EInt(t,i) => EInt(TInt(), i)
    case EFloat(t,i) => EFloat(TFloat(), i)
    case ECall(t,id,xs) =>
      println("xs "+xs)
      val fns = f(id) match {
        case EId(a) => functions(a)
        case _ => throw new Exception("not found method "+id)
      }
      def tpc(ts:List[TType],es:List[E]):Boolean = {
        (ts,es) match {
          case (List(),List()) => true
          case (t::ts,e::es) => if(t!=e.t) false else tpc(ts,es)
          case _ => false
        }
      }
      //println("fns "+fns)
      for(i <- fns) {
        i match {
          case TFun(l,r) =>
           //println("tfun "+l+" "+r)
           if (tpc(l, xs)) return ECall(i,id, xs.map(f))
          case _ => throw new Exception("not found method")
        }
      }
      def tpc2(ts:List[TType],es:List[E]):List[E] = {
        //println("tpc2 "+(ts,es))
        (ts,es) match {
          case (List(),List()) => List()
          case (t::ts,e::es) =>
            println("koko "+t+" "+e)
            if(t==e.t) {
              e::tpc2(ts,es)
            } else if(implicitConversions.contains(t->e.t)){
              println("contains implicits "+t + " "+e)
              implicitConversions(t->e.t)(e)::tpc2(ts,es)

            } else {
              throw new Exception("error")
            }
          case _ => throw new Exception("error")
        }
      }
      // そのままの型がないので暗黙の型変換を探す
      for(i <- fns) {
        try {
          i match {
            case TFun(l,r) =>
              return ECall(i,id, tpc2(l, xs).map(f))
            case _ =>
          }

        } catch {
          case e:Exception =>
        }
      }
      throw new Exception("not found method "+e)
    case EId(a) => EId(a)
  }

  def typs(e:E):TType = e.t
  
  // 関数定義表

  var functions = Map[String,List[TType]](
    "add"->List(
	  TFun(List(TInt(),TInt()),TInt()),
      TFun(List(TStr(),TStr()),TStr()),
      TFun(List(TFloat(),TFloat()),TFloat())
	  )
  )

  // 暗黙の型変換の表
  var implicitConversions = Map[(TType,TType),(E)=>E] (
    (TInt(),TStr()) -> ((a:E)=>ECast(TStr(),a)),
    (TFloat(),TStr()) -> ((a:E)=>ECast(TStr(),a)),
    (TFloat(),TInt()) -> ((a:E)=>ECast(TFloat(),a))
  )
}