Пример #1
0
    def _read_type_usage(self):
        '''Read a type identifier, or array of type, etc. and return a SGType'''
        if self._match_lookahead('id', 'array', True):
            #found an array
            dimensions = []
            # array [0..n,0..m] of
            if self._match_lookahead('symbol', '[', True):
                while True:
                    low_idx = self._match_token('number')[1]
                    self._match_token('symbol', '.')
                    self._match_token('symbol', '.')
                    high_idx = self._match_token('number')[1]
                    dimensions.append((low_idx, high_idx))

                    if self._match_lookahead('symbol', ']', True):
                        break
                    self._match_token('symbol', ',')
            else:
                dimensions.append((0, 'n - 1'))

            # of type...
            self._match_token('id', 'of')
            nested_type = self._read_type_usage()  #recursive call

            name = nested_type.name + ''.join([
                '[%s..%s]' % (low_idx, high_idx)
                for low_idx, high_idx in dimensions
            ])
            was_new = not name in all_types()

            result = find_or_add_type(name)
            if was_new:
                result.dimensions = dimensions
                result.nested_type = nested_type
            return result
        elif self._match_lookahead('symbol', '^', True):
            other_id = self._match_token('id')[1]
            other_type = find_or_add_type(other_id)

            name = '^' + other_type.name

            was_new = not name in all_types()

            result = find_or_add_type(name)
            if was_new:
                result.is_pointer = True
                result.related_type = other_type
            return result
        else:
            id_tok = self._match_token('id')
            return find_or_add_type(id_tok[1])
Пример #2
0
 def _read_type_usage(self):
     '''Read a type identifier, or array of type, etc. and return a SGType'''
     if self._match_lookahead('id', 'array', True):
         #found an array
         dimensions = []
         # array [0..n,0..m] of
         if self._match_lookahead('symbol', '[', True):
             while True:
                 low_idx = self._match_token('number')[1]
                 self._match_token('symbol', '.')
                 self._match_token('symbol', '.')
                 high_idx = self._match_token('number')[1]
                 dimensions.append((low_idx,high_idx))
                 
                 if self._match_lookahead('symbol', ']', True):
                     break
                 self._match_token('symbol', ',')
         else:
             dimensions.append((0,'n - 1'))
         
         # of type...
         self._match_token('id', 'of')
         nested_type = self._read_type_usage() #recursive call
         
         name = nested_type.name + ''.join(['[%s..%s]' % (low_idx, high_idx) for low_idx, high_idx in dimensions])
         was_new = not name in all_types()
         
         result = find_or_add_type(name)
         if was_new:
             result.dimensions = dimensions
             result.nested_type = nested_type
         return result
     elif self._match_lookahead('symbol', '^', True):
         other_id = self._match_token('id')[1]
         other_type = find_or_add_type(other_id)
         
         name = '^' + other_type.name
         
         was_new = not name in all_types()
         
         result = find_or_add_type(name)
         if was_new:
             result.is_pointer = True
             result.related_type = other_type
         return result
     else:
         id_tok = self._match_token('id')
         return find_or_add_type(id_tok[1])
Пример #3
0
    def process_block_types(self, block, token):
        '''Reads the types within a type declaration'''
        logger.info(' Parser    : Processing types')
        logger.info('-' * 70)

        self.process_meta_comments()

        #following type... in pascal
        while True:
            type_name = self._match_token('id')[1]  #read the types name
            self._match_token('operator', '=')  #read the =

            the_type = find_or_add_type(type_name)
            the_type.file_line_details = self._tokeniser.line_details()
            the_type.meta_comment_line_details = self._tokeniser.meta_comment_line_details(
            )

            self._parse_type_declaration(the_type)

            if 'type' or 'class' or 'struct' in the_type.keys():
                self._add_class(the_type)

            self.process_meta_comments()

            tok1, tok2 = self._lookahead(2)
            #looking for... type_name =
            if tok2[0] != 'operator' or tok2[1] != '=' or tok1[0] != 'id':
                logger.info('-' * 70)
                logger.debug('Parser    : At end of block types')
                break
