EpRe1

Mein Scala Source für Expression Problem Lit.LS10 mit Registrierung:

  • nur oo dispatching
  • zweimal type cast
// register operation by Data subtypes

// traits
trait Op {
	def evalOp(d: BaseD): Int
}
trait BaseD {
	def op: Op
}

// primary implementation IntD with eval
class IntD(val value: Int) extends BaseD {
	def op() = IntD.op
}
class IntEval extends Op {
	def evalOp(d: BaseD) = d.asInstanceOf[IntD].value
}
object IntD {
	var op: Op = new IntEval()
}
object eval {
    def apply(d: BaseD) = d.op.evalOp(d)
}

// data extension: PlusD
class PlusEval extends Op {
	def evalOp(d: BaseD) = eval(d.asInstanceOf[PlusD].l) + eval(d.asInstanceOf[PlusD].r)
}
class PlusD(val l: BaseD, val r: BaseD) extends BaseD {
	def op = PlusD.op
}
object PlusD {
	var op = new PlusEval
}

// operation extension
trait ReprOp extends Op {
	def reprOp(d: BaseD): String
}
class IntRepr extends IntEval with ReprOp {
	def reprOp(d: BaseD) =  d.asInstanceOf[IntD].value.toString
}
class PlusRepr extends PlusEval with ReprOp {
	def reprOp(d: BaseD) =  {val r = d.asInstanceOf[PlusD]; repr(r.l) + '+' + repr(r.r)}
}
object repr {
    def apply(d: BaseD) : String = 
	{ 	d.op match  
		{
			case r: ReprOp => r.reprOp(d)
			case r         => 
			{
				println("repr ini .....")
				IntD.op = new IntRepr()
				PlusD.op = new PlusRepr()
				repr(d)
			}
		}
	}
}

// show the elements
object EpReg1 { def show =
	{
		val i1 = new IntD(11)
		val i2 = new IntD(22)
		val p3 = new PlusD(i1, i2)
		val p4 = new PlusD(p3, new PlusD(new IntD(4), new IntD(44)))
		var nm : String = "??"
		for (e <- List("i1", i1, "i2", i2, "p3", p3, "p4", p4)) {
			e match {
				case s: String => nm = s
				case d: BaseD => { println(nm + " " + d  + " eval " + eval(d))
								   println(   "   " + d  + " eval " + eval(d) + " repr " + repr(d)) 
				}
			}
		}
	}
}