public override void CheckSemantic(SymbolTable symbolTable, List <CompileError> errors) { ///check semantics al CallableDeclarationNode base.CheckSemantic(symbolTable, errors); ///si BodyExpression no evaluó de error if (!Object.Equals(CallableBody.NodeInfo, SemanticInfo.SemanticError)) { ///el procedimiento debe retornar void if (!CallableBody.NodeInfo.BuiltInType.IsCompatibleWith(BuiltInType.Void)) { errors.Add(new CompileError { Line = CallableBody.Line, Column = CallableBody.CharPositionInLine, ErrorMessage = string.Format("Cannot implicitly convert type '{0}' to 'void'", CallableBody.NodeInfo.Type.Name), Kind = ErrorKind.Semantic }); ///el nodo evalúa de error NodeInfo = SemanticInfo.SemanticError; } } ///si no ha evaluado de error le seteamos los valores if (!Object.Equals(NodeInfo, SemanticInfo.SemanticError)) { NodeInfo = new SemanticInfo { Name = SemanticInfo.NoName, ElementKind = SymbolKind.NoSymbol, Type = SemanticInfo.Void, BuiltInType = BuiltInType.Void, ILType = null }; SemanticInfo arg; ///guardamos los ILType for (int i = 0; i < Parameters.Count; i++) { symbolTable.GetDefinedTypeDeep(Parameters[i].Value, out arg); ILTypes.Add(arg.Type.ILType); } } SemanticInfo procedure; ///completamos la definición del procedimiento symbolTable.GetDefinedCallableDeep(CallableId, out procedure); procedure.IsPending = false; }
public override void CheckSemantic(SymbolTable symbolTable, List <CompileError> errors) { ///check semantics al CallableDeclarationNode base.CheckSemantic(symbolTable, errors); SemanticInfo returnTypeInfo; ///chequeamos si existe el tipo de retorno if (!symbolTable.GetDefinedTypeDeep(ReturnType, out returnTypeInfo)) { errors.Add(new CompileError { Line = GetChild(ChildCount - 2).Line, Column = GetChild(ChildCount - 2).CharPositionInLine, ErrorMessage = string.Format("Type '{0}' could not be found in current context", ReturnType), Kind = ErrorKind.Semantic }); ///el nodo evalúa de error NodeInfo = SemanticInfo.SemanticError; } ///si CallableBody no evaluó de error y se encontró el tipo de retorno if (!Object.Equals(CallableBody.NodeInfo, SemanticInfo.SemanticError) && !Object.Equals(returnTypeInfo, SemanticInfo.SemanticError)) { ///el tipo deretorno del CallableBody tiene que ser compatible con el tipo de retorno if (!CallableBody.NodeInfo.Type.IsCompatibleWith(returnTypeInfo)) { errors.Add(new CompileError { Line = GetChild(ChildCount - 2).Line, Column = GetChild(ChildCount - 2).CharPositionInLine, ErrorMessage = string.Format("Cannot implicitly convert type '{0}' to '{1}'", CallableBody.NodeInfo.Type.Name, returnTypeInfo.Type.Name), Kind = ErrorKind.Semantic }); ///el nodo evalúa de error NodeInfo = SemanticInfo.SemanticError; } } ///si no ha evaluado de error le seteamos los valores if (!Object.Equals(NodeInfo, SemanticInfo.SemanticError)) { NodeInfo = new SemanticInfo { Name = SemanticInfo.NoName, ElementKind = SymbolKind.NoSymbol, Type = SemanticInfo.Void, BuiltInType = BuiltInType.Void, ILType = returnTypeInfo.ILType }; functionParche = returnTypeInfo; SemanticInfo arg; ///guardamos los ILType for (int i = 0; i < Parameters.Count; i++) { symbolTable.GetDefinedTypeDeep(Parameters[i].Value, out arg); ILTypes.Add(arg.ILType); } } SemanticInfo function; ///completamos la definición de la función symbolTable.GetDefinedCallableDeep(CallableId, out function); function.IsPending = false; }