def assign(name: Value, value: Value) -> Value: """ Assigns `value` to `name`, where `name` must be an `Identifier`. Returns `value`. """ value = value.run() name.assign(value) return value
def assign(name: Value, value: Value) -> Value: """ Assigns `value` to `name`, converting `name` to an `Identifier` if it isn't already. Returns `value`. """ if not isinstance(name, Identifier): name = Identifier(str(name)) value = value.run() name.assign(value) return value
def dump(arg: Value) -> Value: """ Dumps a debug representation of `arg` and returns `arg`. """ arg = arg.run() print(repr(arg), end='') return arg
def parse(stream: Stream) -> Union[None, Function]: """ Parses a `Function` from the stream, returning `None` if the stream didn't start with a function character. This will both parse the function name, and its arguments. If not all the arguments could be parsed, a `ParseError` is raised. """ name = stream.peek() if name not in _FUNCS: return None func = _FUNCS[name] stream.matches(Function.REGEX) args = [] for arg in range(func.__code__.co_argcount): value = Value.parse(stream) if value is None: raise ParseError(f'Missing argument {arg} for function {name}') args.append(value) return Function(func, name, args)
def eval_(text: Value) -> Value: """ Evaluates `text` as Knight code, returning its result. """ value = Value.parse(Stream(str(text))) if value is None: raise ParseError('Nothing to parse.') else: return value.run()
def pow(lhs: Value, rhs: Value) -> Value: """ Exponentiates `lhs` by `rhs`. """ return lhs.run() ** rhs.run()
def while_(cond: Value, body: Value) -> Null: """ Executes `body` while `cond` is truthy. """ while cond: body.run() return Null()
def then(lhs: Value, rhs: Value) -> Value: """ Simply executes `lhs`, then `rhs`, then returns `rhs`. """ lhs.run() return rhs.run()
def or_(lhs: Value, rhs: Value) -> Value: """ Returns `lhs` if its truthy, otherwise `rhs`. """ return lhs.run() or rhs.run()
def and_(lhs: Value, rhs: Value) -> Value: """ Returns `lhs` if its falsey, otherwise `rhs`. """ return lhs.run() and rhs.run()
def eql(lhs: Value, rhs: Value) -> Boolean: """ Checks to see if `lhs` is equal to `rhs`. """ return Boolean(lhs.run() == rhs.run())
def gth(lhs: Value, rhs: Value) -> Boolean: """ Checks to see if `lhs` is greater than `rhs`. """ return Boolean(lhs.run() > rhs.run())
def mod(lhs: Value, rhs: Value) -> Value: """ Modulos `lhs` by `rhs`. """ return lhs.run() % rhs.run()
def div(lhs: Value, rhs: Value) -> Value: """ Divides `lhs` by `rhs`. """ return lhs.run() // rhs.run()
def mul(lhs: Value, rhs: Value) -> Value: """ Multiplies `lhs` by `rhs`. """ return lhs.run() * rhs.run()
def sub(lhs: Value, rhs: Value) -> Value: """ Subtracts `rhs` from `lhs`. """ return lhs.run() - rhs.run()
def add(lhs: Value, rhs: Value) -> Value: """ Adds `rhs` to `lhs`. """ return lhs.run() + rhs.run()
def call(blk: Value) -> Value: """ Executes the return value of a `block`. """ return blk.run().run()
def lth(lhs: Value, rhs: Value) -> Boolean: """ Checks to see if `lhs` is less than `rhs`. """ return Boolean(lhs.run() < rhs.run())