Ejemplo n.º 1
0
    def __parse_define(self, start_point_loc):
        '''
        Private function to parse a single DEFINE expression. The _file
        variable should be in a state starting with (without quotes):
        '<name> (<arg1> <arg2> ...) <body1> <body2> ...)'
        That is, the '(define ' section has alread been read.

        Returns an instance of Define()
        '''

        # Get the return type and function name.
        (l, def_return_type) = self.__parse_word_with_loc()
        if def_return_type == 'list':
            list_type = self.__parse_type()
            if list_type == Type.INT:
                def_return_type = Type.LIST_INT
            elif list_type == Type.FLOAT:
                def_return_type = Type.LIST_FLOAT
            elif list_type == Type.STRING:
                def_return_type = Type.LIST_STRING
            else:
                error_str = '__parse_define cannot get here'
                raise error.InternalError(l, error_str)
        else:
            def_return_type = Type.str_to_type(l, def_return_type)

        def_name = self.__parse_word()

        # Parse the ':' between function name and start of arguments.
        c = self.__eat_whitespace()
        if c == '':
            # The end of file was reached.
            loc = self.__get_point_loc(True).span(self.__get_point_loc())
            raise error.Syntax(loc, f'unexpected end of file')

        if c != ':':
            loc = self.__get_point_loc(True).span(self.__get_point_loc())
            raise error.Syntax(loc, f'expected ":" but found "{c}"')

        # Parse the arguments.
        def_args = []

        while True:
            (l, maybe_type) = self.__parse_word_with_loc()

            # Check if the end of the arguments has been reached.
            if maybe_type == ':':
                break

            # There is another argument to parse.
            arg_type = None
            if maybe_type == 'list':
                list_type = self.__parse_type()
                if list_type == Type.INT:
                    arg_type = Type.LIST_INT
                elif list_type == Type.FLOAT:
                    arg_type = Type.LIST_FLOAT
                elif list_type == Type.STRING:
                    arg_type = Type.LIST_STRING
                else:
                    error_str = '__parse_define cannot get here'
                    raise error.InternalError(l, error_str)
            else:
                arg_type = Type.str_to_type(l, maybe_type)

            arg_name = self.__parse_word()

            def_args.append((arg_type, arg_name))

        # Parse the body expressions.
        def_body = []

        while True:
            e = self.__parse_expr(parsing_exprs_list=True)

            if e is None:
                break

            def_body.append(e)

        # Now the entire function has been parsed.
        loc = start_point_loc.span(self.__get_point_loc())
        return Define(loc, def_return_type, def_name, def_args, def_body)
Ejemplo n.º 2
0
 def __parse_type(self):
     ''' Private function to parse a single type. '''
     (loc, word) = self.__parse_word_with_loc()
     return Type.str_to_type(loc, word)