Пример #4
0
 def _parse_type_declaration(self, the_type):
     '''
     Parse a type from the next token, add details to the_type.
     this is called for each type declaration... type_name = BLAH
     Need to process BLAH and add details to the_type
     '''
     #check what kind of type it is...
     if self._match_lookahead('symbol', '(', True):
         values = []
         while not self._match_lookahead('symbol',')'):
             temp = self._match_token('id')[1]
             if self._match_lookahead('operator', '=', True) or self._match_lookahead('operator', ':=', True): #assigned value
                 values.append('%s = %s' % (temp, self._match_token('number')[1]))
             else:
                 values.append(temp)
             self._match_lookahead('symbol', ',', True) #consume commas
         self._match_token('symbol',')') #read close bracket
         the_type.values = tuple(values)
     elif (self._match_lookahead('id', 'packed', True) and self._match_lookahead('id', 'record', True)) or self._match_lookahead('id', 'record', True):
         #packed record field: Type end;
         while not self._match_lookahead('id', 'end', True):
             #read field
             variables = self._read_variable_list()
             self._match_token('symbol', ';')
             for name, data_type in variables:
                 field = SGField(name)
                 field.data_type = data_type
                 the_type.fields.append(field)
     elif self._match_lookahead('id', 'array') or self._match_lookahead('symbol', '^'):
         #is pointer or array
         the_type.clone(self._read_type_usage())
     elif self._match_lookahead('id', 'procedure', True):
         #procedure type: read ( params );
         self._match_token('symbol', '(')
         m = SGMethod(the_type.name)
         m.in_file = self._current_file
         self._read_params(m)
         the_type.is_procedure = True
         the_type.method = m
         if self._lookahead(2)[1][1] == 'cdecl':
             self._match_token('symbol', ';')
             self._match_token('id', 'cdecl')
     elif self._match_lookahead('id'):
         other_id = self._match_token('id')[1]
         other_type = find_or_add_type(other_id)
         the_type.related_type = other_type
     else:
         tok = self._next_token()
         logger.error('Parser Error %s: unknown type %s(%s)', 
             self._tokeniser.line_details(), tok[0], tok[1])
         assert False
             
     if the_type.related_type != None:
         logger.info(' Parser    : Setup type %s = %s', the_type, the_type.related_type)
     elif the_type.is_enum:
         logger.info(' Parser    : Setup type %s = %s', the_type, the_type.values)
     else:
         logger.info(' Parser    : Setup type %s = %s', the_type, the_type.fields)
     self._apply_attributes_to(the_type)
     self._match_token('symbol', ';')
Пример #5
0
 def process_block_types(self, block, token):
     '''Reads the types within a type declaration'''
     logger.info(' Parser    : Processing types')
     logger.info('-' * 70)
     
     self.process_meta_comments()
     
     #following type... in pascal
     while True:
         type_name = self._match_token('id')[1] #read the types name
         self._match_token('operator','=') #read the =
         
         the_type = find_or_add_type(type_name)
         the_type.file_line_details = self._tokeniser.line_details()
         the_type.meta_comment_line_details = self._tokeniser.meta_comment_line_details()
         
         self._parse_type_declaration(the_type)
         
         if 'type' or 'class' or 'struct'in the_type.keys():
             self._add_class(the_type)
         
         self.process_meta_comments()
         
         tok1, tok2 = self._lookahead(2)
         #looking for... type_name = 
         if tok2[0] != 'operator' or tok2[1] != '=' or tok1[0] != 'id':
             logger.info('-' * 70)
             logger.debug('Parser    : At end of block types')
             break
