public override void CheckSemantic(Scope scope, List<Error> errors) { InitialExp.CheckSemantic(scope.Parent, errors); if (!InitialExp.ReturnType.MatchWith(IntType.IntInstance)) { errors.Add(new Error(InitialExp, "En una expresión 'for' la expresión de inicialización debe ser de tipo 'int' y se encontró una expresión de tipo '{0}'",InitialExp.ReturnType)); HasError = true; } RelatedType = IntType.IntInstance; scope.AddFunVar(VariableName, this); }
public override void CheckSemantic(Scope scope, List<Error> errors) { DeclarationNode funDeclaration = scope.GetFunVar(VariableName, false); //El tipo del parametro se determino en el chequeo de semantica de la secuencia de declaraciones de funciones if (funDeclaration != null) { errors.Add(new Error(this, "Se han definido dos o más parámetros con el nombre '{0}' dentro de la función", VariableName)); HasError = true; } else scope.AddFunVar(VariableName, this); }
public override void CheckSemantic(Scope scope, List<Error> errors) { InitialExp.CheckSemantic(scope, errors); //se pone por defecto con error y de tipo indefinido para factorizar HasError = true; RelatedType = UndefinedType.UndefinedInstance; if (TypeName != null) //se conoce el tipo de la variable { TigerType formalType = scope.GetType(TypeName); if (formalType == null) //el tipo formal no esta definido errors.Add(new Error(GetChild(2),"El tipo '{0}' no ha sido definido en el ámbito actual", TypeName)); else if (!InitialExp.ReturnType.MatchWith(formalType)) //el tipo real no coincide con el formal { errors.Add(new Error(InitialExp, "En una declaración el tipo de variable debe coincidir con el tipo de la expresión de inicialización y se encontró el tipo '{0}' y una expresión de tipo '{1}'", formalType, InitialExp.ReturnType)); RelatedType = formalType; // En C# si se declara 'string a = 5' se asume que 'a' es de tipo 'string' aunque no machee } else //si entra aqui es que no hay error { HasError = false; RelatedType = formalType; } } else //se debe inferir el tipo de la variable { if (InitialExp.ReturnType == NillType.NillInstance) errors.Add(new Error(InitialExp,"No es posible inferir el tipo de la variable '{0}' debido a que la expresión de inicialización es de tipo 'nil'",VariableName)); else if (InitialExp.ReturnType.MatchWith(VoidType.VoidInstance)) errors.Add(new Error(InitialExp,"No es posible inferir el tipo de la variable debido a que la expresión de inicialización es de tipo 'void'")); else //si entra aqui es que no hay error { HasError = false; RelatedType = InitialExp.ReturnType; } } DeclarationNode varDeclaretions = scope.GetFunVar(VariableName, false); if (varDeclaretions != null) { if (varDeclaretions is VariableDecNode) errors.Add(new Error(GetChild(0),"No es posible definir una variable con el nombre '{0}' debido a que existe otra variable con igual nombre dentro del mismo 'let'",VariableName)); else errors.Add(new Error(GetChild(0),"No es posible definir una variable con el nombre '{0}' debido a que existe una función con igual nombre dentro del mismo 'let'", VariableName)); HasError = true; } else scope.AddFunVar(VariableName, this); }
public override void CheckSemantic(Scope scope, List<Error> errors) { foreach (FunctionDecNode funcDec in Declarations) { #region determinar el tipo de retorno if (funcDec.ReturnTypeName == null) // es un procedure funcDec.RelatedType = VoidType.VoidInstance; else // es una function { TigerType funType = scope.GetType(funcDec.ReturnTypeName); if (funType == null) { errors.Add( new Error(funcDec.GetChild(0), "El tipo '{0}' no está definido en el ámbito actual", funcDec.ReturnTypeName)); HasError = true; funcDec.RelatedType = UndefinedType.UndefinedInstance; } else funcDec.RelatedType = funType; } #endregion #region determinar el tipo de cada parametro foreach (FunctionVariableDecNode paramDecl in funcDec.Arguments) { TigerType paramType = scope.GetType(paramDecl.TypeName); if (paramType == null) { paramDecl.RelatedType = UndefinedType.UndefinedInstance; HasError = true; errors.Add(new Error(paramDecl.GetChild(0),"El tipo '{0}' no está definido en el ámbito actual", paramDecl.TypeName)); } else paramDecl.RelatedType = paramType; } #endregion #region añadir la funcion al scope si no esta repetida DeclarationNode funDeclarations = scope.GetFunVar(funcDec.Name, false); if (funDeclarations != null) { if (funDeclarations is FunctionDecNode) errors.Add(new Error(funcDec.GetChild(0),"No es posible definir una función con el nombre '{0}' debido a que existe otra función con igual nombre dentro de un mismo 'let'", funcDec.Name)); else errors.Add(new Error(funcDec.GetChild(0), "No es posible definir una función con el nombre '{0}' debido a que existe una variable con igual nombre dentro de un mismo 'let'", funcDec.Name)); HasError = true; } else if (BuiltInFunctions.Functions.Contains(funcDec.Name)) { errors.Add(new Error(funcDec.GetChild(0),"La función '{0}' está definida en la Biblioteca Estándar de Tiger y no puede ser redefinida", funcDec.Name)); HasError = true; } else scope.AddFunVar(funcDec.Name, funcDec); #endregion } foreach (FunctionDecNode funcDecl in Declarations) funcDecl.CheckSemantic(scope, errors); }
public static void DefineBuiltinFunctions(Scope scope, out FunctionDecNode printFunct, out FunctionDecNode printiFunct, out FunctionDecNode printlineFunct, out FunctionDecNode getCharFunct, out FunctionDecNode getlineFunct, out FunctionDecNode chrFunct, out FunctionDecNode sizeFunct, out FunctionDecNode substringFunct, out FunctionDecNode concatFunct, out FunctionDecNode notFunct, out FunctionDecNode exitFunct, out FunctionDecNode flushFunct, out FunctionDecNode ordFunct) { // print() Function printFunct = new FunctionDecNode(); printFunct.Name = "print"; printFunct.Arguments = new List<FunctionVariableDecNode>() { new FunctionVariableDecNode() { RelatedType = StringType.StringInstance, VariableName = "text" } }; printFunct.RelatedType = VoidType.VoidInstance; scope.AddFunVar("print", printFunct); // printline() Function printlineFunct = new FunctionDecNode(); printlineFunct.Name = "printline"; printlineFunct.Arguments = new List<FunctionVariableDecNode>() { new FunctionVariableDecNode() { RelatedType = StringType.StringInstance, VariableName = "text" } }; printlineFunct.RelatedType = VoidType.VoidInstance; scope.AddFunVar("printline", printlineFunct); // printi() Function printiFunct = new FunctionDecNode(); printiFunct.Name = "printi"; printiFunct.Arguments = new List<FunctionVariableDecNode>() { new FunctionVariableDecNode() { RelatedType = IntType.IntInstance, VariableName = "number" } }; printiFunct.RelatedType = VoidType.VoidInstance; scope.AddFunVar("printi", printiFunct); //getchar():string Function getCharFunct = new FunctionDecNode(); getCharFunct.Name = "getchar"; getCharFunct.Arguments = new List<FunctionVariableDecNode>(); getCharFunct.RelatedType = StringType.StringInstance; scope.AddFunVar("getchar", getCharFunct); //getcharln():string Function getlineFunct = new FunctionDecNode(); getlineFunct.Name = "getline"; getlineFunct.Arguments = new List<FunctionVariableDecNode>(); getlineFunct.RelatedType = StringType.StringInstance; scope.AddFunVar("getline", getlineFunct); //chr(i:int):string Function chrFunct = new FunctionDecNode(); chrFunct.Name = "chr"; chrFunct.Arguments = new List<FunctionVariableDecNode>() { new FunctionVariableDecNode() { RelatedType = IntType.IntInstance, VariableName = "number" } }; chrFunct.RelatedType = StringType.StringInstance; scope.AddFunVar("chr", chrFunct); //size(s:string): int Function sizeFunct = new FunctionDecNode(); sizeFunct.Name = "size"; sizeFunct.Arguments = new List<FunctionVariableDecNode>() { new FunctionVariableDecNode() { RelatedType = StringType.StringInstance, VariableName = "strg" } }; sizeFunct.RelatedType = IntType.IntInstance; scope.AddFunVar("size", sizeFunct); //substring(s:string , first:int, n:int): int Function substringFunct = new FunctionDecNode(); substringFunct.Name = "substring"; substringFunct.Arguments = new List<FunctionVariableDecNode>() { new FunctionVariableDecNode() { RelatedType = StringType.StringInstance, VariableName = "s" }, new FunctionVariableDecNode() { RelatedType = IntType.IntInstance, VariableName = "first" }, new FunctionVariableDecNode() { RelatedType = IntType.IntInstance, VariableName = "n" } }; substringFunct.RelatedType = StringType.StringInstance; scope.AddFunVar("substring", substringFunct); //concat(s1:string ,s1:string ):string Function concatFunct = new FunctionDecNode(); concatFunct.Name = "concat"; concatFunct.Arguments = new List<FunctionVariableDecNode>() { new FunctionVariableDecNode() { RelatedType = StringType.StringInstance, VariableName = "s1" }, new FunctionVariableDecNode() { RelatedType = StringType.StringInstance, VariableName = "s2" } }; concatFunct.RelatedType = StringType.StringInstance; scope.AddFunVar("concat", concatFunct); //not(i:int ):int Function notFunct = new FunctionDecNode(); notFunct.Name = "not"; notFunct.Arguments = new List<FunctionVariableDecNode>() { new FunctionVariableDecNode() { RelatedType = IntType.IntInstance, VariableName = "i" } }; notFunct.RelatedType = IntType.IntInstance; scope.AddFunVar("not", notFunct); //exit(i:int ):int Function exitFunct = new FunctionDecNode(); exitFunct.Name = "exit"; exitFunct.Arguments = new List<FunctionVariableDecNode>() { new FunctionVariableDecNode() { RelatedType = IntType.IntInstance, VariableName = "exitcode" } }; exitFunct.RelatedType = VoidType.VoidInstance; scope.AddFunVar("exit", exitFunct); //flush () Function flushFunct = new FunctionDecNode(); flushFunct.Name = "flush"; flushFunct.Arguments = new List<FunctionVariableDecNode>(); flushFunct.RelatedType = VoidType.VoidInstance; scope.AddFunVar("flush", flushFunct); //ord(s:string): int Function ordFunct = new FunctionDecNode(); ordFunct.Name = "ord"; ordFunct.Arguments = new List<FunctionVariableDecNode>() { new FunctionVariableDecNode() { RelatedType = StringType.StringInstance, VariableName = "str" } }; ordFunct.RelatedType = IntType.IntInstance; scope.AddFunVar("ord", ordFunct); }