49 lines
1020 B
Python
49 lines
1020 B
Python
from itertools import islice
|
|
from typing import Callable, Optional, Union
|
|
|
|
from src.tokentypes.types import Number, ArgumentsError
|
|
|
|
|
|
def if_else(
|
|
condition: Number,
|
|
if_cb: Callable,
|
|
else_cb: Optional[Callable] = None) -> Number:
|
|
if else_cb is None:
|
|
return _if(condition, if_cb)
|
|
|
|
return if_cb() if condition else else_cb()
|
|
|
|
|
|
def _if(condition: Number, cb: Callable) -> int:
|
|
return cb() if condition else 0
|
|
|
|
|
|
def while_(condition: Callable, body: Callable) -> int:
|
|
while condition():
|
|
body()
|
|
|
|
return 0
|
|
|
|
|
|
def branch(*values: Union[Number, Callable]) -> int:
|
|
"""
|
|
This is also kind of if, but a bit better
|
|
"""
|
|
|
|
if len(values) < 2 or callable(values[0]):
|
|
raise ArgumentsError("invalid arguments")
|
|
|
|
pairs = zip(
|
|
islice(values, None, None, 2),
|
|
islice(values, 1, None, 2)
|
|
)
|
|
|
|
for cond, callback in pairs:
|
|
if cond:
|
|
return callback()
|
|
|
|
if len(values) % 2:
|
|
return values[-1]()
|
|
|
|
return 0
|