Пример #6
0
 def to_keyed_dict(self, doc_transform = None, type_visitor = None, array_idx_sep = ', ', param_visitor = None, map_data_value = None):
     """Export a keyed dictionary of the class for template matching"""
     
     import wrapper_helper
     
     result = dict()
     result['name'] = self.name
     result['name_lower'] = wrapper_helper.lower_name(self.name)
     result['camel_name'] = self.name.lower()[0] + self.name[1:]
     result['doc'] = doc_transform(self.doc) if doc_transform != None else self.doc
     result['static'] = 'static ' if self.is_static else ''
     result['sealed'] = 'sealed ' if self.is_module else ''
     
     if self.wraps_array:
         # add accessor methods
         main_type = self.data_type.related_type
         dim = main_type.dimensions
         data_type = find_or_add_type('longint')
         idx_type = type_visitor(data_type) if type_visitor != None else 'int'
         
         result['element.type'] = type_visitor(main_type.nested_type)
         
         if param_visitor == None:
             result['element.idx.params'] =  ', '.join([idx_type + ' idx%s' % i for i,d in enumerate(dim)])
         else:
             result['element.idx.params'] =  ''.join([param_visitor(SGParameter('idx%s' % i, data_type), i + 1 == len(dim)) for i,d in enumerate(dim)])
         
         result['element.idx.expr'] = array_idx_sep.join(['idx%s' % i for i,d in enumerate(dim)])
         
         result['element.access'] = map_data_value('return_val', main_type.nested_type, 'data[%(element.idx.expr)s]' % result)
         result['element.value'] = map_data_value('arg_val', main_type.nested_type, 'value')
     
     return result
Пример #7
0
def method_process_visitor(the_method, other):
    '''Process a method prior to rendering. This does all of the transformations
    that go into the functions and procedures of the SGSDK unit.'''

    # Change functions with string or array return type to have a result parameter
    if the_method.return_type != None and (
            the_method.return_type.wraps_array
            or the_method.return_type.name.lower() in ['string']):
        #print 'PARS RUN PARAMS', [p.name for p in the_method.params]
        result_param = SGParameter('result')

        for param in the_method.params:
            if 'result' == param.name:
                logger.error('PARSER RUN: Error adding result parameter to %s',
                             the_method.name)
                assert False
        _add_parameter(the_method, result_param)

        result_param.maps_result = True
        result_param.modifier = 'result'

        result_param.data_type = the_method.return_type

        the_method.return_type = None
        the_method.was_function = True
        #print 'PARS RUN PARAMS', [p.name for p in the_method.params]

    #Replace any variable length arrays
    orig_params = the_method.params
    for param in orig_params:
        #does it wrap a variable length array
        if param.data_type.array_wrapper:
            the_method.has_length_params = True
            logger.debug(
                'PARSER RUN: Altering variable length array of %s\'s parameter %s',
                the_method.name, param.name)
            # old_type = param.data_type
            #param.data_type = param.data_type #.fields[0].data_type
            len_param = SGParameter('%s_len' % param.name)
            len_param.is_length_param = True
            len_param.data_type = find_or_add_type('Longint')
            len_param.modifier = param.modifier if param.modifier is [
                'out', 'var'
            ] else None
            len_param.length_of = param
            param.has_length_param = True
            param.length_idx = _add_parameter(the_method, len_param)
    return other
Пример #8
0
def add_length_local(to_method, for_param):
    var_name = for_param.local_var_name() + '_len'
    local_var = SGParameter(var_name)
    local_var.is_length_param = True
    local_var.local_for = for_param
    local_var.data_type = find_or_add_type('Longint')
    local_var.modifier = for_param.modifier
    local_var.length_of = for_param
    
    for_param.length_param = local_var
    for_param.has_length_param = True
    
    to_method.local_vars.append(local_var)
    to_method.args.append(local_var.name)
    
    return local_var
