//
// Copyright (c) 2010, Brian Frank and Andy Frank
// Licensed under the Academic Free License version 3.0
//
// History:
// 9 Nov 10 Brian Frank Creation
//
**
** COperators is used to manage methods annoated with the
** Operator facet for efficient operator method resolution.
**
class COperators
{
** Construct for given parent type
new make(CType parent)
{
this.parent = parent
parent.slots.each |slot|
{
if (slot is CMethod && slot.hasFacet("sys::Operator"))
{
prefix := toPrefix(slot.name)
if (prefix == null) echo("WARN: operator method has invalid perfix: $slot.qname")
else
{
acc := byPrefix[prefix]
if (acc == null) byPrefix[prefix] = acc = CMethod[,]
acc.add(slot)
}
}
}
}
**
** Given a method name get the operator prefix:
** "plus" => "plus"
** "plusInt" => "plus"
** "fooBar" => null
**
static Str? toPrefix(Str methodName)
{
exacts[methodName] ?: prefixes.find |p| { methodName.startsWith(p) }
}
**
** Get operators defined for prefix. For example:
** find("plus") => [plus, plusFloat, plusDecimal]
**
CMethod[] find(Str prefix)
{
byPrefix[prefix] ?: CMethod#.emptyList
}
private static const Str[] prefixes := ["get", "plus", "minus", "mult", "div", "mod"]
private static const Str:Str exacts := Str:Str[:].setList(prefixes).setList(["set", "negate", "increment", "decrement", "add"])
CType parent { private set }
private Str:CMethod[] byPrefix := [:]
}