def semantic_check(self, scope: IdentScope) -> None: if scope.curr_func: self.semantic_error( "Объявление функции ({}) внутри другой функции не поддерживается" .format(self.name.name)) parent_scope = scope self.type.semantic_check(scope) scope = IdentScope(scope) # временно хоть какое-то значение, чтобы при добавлении параметров находить scope функции scope.func = EMPTY_IDENT params = [] for param in self.params: # при проверке параметров происходит их добавление в scope param.semantic_check(scope) params.append(param.type.type) type_ = TypeDesc(None, self.type.type, tuple(params)) func_ident = IdentDesc(self.name.name, type_) scope.func = func_ident self.name.node_type = type_ try: self.name.node_ident = parent_scope.curr_global.add_ident( func_ident) except SemanticException as e: self.name.semantic_error("Повторное объявление функции {}".format( self.name.name)) self.body.semantic_check(scope) self.node_type = TypeDesc.VOID
def semantic_check(self, scope: IdentScope) -> None: self.cond.semantic_check(scope) self.cond = type_convert(self.cond, TypeDesc.BOOL, None, 'условие') self.then_stmt.semantic_check(IdentScope(scope)) if self.else_stmt: self.else_stmt.semantic_check(IdentScope(scope)) self.node_type = TypeDesc.VOID
def semantic_check(self, scope: IdentScope) -> None: scope = IdentScope(scope) if self.cond == EMPTY_STMT: self.cond = LiteralNode('true') self.cond.semantic_check(scope) self.cond = type_convert(self.cond, TypeDesc.BOOL, None, 'условие') self.stmt.semantic_check(IdentScope(scope)) self.node_type = TypeDesc.VOID
def semantic_check(self, scope: IdentScope) -> None: self.type.semantic_check(scope) for var in self.vars: var_node: IdentNode = var.var if isinstance(var, AssignNode) else var try: scope.add_ident(IdentDesc(var_node.name, self.type.type)) except SemanticException as e: var_node.semantic_error(e.message) var.semantic_check(scope) self.node_type = TypeDesc.VOID
def semantic_check(self, scope: IdentScope) -> None: self.val.semantic_check(IdentScope(scope)) func = scope.curr_func if func is None: self.semantic_error('Оператор return применим только к функции') self.val = type_convert(self.val, func.func.type.return_type, self, 'возвращаемое значение') self.node_type = TypeDesc.VOID
def semantic_check(self, scope: IdentScope) -> None: self.type.semantic_check(scope) self.name.node_type = self.type.type try: self.name.node_ident = scope.add_ident( IdentDesc(self.name.name, self.type.type, ScopeType.PARAM)) except SemanticException: raise self.name.semantic_error('Параметр {} уже объявлен'.format( self.name.name)) self.node_type = TypeDesc.VOID
def semantic_check(self, scope: IdentScope) -> None: func = scope.get_ident(self.func.name) if func is None: self.semantic_error('Функция {} не найдена'.format(self.func.name)) if not func.type.func: self.semantic_error('Идентификатор {} не является функцией'.format( func.name)) if len(func.type.params) != len(self.params): self.semantic_error( 'Кол-во аргументов {} не совпадает (ожидалось {}, передано {})' .format(func.name, len(func.type.params), len(self.params))) params = [] error = False decl_params_str = fact_params_str = '' for i in range(len(self.params)): param: ExprNode = self.params[i] param.semantic_check(scope) if (len(decl_params_str) > 0): decl_params_str += ', ' decl_params_str += str(func.type.params[i]) if (len(fact_params_str) > 0): fact_params_str += ', ' fact_params_str += str(param.node_type) try: params.append(type_convert(param, func.type.params[i])) except: error = True if error: self.semantic_error( 'Фактические типы ({1}) аргументов функции {0} не совпадают с формальными ({2})\ и не приводимы'.format( func.name, fact_params_str, decl_params_str)) else: self.params = tuple(params) self.func.node_type = func.type self.func.node_ident = func self.node_type = func.type.return_type
def semantic_check(self, scope: IdentScope) -> None: if not self.program: scope = IdentScope(scope) for expr in self.exprs: expr.semantic_check(scope) self.node_type = TypeDesc.VOID
def semantic_check(self, scope: IdentScope) -> None: ident = scope.get_ident(self.name) if ident is None: self.semantic_error('Идентификатор {} не найден'.format(self.name)) self.node_type = ident.type self.node_ident = ident