#!/usr/bin/ruby
class Base { }
class Log < Base {}
class Exp < Base {}
class Sin < Base {}
class Exp(v) {
method *(Exp o) {
"Exp: #{self} * #{o}"
}
method *(Log o) {
"Exp: #{self} * #{o}"
}
method to_s {
"Exp"
}
}
class Log(v) {
method *(Log o) {
"Log: #{self} * #{o}"
}
method to_s {
"Log"
}
}
class Sin(v) {
method *(Log o) {
"Sin: #{self} * #{o}"
}
method to_s {
"Sin"
}
}
class Base {
method *(Exp o) {
"Base1: #{self} * #{o}"
}
method *(Object o) {
"Base2: #{self} * #{o}"
}
}
var e = Exp(1)
var l = Log(5)
var s = Sin(7)
say l*l
say l*e
say s*l
assert_eq(l*l, "Log: Log * Log")
assert_eq(l*e, "Base1: Log * Exp")
assert_eq(e*e, "Exp: Exp * Exp")
assert_eq(e*l, "Exp: Exp * Log")
assert_eq(e*s, "Base2: Exp * Sin")
assert_eq(l*s, "Base2: Log * Sin")
assert_eq(s*s, "Base2: Sin * Sin")
assert_eq(s*l, "Sin: Sin * Log")
assert_eq(s*e, "Base1: Sin * Exp")
assert_eq(l*3, "Base2: Log * 3")
assert_eq(e*4, "Base2: Exp * 4")
assert_eq(s*e, "Base1: Sin * Exp")