Example #1
0
	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)
Example #2
0
    def parse(cls, stream: Stream) -> Union[None, Number]:
        """
		Parses a Number out from the stream.

		This returns `None` if the stream doesn't start with a digit.
		"""
        if match := stream.matches(Number.REGEX):
            return cls(int(match))
Example #3
0
	def parse(cls, stream: Stream) -> Union[None, Identifier]:
		"""
		Parses an Identifier out from the stream.

		This returns `None` if the stream doesn't start with a lowercase
		letter, or an underscore.
		"""
		if match := stream.matches(Identifier.REGEX):
			return cls(match)
Example #4
0
    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)
Example #5
0
 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')
Example #6
0
 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')
Example #7
0
 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()
Example #8
0
 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