Beispiel #1
0
 def _visit_func_decl(self, node: ASTNode):
     # Only for member function
     node.record = Record(
         node.children[0].token.lexeme,
         SymbolType(node.children[2].token.lexeme, []),
         RecordType.FUNCTION,
         node.children[0].token.location,
         params=[param.record for param in node.children[1].children],
     )
Beispiel #2
0
 def _visit_func_param(self, node: ASTNode):
     node.record = Record(
         node.children[1].token.lexeme,  # ID
         SymbolType(
             node.children[0].token.lexeme,
             [child.token for child in node.children[2].children],
         ),
         RecordType.PARAM,
         node.children[1].token.location,
     )
Beispiel #3
0
 def _visit_var_decl(self, node: ASTNode):
     node.record = Record(
         node.children[1].token.lexeme,  # ID
         SymbolType(
             node.children[0].token.lexeme,
             [child.token for child in node.children[2].children],
         ),
         None,
         node.children[1].token.location,
     )
Beispiel #4
0
    def _type_for_data_member(
        self,
        node: ASTNode,
        types: List[SymbolType],
        records: List[Record],
        is_first: bool,
    ) -> SymbolType:
        token = node.children[0].token
        record = next(
            (r for r in records if r.record_type in DATA_RECORD_TYPES),
            None,
        )
        if record is None:
            self.error(
                'Use of undeclared {type} "{name}"'.format(
                    type="local variable" if is_first else "data member",
                    name=token.lexeme,
                ),
                token.location,
            )
            return None

        index_types = types or []
        if len(index_types) > len(record.type.dims) or any(
                type_ != SymbolType(INT, []) for type_ in index_types):
            self.error(
                'Invalid indexing for "{name}", type is "{type}"'.format(
                    name=token.lexeme, type=record.format_type()),
                token.location,
            )
            return None

        if index_types:
            # Reserve space for offset calculation
            node.temp_record = Record("", SymbolType(INT, []), RecordType.TEMP,
                                      None)
            self.scope.insert(node.temp_record)

        node.record = record
        return SymbolType(record.type.base,
                          record.type.dims[len(index_types):])
Beispiel #5
0
 def _visit_main(self, node: ASTNode):
     table = SymbolTable("main")
     for child in node.children[0].children:  # Locals
         table.insert(child.record)
     node.record = Record(
         "main",
         SymbolType("void", []),
         RecordType.FUNCTION,
         node.token.location,
         params=[],
         table=table,
     )
Beispiel #6
0
    def _visit_func_def(self, node: ASTNode):
        name = node.children[1].token.lexeme
        table = SymbolTable(name, is_function=True)
        params = [param.record for param in node.children[2].children]
        for param in params:
            table.insert(param)

        for child in node.children[4].children:  # Locals
            table.insert(child.record)

        node.record = Record(
            name,
            SymbolType(node.children[3].token.lexeme, []),
            RecordType.FUNCTION,
            node.children[1].token.location,
            params=params,
            table=table,
        )

        scope = node.children[0].token
        if scope:
            parent = BaseType(scope.lexeme).table
            if not parent:
                self.error(
                    'Use of undeclared class "{name}"'.format(
                        name=scope.lexeme),
                    scope.location,
                )
                return
            records = parent.entries.get(name, [])
            record = next(
                (r for r in records if r.record_type == RecordType.FUNCTION
                 and equal_params(r.params, params)
                 and r.type.base is node.record.type.base),
                None,
            )
            if not record:
                self.error(
                    'Member function "{scope}::{name}{type}" is defined but has not been declared'
                    .format(scope=scope.lexeme,
                            name=name,
                            type=node.record.format_type()),
                    scope.location,
                )
                return
            record.table = table  # Attach table on existing record in the class table
            table.inherits = [BaseType(scope.lexeme)]
            table.name = scope.lexeme + "::" + table.name
            node.record = record
        else:
            GLOBALS.insert(node.record)
Beispiel #7
0
 def _visit_rel_expr(self, node: ASTNode,
                     types: List[SymbolType]) -> SymbolType:
     if self._binary_op(node, types) is None:
         return None
     return SymbolType(BOOLEAN, [])
Beispiel #8
0
 def _visit_literal(self, node: ASTNode,
                    types: List[SymbolType]) -> SymbolType:
     if node.token.token_type == L.INTEGER_LITERAL:
         return SymbolType(INT, [])
     return SymbolType(FLOAT, [])