63 lines
1.4 KiB
Plaintext
63 lines
1.4 KiB
Plaintext
import morfa.base;
|
|
|
|
template <T>
|
|
public struct Dynamic
|
|
{
|
|
var data: Dict<text, T>;
|
|
}
|
|
|
|
// convenience to create new Dynamic instances
|
|
template <T>
|
|
public property dynamic(): Dynamic<T>
|
|
{
|
|
return Dynamic<T>(new Dict<text,T>());
|
|
}
|
|
|
|
// introduce replacement operator for . - a quoting ` operator
|
|
public operator ` { kind = infix, precedence = max, associativity = left, quoting = right }
|
|
template <T>
|
|
public func `(d: Dynamic<T>, name: text): DynamicElementAccess<T>
|
|
{
|
|
return DynamicElementAccess<T>(d, name);
|
|
}
|
|
|
|
// to allow implicit cast from the wrapped instance of T (on access)
|
|
template <T>
|
|
public func convert(dea: DynamicElementAccess<T>): T
|
|
{
|
|
return dea.holder.data[dea.name];
|
|
}
|
|
|
|
// cannot overload assignment - introduce special assignment operator
|
|
public operator <- { kind = infix, precedence = assign }
|
|
template <T>
|
|
public func <-(access: DynamicElementAccess<T>, newEl: T): void
|
|
{
|
|
access.holder.data[access.name] = newEl;
|
|
}
|
|
|
|
func main(): void
|
|
{
|
|
var test = dynamic<int>;
|
|
|
|
test`a <- 10;
|
|
test`b <- 20;
|
|
test`a <- 30;
|
|
|
|
println(test`a, test`b);
|
|
}
|
|
|
|
// private helper structure
|
|
template <T>
|
|
struct DynamicElementAccess
|
|
{
|
|
var holder: Dynamic<T>;
|
|
var name: text;
|
|
|
|
import morfa.io.format.Formatter;
|
|
public func format(formatt: text, formatter: Formatter): text
|
|
{
|
|
return getFormatFunction(holder.data[name])(formatt, formatter);
|
|
}
|
|
}
|