# object oriented programming - TODO
use IO.Std.write_line;
entry() is
let int_calculator = CALCULATOR(
[
("+", INTEGER_ADDITION()),
("-", INTEGER_SUBTRACTION()),
("*", INTEGER_MULTIPLICATION()),
("/", INTEGER_DIVISION())
]
);
write_line("1 + 2 = {int_calculator.calculate("+", 1, 2)}");
write_line("1 - 2 = {int_calculator.calculate("-", 1, 2)}");
write_line("1 * 2 = {int_calculator.calculate("*", 1, 2)}");
write_line("1 / 2 = {int_calculator.calculate("/", 1, 2)}");
write_line("1 + 2 - 3 = {int_calculator.calculate_from_memory("-", 3)}");
let string_calculator = CALCULATOR(
[
("+", STRING_CONCATENATION()),
("-", STRING_SUBTRACTION())
]
);
write_line("hello + world = {string_calculator.calculate("+", "hello", "world")}");
write_line("helloworld - world = {string_calculator.calculate("-", "helloworld", "world")}");
string_calculator.clear_memory();
write_line("memory is cleared");
si
trait Operation[T] is
execute(left: T, right: T) -> T;
si
class CALCULATOR[T] is
_operations: Collections.MAP[string, Operation[T]];
memory: T;
init(operations: Collections.Iterable[(name: string, operation: Operation[T])]) is
_operations =
Collections.MAP(
operations |
.map(on => let (name, operation) = on in Collections.KeyValuePair`2(name, operation)));
si
calculate(operation_name: string, left: T, right: T) -> T =>
if _operations.contains_key(operation_name) then
let operation = _operations[operation_name];
memory = operation.execute(left, right);
memory
else
throw System.InvalidOperationException("invalid operation {operation_name}")
fi;
calculate_from_memory(operation_name: string, right: T) -> T =>
if _operations.contains_key(operation_name) then
let operation = _operations[operation_name];
memory = operation.execute(memory, right);
memory
else
throw System.InvalidOperationException("invalid operation {operation_name}")
fi;
clear_memory() is
let def: T; // uninitialized variable has default value
memory = def;
si
si
class INTEGER_ADDITION: Operation[int] is
init() is si
execute(left: int, right: int) -> int => left + right;
si
class INTEGER_SUBTRACTION: Operation[int] is
init() is si
execute(left: int, right: int) -> int => left - right;
si
class INTEGER_MULTIPLICATION: Operation[int] is
init() is si
execute(left: int, right: int) -> int => left * right;
si
class INTEGER_DIVISION: Operation[int] is
init() is si
execute(left: int, right: int) -> int =>
if right == 0 then
throw System.InvalidOperationException("division by zero");
else
left / right
fi;
si
class STRING_CONCATENATION: Operation[string] is
init() is si
execute(left: string, right: string) -> string => left + right;
si
class STRING_SUBTRACTION: Operation[string] is
init() is si
execute(left: string, right: string) -> string => left.replace(right, "");
si