public override void VisitIdentifierName(IdentifierNameSyntax identifierName, BindingScope bindingScope) { if (!bindingScope.Lookup(identifierName.Name, out var binding)) { return; } var shadowedBy = binding.WasShadowedBy.LastOrDefault(); if (shadowedBy == null) { return; } diagnostics.Add(SemanticError.CantShadow(function.File, shadowedBy.NameSpan, identifierName.Span)); function.Poison(); }
public override void CheckSemantics(Scope scope, List <SemanticError> errors) { //-------------------------------------------------- // Hacer 'CheckSemantics' A Los Dos Hijos. //-------------------------------------------------- this.LeftOperandNode.CheckSemantics(scope, errors); this.RightOperandNode.CheckSemantics(scope, errors); //-------------------------------------------------- // Poner El Valor De Retorno De La Expresión A 'Error' // Por Default. //-------------------------------------------------- this.ExpressionType = PredefinedTypes.ErrorType; //-------------------------------------------------- // Si Ha Ocurrido Un Error En Alguno De Los Hijos, // Parar De Reportar Errores. //-------------------------------------------------- if (this.LeftOperandNode.ExpressionType == PredefinedTypes.ErrorType || this.RightOperandNode.ExpressionType == PredefinedTypes.ErrorType) { return; } //-------------------------------------------------- // Comprobar Que Ambas Expresiones Devuelvan 'int'. //-------------------------------------------------- bool IsOk = true; if (this.LeftOperandNode.ExpressionType != PredefinedTypes.IntType) { IsOk = false; errors.Add(SemanticError.InvalidUseOfBinaryArithmeticOperator( this.OperatorName, "left", this.LeftOperandNode)); } if (this.RightOperandNode.ExpressionType != PredefinedTypes.IntType) { IsOk = false; errors.Add(SemanticError.InvalidUseOfBinaryArithmeticOperator( this.OperatorName, "right", this.RightOperandNode)); } if (IsOk) { this.ExpressionType = PredefinedTypes.IntType; } }
public override void CheckSemantics(Scope scope, List <SemanticError> errors) { LeftOperand.CheckSemantics(scope, errors); RightOperand.CheckSemantics(scope, errors); if (errors.Any()) { return; } if (!SupportType(LeftOperand.Type)) { errors.Add(SemanticError.InvalidUseOfOperator("binary relational", "valid", "left", LeftOperand)); } if (!SupportType(RightOperand.Type)) { errors.Add(SemanticError.InvalidUseOfOperator("binary relational", "valid", "right", RightOperand)); } if (RightOperand.Type != LeftOperand.Type) { errors.Add(new SemanticError { Message = "Types of left and right operands of the binary relational operator do not match", Node = this }); } if (LeftOperand.Type.Equals(Types.Nil) && RightOperand.Type.Equals(Types.Nil)) { errors.Add(new SemanticError { Message = $"Types of left and right operands of the binary relational operator can't be both '{Types.Nil}'", Node = this }); } if (LeftOperand is ComparisonNode || RightOperand is ComparisonNode) { errors.Add(new SemanticError { Message = "Comparison operators do not associate", Node = this }); } }
public override void VisitVariableDeclarationStatement(VariableDeclarationStatementSyntax variableDeclaration, BindingScope bindingScope) { base.VisitVariableDeclarationStatement(variableDeclaration, bindingScope); if (bindingScope.Lookup(variableDeclaration.Name, out var binding)) { if (binding.MutableBinding) { diagnostics.Add(SemanticError.CantRebindMutableBinding(function.File, variableDeclaration.NameSpan)); function.Poison(); } else if (variableDeclaration.MutableBinding) { diagnostics.Add(SemanticError.CantRebindAsMutableBinding(function.File, variableDeclaration.NameSpan)); function.Poison(); } } }
public override void CheckSemantics(Scope scope, List <SemanticError> errors) { LeftOperand.CheckSemantics(scope, errors); RightOperand.CheckSemantics(scope, errors); if (LeftOperand.Type != Type) { errors.Add(SemanticError.InvalidUseOfOperator( "binary logical", LeftOperand.Type.Equals(Types.Nil) ? "valued" : "integer", "left", LeftOperand)); } if (RightOperand.Type != Type) { errors.Add(SemanticError.InvalidUseOfOperator( "binary logical", RightOperand.Type.Equals(Types.Nil) ? "valued" : "integer", "right", RightOperand)); } }
public override void CheckSemantics(Scope scope, List <SemanticError> errors) { //-------------------------------------------------- // Hacer 'CheckSemantics' A Los Dos Hijos. //-------------------------------------------------- this.LeftOperandNode.CheckSemantics(scope, errors); this.RightOperandNode.CheckSemantics(scope, errors); //-------------------------------------------------- // Poner El Valor De Retorno De La Expresión A 'Error' // Por Default. //-------------------------------------------------- this.ExpressionType = PredefinedTypes.ErrorType; //-------------------------------------------------- // Si Ha Ocurrido Un Error En Alguno De Los Hijos, // Parar De Reportar Errores. //-------------------------------------------------- if (this.LeftOperandNode.ExpressionType == PredefinedTypes.ErrorType || this.RightOperandNode.ExpressionType == PredefinedTypes.ErrorType) { return; } //-------------------------------------------------- // Solamente Se Pueden Comprar Enteros Y Cadenas. //-------------------------------------------------- if (this.LeftOperandNode.ExpressionType != this.RightOperandNode.ExpressionType) { errors.Add(SemanticError.InvalidCompareOperation(this.LeftOperandNode.ExpressionType, this.RightOperandNode.ExpressionType, this)); } else { if (this.LeftOperandNode.ExpressionType != PredefinedTypes.IntType && this.LeftOperandNode.ExpressionType != PredefinedTypes.StrType) { errors.Add(SemanticError.InvalidCompareOperation(this.LeftOperandNode.ExpressionType, this.RightOperandNode.ExpressionType, this)); } else { this.ExpressionType = PredefinedTypes.IntType; } } }
public override void CheckSemantics(Semantics.Scope scope, List <Semantics.SemanticError> errors) { //-------------------------------------------------- // Poner Por Defecto Que Hay Errores. //-------------------------------------------------- this.ExpressionType = PredefinedTypes.ErrorType; //-------------------------------------------------- // Buscar El Primer Nodo Hacia La Raiz Que Acepte // Break. //-------------------------------------------------- this.Owner = null; var pathToTheRoot = this.GetAncestors().Reverse(); foreach (var u in pathToTheRoot) { if (u is IBreakableNode) { this.Owner = u as IBreakableNode; break; } if (u is FunctionDeclarationNode) { break; } if (u is ExpressionsBlockNode) { (u as ExpressionsBlockNode).ContainsBreakNodes = true; } } //-------------------------------------------------- // Comprobar Si El Break Está Siendo Usado Fuera // De Un For, While, O Bloque De Expresiones. //-------------------------------------------------- if (this.Owner == null) { errors.Add(SemanticError.InvalidUseOfBreak(this)); } else { this.ExpressionType = PredefinedTypes.VoidType; } }
public VariableFlags Assignment( IAssignmentExpression assignmentExpression, VariableFlags definitelyUnassigned) { switch (assignmentExpression.LeftOperand) { case INameExpression identifier: var symbol = identifier.ReferencedSymbol; if (!symbol.IsMutableBinding && definitelyUnassigned[symbol] == false) { diagnostics.Add(SemanticError.VariableMayAlreadyBeAssigned(file, identifier.Span, identifier.ReferencedSymbol.Name)); } return(definitelyUnassigned.Set(symbol, false)); case IFieldAccessExpression _: return(definitelyUnassigned); default: throw new NotImplementedException("Complex assignments not yet implemented"); } }
public override void CheckSemantics(Scope scope, List <SemanticError> errors) { //-------------------------------------------------- // Hacer 'CheckSemantics' A Los Hijos. //-------------------------------------------------- this.LeftVariable.CheckSemantics(scope, errors); this.Value.CheckSemantics(scope, errors); //-------------------------------------------------- // Poner Por Defecto Que Hay Errores. //-------------------------------------------------- this.ExpressionType = PredefinedTypes.ErrorType; //-------------------------------------------------- // Si Ha Ocurrido Un Error En Alguno De Los Hijos, // Parar De Reportar Errores. //-------------------------------------------------- if (this.LeftVariable.ExpressionType == PredefinedTypes.ErrorType || this.Value.ExpressionType == PredefinedTypes.ErrorType) { return; } if (this.LeftVariable.ReadOnly) { errors.Add(SemanticError.InvalidUseOfAssignmentToAReadonlyVariable(this.LeftVariable)); return; } if (!SemanticError.CompatibleTypes(this.LeftVariable.ExpressionType, this.Value.ExpressionType)) { errors.Add(SemanticError.ExpectedType(this.LeftVariable.ExpressionType, this.Value.ExpressionType, this)); } else { this.ExpressionType = PredefinedTypes.VoidType; } }
public override void CheckSemantics(Scope scope, List <SemanticError> errors) { //-------------------------------------------------- // A 'IdNode' Se Le Hace 'CheckSemantics' Solamente // Cuando Es Usado Como 'AccessNode'. //-------------------------------------------------- this.VariableInfo = scope.FindVariableInfo(this.Name); //-------------------------------------------------- // Si No Existe Una Variable En El Scope Visible // Actual Que Corresponda Al Nombre Del 'ID' Actual, // Informamos Error. //-------------------------------------------------- if (this.VariableInfo == null) { errors.Add(SemanticError.UndefinedVariableUsed(this.Name, this)); this.ExpressionType = PredefinedTypes.ErrorType; } else { this.ExpressionType = this.VariableInfo.TypeNode; this.ReadOnly = this.VariableInfo.ReadOnly; } }
public override void CheckSemantics(Scope scope, List <SemanticError> errors) { //-------------------------------------------------- // Buscar En El Scope Actual El TypeInfo De TypeID. //-------------------------------------------------- var TI = scope.FindTypeInfo(this.TypeID.Name); //-------------------------------------------------- // Si El Tipo No Existe, Entonces Reportar El Error, // En Caso Contrario, Crear Un 'VariableInfo' Para // El Campo Actual Con Nombre ID Y Tipo TI. Actualizar // IsOk En Cada Caso. //-------------------------------------------------- if (TI == null) { errors.Add(SemanticError.TypeDoesNotExist(this.TypeID.Name, this.TypeID)); this.IsOk = false; } else { this.VariableInfo = new VariableInfo(ID.Name, TI.TypeNode); this.IsOk = true; } }
public override void CheckSemantics(Scope scope, List <SemanticError> errors) { //-------------------------------------------------- // Poner El Valor De Retorno De La Expresión A 'Error' // Por Default. //-------------------------------------------------- this.ExpressionType = PredefinedTypes.ErrorType; //-------------------------------------------------- // Buscar Por El Tipo Del Record. //-------------------------------------------------- var TI = scope.FindTypeInfo(this.TypeID.Name); //-------------------------------------------------- // Si El Tipo No Está Definido, Reportar Error. //-------------------------------------------------- if (TI == null) { errors.Add(SemanticError.TypeDoesNotExist(this.TypeID.Name, this.TypeID)); return; } var RecordType = TI.TypeNode as RecordTypeNode; //-------------------------------------------------- // Si El Tipo No Es Un Record. //-------------------------------------------------- if (RecordType == null) { errors.Add(SemanticError.RecordTypeExpected(TI.TypeNode, this.TypeID)); return; } //-------------------------------------------------- // La Cantidad De Campos Debe Ser La Misma. //-------------------------------------------------- if (this.Fields.Length != RecordType.Fields.Length) { errors.Add(SemanticError.WrongFieldNumberInRecord(RecordType.Name, RecordType.Fields.Length, this.Fields.Length, this)); return; } //-------------------------------------------------- // Hacer 'CheckSemantics' A Los Campos Del Record. //-------------------------------------------------- bool IsOk = true; foreach (var field in this.Fields) { field.CheckSemantics(scope, errors); if (field.ExpressionType == PredefinedTypes.ErrorType) { IsOk = false; } } if (!IsOk) { return; } //-------------------------------------------------- // Comprobar El Orden De Los Campos Y Los Tipos. //-------------------------------------------------- for (int i = 0; i < this.Fields.Length; i++) { if (this.Fields[i].ID.Name != RecordType.Fields[i].ID.Name) { IsOk = false; errors.Add(SemanticError.WrongFieldNameInRecord( this.Fields[i].ID.Name, RecordType.Fields[i].ID.Name, this.Fields[i] )); } if (!SemanticError.CompatibleTypes(RecordType.Fields[i].VariableInfo.TypeNode, this.Fields[i].ExpressionType)) { IsOk = false; errors.Add(SemanticError.ExpectedType( RecordType.Fields[i].VariableInfo.TypeNode, this.Fields[i].ExpressionType, this.Fields[i] )); } } if (IsOk) { this.ExpressionType = RecordType; } }
public override void CheckSemantics(Scope scope, List <SemanticError> errors) { //-------------------------------------------------- // Buscar El FunctionInfo Correspondiente. //-------------------------------------------------- this.FunctionInfo = scope.FindFunctionInfo(ID.Name); //-------------------------------------------------- // Poner Por Defecto Que Hay Errores. //-------------------------------------------------- this.ExpressionType = PredefinedTypes.ErrorType; //-------------------------------------------------- // Si La Función No Existe, Reportar Error. //-------------------------------------------------- if (this.FunctionInfo == null) { errors.Add(SemanticError.FunctionDoesNotExist(this.ID.Name, this)); return; } //-------------------------------------------------- // Si La Cantidad De Argumentos Es Diferente A La // Cantidad De Parámetros, Reportar Error. //-------------------------------------------------- var parameters = this.FunctionInfo.Parameters; if (this.Arguments.Count() != parameters.Length) { errors.Add(SemanticError.WrongParameterNumber(this.ID.Name, parameters.Length, this.Arguments.Count(), this)); return; } //-------------------------------------------------- // Hacer 'CheckSemantics' A Cada Argumento. //-------------------------------------------------- bool IsOk = true; foreach (var argument in this.Arguments) { argument.CheckSemantics(scope, errors); if (argument.ExpressionType == PredefinedTypes.ErrorType) { IsOk = false; } } //-------------------------------------------------- // Si Hay Errores En Los Argumentos, Parar De // Reportar Errores. //-------------------------------------------------- if (!IsOk) { return; } //-------------------------------------------------- // Comprobar Que Los Tipos De Los Argumentos Son Iguales // A Los Tipos De Los Parámetros Correspondientes. //-------------------------------------------------- for (int i = 0; i < parameters.Length; i++) { var arg = this.Arguments.ElementAt(i); if (!SemanticError.CompatibleTypes(parameters[i].TypeNode, arg.ExpressionType)) { errors.Add(SemanticError.InvalidTypeConvertion(parameters[i].TypeNode, arg.ExpressionType, arg)); IsOk = false; } } if (IsOk) { this.ExpressionType = this.FunctionInfo.ReturnType; } }
public void ErrorSuppressComment(string format, params object[] args) { var err = new SemanticError(String.Format(format, args), item, readFrom.LineNumber, readFrom.LinePosition); engine.ReportError(err); }
public void ErrorSuppressComment(string message) { var err = new SemanticError(message, item, readFrom.LineNumber, readFrom.LinePosition); engine.ReportError(err); }
public override void CheckSemantics(Scope scope, List <SemanticError> errors) { //-------------------------------------------------- // Por Default, El Nodo No Tiene Errores. //-------------------------------------------------- this.IsOk = true; //-------------------------------------------------- // Si Existe Una Función O Una Variable Con El Mismo // Nombre En El Scope Local, Reportar Error. //-------------------------------------------------- if (scope.FindLocalFunctionInfo(this.ID.Name) != null || scope.FindLocalVariableInfo(this.ID.Name) != null) { errors.Add(SemanticError.PreviousVariableOrFunctionDeclaration(this.ID.Name, this)); this.IsOk = false; } //-------------------------------------------------- // Hacer 'CheckSemantics' Al Valor De La Variable. //-------------------------------------------------- this.Expression.CheckSemantics(scope, errors); //-------------------------------------------------- // Si El Valor De La Expresión Tiene Algún Error, // Parar De Reportar Errores. //-------------------------------------------------- if (this.Expression.ExpressionType == PredefinedTypes.ErrorType) { this.IsOk = false; } if (!this.IsOk) { return; } if (this.ChildCount == 3) { //-------------------------------------------------- // Si La Variable Tiene El Tipo Explícitamente Entonces // Es De La Siguiente Forma: // // var id : type-id := expr //-------------------------------------------------- var typeID = this.Children[2] as IdNode; //-------------------------------------------------- // Si El Tipo No Existe, Entonces Reportar El Error. //-------------------------------------------------- var TI = scope.FindTypeInfo(typeID.Name); if (TI == null) { errors.Add(SemanticError.TypeDoesNotExist(typeID.Name, this)); this.IsOk = false; return; } if (this.Expression.ExpressionType == PredefinedTypes.NilType) { //-------------------------------------------------- // Si El Valor De La Expresión Es <nil>, Entonces El // Tipo De La Variable, Escrito Explícitamente; Puede // Ser Cualquiera, Excepto 'int'. // // var id : type-id := nil //-------------------------------------------------- if (TI.TypeNode == PredefinedTypes.IntType) { errors.Add(SemanticError.InvalidIntNilAssignation(this)); this.IsOk = false; return; } } else if (TI.TypeNode != this.Expression.ExpressionType) { //-------------------------------------------------- // Si Los Tipos Son Diferentes, Reportar Error. //-------------------------------------------------- this.IsOk = false; errors.Add(SemanticError.InvalidTypeConvertion(TI.TypeNode, this.Expression.ExpressionType, this)); return; } //-------------------------------------------------- // Crear 'VariableInfo'. //-------------------------------------------------- this.VariableInfo = new VariableInfo(this.ID.Name, TI.TypeNode); } else { //-------------------------------------------------- // En Este Caso Se Omite El Tipo De La Variable, Por // Tanto Se Debe Inferir De La Parte Derecha. Se Debe // Comprobar Que La Parte Derecha No Sea <nil> o <void>. // // var id := expr //-------------------------------------------------- if (this.Expression.ExpressionType == PredefinedTypes.NilType || this.Expression.ExpressionType == PredefinedTypes.VoidType) { errors.Add(SemanticError.InvalidTypeInference(this.Expression.ExpressionType, this)); this.IsOk = false; return; } //-------------------------------------------------- // Crear 'VariableInfo'. //-------------------------------------------------- this.VariableInfo = new VariableInfo(this.ID.Name, this.Expression.ExpressionType); } //-------------------------------------------------- // Actualizar 'Scope' Con La Variable Actual. //-------------------------------------------------- scope.Add(this.VariableInfo); }
public override void CheckSemantics(Scope scope, List <SemanticError> errors) { //-------------------------------------------------- // Hacer 'CheckSemantics' A Los Hijos. //-------------------------------------------------- this.Size.CheckSemantics(scope, errors); this.Value.CheckSemantics(scope, errors); //-------------------------------------------------- // Poner El Valor De Retorno De La Expresión A 'Error' // Por Default. //-------------------------------------------------- this.ExpressionType = PredefinedTypes.ErrorType; //-------------------------------------------------- // Si Ha Ocurrido Un Error En Alguno De Los Hijos, // Parar De Reportar Errores. //-------------------------------------------------- if (this.Size.ExpressionType == PredefinedTypes.ErrorType || this.Value.ExpressionType == PredefinedTypes.ErrorType) { return; } //-------------------------------------------------- // Buscar Por El Tipo Del Array //-------------------------------------------------- var TI = scope.FindTypeInfo(this.TypeID.Name); //-------------------------------------------------- // Si El Tipo No Está Definido, Reportar Error. //-------------------------------------------------- if (TI == null) { errors.Add(SemanticError.TypeDoesNotExist(this.TypeID.Name, this.TypeID)); return; } var ArrayType = TI.TypeNode as ArrayTypeNode; //-------------------------------------------------- // Si El Tipo No Es Un Array. //-------------------------------------------------- if (ArrayType == null) { errors.Add(SemanticError.ArrayTypeExpected(TI.TypeNode, this.TypeID)); return; } //-------------------------------------------------- // 'Size' Debe Ser De Tipo <int>. //-------------------------------------------------- if (this.Size.ExpressionType != PredefinedTypes.IntType) { errors.Add(SemanticError.ExpectedType(PredefinedTypes.IntType, this.Size.ExpressionType, this.Size)); return; } //-------------------------------------------------- // 'Value' Debe Ser Del Mismo Tipo Que El Array. //-------------------------------------------------- if (!SemanticError.CompatibleTypes(ArrayType.ArrayOf, this.Value.ExpressionType)) { errors.Add(SemanticError.ExpectedType(ArrayType.ArrayOf, this.Value.ExpressionType, this.Value)); return; } this.ExpressionType = ArrayType; }
public DeclareAndInitializeGlobalVariable(SemanticError error) { Name = Strings.DeclareAndInitializeGlobalVariable; Error = error; }
public override void CheckSemantics(Scope scope, List <SemanticError> errors) { //-------------------------------------------------- // Por Default, El Nodo No Tiene Errores. //-------------------------------------------------- this.IsOk = true; //-------------------------------------------------- // Obtener Todos Los Nombres De Los Tipos En El // Bloque Actual. //-------------------------------------------------- string[] names = this.Declarations.Select(x => x.ID.Name).ToArray <string>(); //-------------------------------------------------- // Comprobar Que Todos Los Nombres Se Declaren Solo // Una Vez. //-------------------------------------------------- for (int i = 0; i < names.Length; i++) { bool hasPreviousDeclaration = (scope.FindLocalTypeInfo(names[i]) != null); for (int j = 0; j < i; j++) { if (names[i] == names[j]) { hasPreviousDeclaration = true; } } if (hasPreviousDeclaration) { errors.Add(SemanticError.PreviousTypeDeclaration(names[i], this.Declarations[i])); this.IsOk = false; } } if (!this.IsOk) { return; } //-------------------------------------------------- // Buscar Ciclos En Las Declaraciones AliasTypeNode // Y ArrayTypeNode. //-------------------------------------------------- bool[] visited = new bool[this.Declarations.Length]; //-------------------------------------------------- // Actualizar 'Scope' Solamente Con Declaraciones De Records. //-------------------------------------------------- for (int i = 0; i < this.Declarations.Length; i++) { if (this.Declarations[i].TypeNode is RecordTypeNode) { visited[i] = true; scope.Add(new TypeInfo(this.Declarations[i].ID.Name, this.Declarations[i].TypeNode)); } } for (int i = 0; i < names.Length && this.IsOk; i++) { if (visited[i]) { continue; } List <int> path = new List <int>(); int currentDeclaration = i; while (true) { //-------------------------------------------------- // Si La Declaración Ha Sido Visitada Previamente, // Entonces Estamos En Presencia De Un Ciclo. //-------------------------------------------------- if (visited[currentDeclaration]) { errors.Add(SemanticError.CycleInTypeDeclaration( this.Declarations[currentDeclaration].ID.Name, this )); this.IsOk = false; break; } //-------------------------------------------------- // Marcar Como "Visitada" La Declaración Actual. //-------------------------------------------------- path.Add(currentDeclaration); visited[currentDeclaration] = true; //-------------------------------------------------- // Buscar El Nombre Del Tipo Del Que Depende La // Declaración Actual: // // type <type-id> = <type-id> // type <type-id> = array of <type-id> //-------------------------------------------------- var CDN = this.Declarations.ElementAt(currentDeclaration).TypeNode; string type = CDN is AliasTypeNode ? (CDN as AliasTypeNode).TypeID.Name : (CDN as ArrayTypeNode).TypeID.Name; //-------------------------------------------------- // Buscar Primero Si Depende De Un Tipo En Este Bloque // De Declaraciones. //-------------------------------------------------- int namesIndex = Array.FindIndex(this.Declarations, x => x.ID.Name == type); //-------------------------------------------------- // Si El Tipo No Esta En El Bloque De Declaraciones, // Buscar En El Scope Global. De Lo Contrario, Buscar // En El Scope Local. //-------------------------------------------------- TypeInfo TI = null; if (namesIndex < 0 || namesIndex >= names.Length) { TI = scope.FindTypeInfo(type); } else { TI = scope.FindLocalTypeInfo(type); } //-------------------------------------------------- // Si El Tipo Está En El Scope, Actualizar Cada Una // De Las Declaraciones. //-------------------------------------------------- if (TI != null) { var TN = TI.TypeNode; for (int u = path.Count - 1; u >= 0; u--) { var declarationNode = this.Declarations[path[u]]; if (declarationNode.TypeNode is AliasTypeNode) { (declarationNode.TypeNode as AliasTypeNode).AliasOf = TN; } else { (declarationNode.TypeNode as ArrayTypeNode).ArrayOf = TN; TN = declarationNode.TypeNode; } scope.Add(new TypeInfo(declarationNode.ID.Name, TN)); } break; } //-------------------------------------------------- // Si No Se Pudo Encontrar El Tipo , Entonces Comprobar // Si Depende De Alguna Declaración En El Mismo Bloque. // Si No Es El Caso, Reportar Error. //-------------------------------------------------- currentDeclaration = namesIndex; if (currentDeclaration < 0 || currentDeclaration >= names.Length) { errors.Add(SemanticError.TypeDoesNotExist(type, CDN)); this.IsOk = false; break; } } } //-------------------------------------------------- // Si Hay Errores, Parar De Reportar Errores. //-------------------------------------------------- if (!this.IsOk) { return; } //-------------------------------------------------- // Hacer 'CheckSemantics' A Cada TypeDeclarationNode. //-------------------------------------------------- foreach (var declaration in this.Declarations) { declaration.CheckSemantics(scope, errors); this.IsOk &= declaration.IsOk; } }
public static void ReportError(SemanticError error) { Diagnostics.SemanticErrors.Add(error); }
public override void CheckSemantics(Semantics.Scope scope, List <Semantics.SemanticError> errors) { //-------------------------------------------------- // Por Default, El Nodo No Tiene Errores. //-------------------------------------------------- this.IsOk = true; //-------------------------------------------------- // Si Existe Una Función O Una Variable Con El Mismo // Nombre En El Scope Local, Reportar Error. //-------------------------------------------------- if (scope.FindLocalFunctionInfo(this.ID.Name) != null || scope.FindLocalVariableInfo(this.ID.Name) != null) { errors.Add(SemanticError.PreviousVariableOrFunctionDeclaration(this.ID.Name, this)); this.IsOk = false; } //-------------------------------------------------- // Buscar Parámetros Repetidos En La Declaración De La Función. //-------------------------------------------------- var ParameterName = this.Parameters.Select(x => x.ID.Name).ToArray <string>(); for (int i = 0; i < ParameterName.Length; i++) { int j = 0; while (j < i && ParameterName[i] != ParameterName[j]) { j = j + 1; } if (j < i) { errors.Add(SemanticError.PreviousParameterDeclaration(ParameterName[i], this.ID.Name, this.Parameters[i])); this.IsOk = false; } } //-------------------------------------------------- // Hacer 'CheckSemantics' A Los Parámetros... //-------------------------------------------------- foreach (var parameter in this.Parameters) { parameter.CheckSemantics(scope, errors); this.IsOk &= parameter.IsOk; } if (!this.IsOk) { return; } //-------------------------------------------------- // Crea El 'FunctionInfo' Correspondiente A La Función // Actual. Notar Que El Tipo De Retorno Se Pone En <none>. //-------------------------------------------------- this.FunctionInfo = new FunctionInfo( this.ID.Name, PredefinedTypes.VoidType, this.Parameters.Select(x => x.VariableInfo).ToArray() ); //-------------------------------------------------- // Si La Función Tiene El Tipo De Retorno Explícitamente // Entonces Es De La Siguiente Forma: // // function foo( parameters ) : type-id = expr // // ... Y Podemos Actualizar El 'FunctionInfo'; //-------------------------------------------------- if (this.ChildCount == 4) { var typeID = this.Children[3] as IdNode; //-------------------------------------------------- // Si El Tipo No Existe, Entonces Reportar El Error. //-------------------------------------------------- var TI = scope.FindTypeInfo(typeID.Name); if (TI == null) { errors.Add(SemanticError.TypeDoesNotExist(typeID.Name, typeID)); this.IsOk = false; return; } //-------------------------------------------------- // Actualizar El Tipo De Retorno De La Función. //-------------------------------------------------- this.FunctionInfo.ReturnType = TI.TypeNode; } //-------------------------------------------------- // Actualizar El Scope Actual. //-------------------------------------------------- scope.Add(this.FunctionInfo); }
public void Error(string format, params object[] args) { var err = new SemanticError(String.Format(format, args), item, readFrom.LineNumber, readFrom.LinePosition); engine.ReportError(err); // Inject an HTML comment describing the error: if (engine.InjectErrorComments) writeTo.AppendFormat("<!-- IVOCMS error in '{0}' ({1}:{2}): {3} -->", err.Item.TreeBlobPath.Path, err.LineNumber, err.LinePosition, err.Message); }
public override void CheckSemantics(Scope scope, List <SemanticError> errors) { //-------------------------------------------------- // Por Default, El Nodo No Tiene Errores. //-------------------------------------------------- this.IsOk = true; //-------------------------------------------------- // Hacer 'CheckSemantics' A Cada Función. //-------------------------------------------------- foreach (var declaration in this.Declarations) { declaration.CheckSemantics(scope, errors); this.IsOk &= declaration.IsOk; } if (!this.IsOk) { return; } //-------------------------------------------------- // Hacer 'CheckSemantics' Al Cuerpo De Las Funciones. // Esto Es Una Segunda Pasada. //-------------------------------------------------- foreach (var declaration in this.Declarations) { Scope InnerScope = scope.CreateChildScope(); foreach (var parameter in declaration.FunctionInfo.Parameters) { InnerScope.Add(parameter); } //-------------------------------------------------- // Mantener La Referencia Del Scope Definido En // El Function Info. //-------------------------------------------------- declaration.FunctionInfo.Scope = InnerScope; declaration.Body.CheckSemantics(InnerScope, errors); //-------------------------------------------------- // Parar De Reportar Errores Si El Cuerpo De La Función // Tiene Error. //-------------------------------------------------- if (declaration.Body.ExpressionType == PredefinedTypes.ErrorType) { declaration.IsOk = false; } this.IsOk &= declaration.IsOk; if (!declaration.IsOk) { continue; } //-------------------------------------------------- // Comprobar Que El Tipo De Retorno De La Función // Sea Igual Al Del Cuerpo De La Misma. Comprobar Tres // Casos: // 1 - La Función No Devuelve & El Cuerpo Devuelve // 2 - La Función Devuelve & El Cuerpo No Devuelve // 3 - La Función Y El Cuerpo Devuelven Pero Tipos Incompatibles. // - Tener En Cuenta El Caso <object_type> = <nil> //-------------------------------------------------- if (declaration.FunctionInfo.ReturnType == PredefinedTypes.VoidType) { //-------------------------------------------------- // La Función Es Un Procedimiento ( No Devuelve )... //-------------------------------------------------- if (declaration.Body.ExpressionType != PredefinedTypes.VoidType) { errors.Add(SemanticError.ProcedureCannotReturn(declaration.ID.Name, declaration)); declaration.IsOk = false; } } else { //-------------------------------------------------- // La Función Devuelve ... //-------------------------------------------------- if (declaration.Body.ExpressionType == PredefinedTypes.VoidType) { errors.Add(SemanticError.FunctionMustReturn(declaration.ID.Name, declaration)); declaration.IsOk = false; } else { if (declaration.Body.ExpressionType == PredefinedTypes.NilType) { if (declaration.FunctionInfo.ReturnType == PredefinedTypes.IntType) { errors.Add(SemanticError.InvalidIntNilAssignation(declaration)); declaration.IsOk = false; } } else if (declaration.Body.ExpressionType != declaration.FunctionInfo.ReturnType) { errors.Add(SemanticError.InvalidTypeConvertion(declaration.FunctionInfo.ReturnType, declaration.Body.ExpressionType, declaration)); declaration.IsOk = false; } } } this.IsOk &= declaration.IsOk; } }
public override void CheckSemantics(Scope scope, List <SemanticError> errors) { //-------------------------------------------------- // Hacer 'CheckSemantics' A Los Hijos. //-------------------------------------------------- this.LoNode.CheckSemantics(scope, errors); this.HiNode.CheckSemantics(scope, errors); //-------------------------------------------------- // Poner El Valor De Retorno De La Expresión A 'Error' // Por Default. //-------------------------------------------------- this.ExpressionType = PredefinedTypes.ErrorType; //-------------------------------------------------- // Si Ha Ocurrido Un Error En Alguno De Los Hijos, // Parar De Reportar Errores. //-------------------------------------------------- if (this.LoNode.ExpressionType == PredefinedTypes.ErrorType || this.HiNode.ExpressionType == PredefinedTypes.ErrorType) { return; } //-------------------------------------------------- // Ambos Nodos, LoNode & HiNode, Deben Ser De Tipo <int>. //-------------------------------------------------- if (this.LoNode.ExpressionType != PredefinedTypes.IntType || this.HiNode.ExpressionType != PredefinedTypes.IntType) { if (this.LoNode.ExpressionType != PredefinedTypes.IntType) { errors.Add(SemanticError.ExpectedType(PredefinedTypes.IntType, this.LoNode.ExpressionType, this.LoNode)); } if (this.HiNode.ExpressionType != PredefinedTypes.IntType) { errors.Add(SemanticError.ExpectedType(PredefinedTypes.IntType, this.HiNode.ExpressionType, this.HiNode)); } return; } //-------------------------------------------------- // Definir Un Nuevo Scope Con La Variable De Iteración // Incluída. //-------------------------------------------------- this.ID.VariableInfo = new VariableInfo(this.ID.Name, PredefinedTypes.IntType, true); Scope InnerScope = scope.CreateChildScope(); InnerScope.Add(this.ID.VariableInfo); //-------------------------------------------------- // Hacer 'CheckSemantics' En El Cuerpo Del For. //-------------------------------------------------- this.BodyNode.CheckSemantics(InnerScope, errors); //-------------------------------------------------- // Si Hay Errores En El Cuerpo Del For, Parar De // Reportar Errores. //-------------------------------------------------- if (this.BodyNode.ExpressionType == PredefinedTypes.ErrorType) { return; } //-------------------------------------------------- // El Cuerpo Del For No Puede Devolver Valor. //-------------------------------------------------- if (this.BodyNode.ExpressionType != PredefinedTypes.VoidType) { errors.Add(SemanticError.ExpectedType(PredefinedTypes.VoidType, this.BodyNode.ExpressionType, this)); } else { this.ExpressionType = PredefinedTypes.VoidType; } }