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 parse(cls, stream: Stream) -> Union[None, String]: """ Parses a `String` from the `stream`, returning `None` if the nothing can be parsed. If a starting quote is matched and no ending quote is, then a `ParseError` will be raised. """ quote = stream.matches(String.BEGIN_REGEX) if not quote: return None regex = String.SINGLE_REGEX if quote == "'" else String.DOUBLE_REGEX body = stream.matches(regex, 1) if body is None: raise ParseError(f'unterminated string encountered: {stream}') else: return String(body)
def parse(cls, stream: Stream) -> Union[None, Boolean]: """ Parses a `Boolean` if the stream starts with `T` or `F`. """ if match := stream.matches(Boolean.REGEX, 1): return cls(match == 'T')
def parse(cls, stream: Stream) -> Union[None, Boolean]: """ Attempts to parse a `Boolean """ if match := stream.matches(r'([TF])[A-Z]*', 1): return cls(match == 'T')
def parse(cls, stream: Stream) -> Union[None, Null]: """ Parses `Null` if the stream starts with `N`. """ if match := stream.matches(r'N[A-Z]*'): return cls()
def parse(cls, stream: Stream) -> Union[None, Null]: """ Parses `Null` if the stream starts with `N`. """ if stream.matches(Null.REGEX): return cls() else: return None