Пример #9
0
def method_process_visitor(the_method, other):
    '''Process a method prior to rendering. This does all of the transformations
    that go into the functions and procedures of the SGSDK unit.'''
    
    # Change functions with string or array return type to have a result parameter
    if the_method.return_type != None and (the_method.return_type.wraps_array or the_method.return_type.name.lower() in ['string']):
        #print 'PARS RUN PARAMS', [p.name for p in the_method.params]
        result_param = SGParameter('result')
        
        for param in the_method.params:
            if 'result' == param.name:
                logger.error('PARSER RUN: Error adding result parameter to %s', the_method.name)
                assert False
        _add_parameter(the_method, result_param)
        
        result_param.maps_result = True
        result_param.modifier = 'result'
        
        result_param.data_type = the_method.return_type
        
        the_method.return_type = None
        the_method.was_function = True
        #print 'PARS RUN PARAMS', [p.name for p in the_method.params]
        
    #Replace any variable length arrays
    orig_params = the_method.params
    for param in orig_params:
        #does it wrap a variable length array
        if param.data_type.array_wrapper:
            the_method.has_length_params = True
            logger.debug('PARSER RUN: Altering variable length array of %s\'s parameter %s', the_method.name, param.name)
            # old_type = param.data_type
            #param.data_type = param.data_type #.fields[0].data_type
            len_param = SGParameter('%s_len' % param.name)
            len_param.is_length_param = True
            len_param.data_type = find_or_add_type('Longint')
            len_param.modifier = param.modifier if param.modifier is ['out', 'var'] else None
            len_param.length_of = param
            param.has_length_param = True
            param.length_idx = _add_parameter(the_method, len_param)
    return other
Пример #10
0
    def _parse_type_declaration(self, the_type):
        '''
        Parse a type from the next token, add details to the_type.
        this is called for each type declaration... type_name = BLAH
        Need to process BLAH and add details to the_type
        '''
        #check what kind of type it is...
        if self._match_lookahead('symbol', '(', True):
            values = []
            while not self._match_lookahead('symbol', ')'):
                temp = self._match_token('id')[1]
                if self._match_lookahead(
                        'operator', '=', True) or self._match_lookahead(
                            'operator', ':=', True):  #assigned value
                    values.append('%s = %s' %
                                  (temp, self._match_token('number')[1]))
                else:
                    values.append(temp)
                self._match_lookahead('symbol', ',', True)  #consume commas
            self._match_token('symbol', ')')  #read close bracket
            the_type.values = tuple(values)
        elif (self._match_lookahead('id', 'packed', True)
              and self._match_lookahead('id', 'record',
                                        True)) or self._match_lookahead(
                                            'id', 'record', True):
            #packed record field: Type end;
            while not self._match_lookahead('id', 'end', True):
                #read field
                variables = self._read_variable_list()
                self._match_token('symbol', ';')
                for name, data_type in variables:
                    field = SGField(name)
                    field.data_type = data_type
                    the_type.fields.append(field)
        elif self._match_lookahead('id', 'array') or self._match_lookahead(
                'symbol', '^'):
            #is pointer or array
            the_type.clone(self._read_type_usage())
        elif self._match_lookahead('id', 'procedure', True):
            #procedure type: read ( params );
            self._match_token('symbol', '(')
            m = SGMethod(the_type.name)
            m.in_file = self._current_file
            self._read_params(m)
            the_type.is_procedure = True
            the_type.method = m
            if self._lookahead(2)[1][1] == 'cdecl':
                self._match_token('symbol', ';')
                self._match_token('id', 'cdecl')
        elif self._match_lookahead('id'):
            other_id = self._match_token('id')[1]
            other_type = find_or_add_type(other_id)
            the_type.related_type = other_type
        else:
            tok = self._next_token()
            logger.error('Parser Error %s: unknown type %s(%s)',
                         self._tokeniser.line_details(), tok[0], tok[1])
            assert False

        if the_type.related_type != None:
            logger.info(' Parser    : Setup type %s = %s', the_type,
                        the_type.related_type)
        elif the_type.is_enum:
            logger.info(' Parser    : Setup type %s = %s', the_type,
                        the_type.values)
        else:
            logger.info(' Parser    : Setup type %s = %s', the_type,
                        the_type.fields)
        self._apply_attributes_to(the_type)
        self._match_token('symbol', ';')