public override void CheckSemantic(Scope scope, List<Error> errors) { TypeInfo t = null; //busco el tipo en el scope t = scope.ExistType(Name); //si no existe lanzo un error if (t == null) errors.Add(new Error(Row, Col, string.Format("Doesn't exist any type with name \"{0}\"", Name))); //si existe pero no es de tipo record else if (!t.IsRecord) errors.Add(new Error(Row, Col, string.Format("The type {0} isn't record", Name))); else { //chekeo q tenga la misma cantidad de parametros if (Ids.Count() != t.Record_parameters.Count()) errors.Add(new Error(Row, Col,string.Format("The record \"{0}\" don't have {1} parameter(s)",Name,Ids.Count()))); else { //chekeo q los campos esten en el mismo orden for (int i = 0; i < Ids.Count(); i++) { string field_name = t.Record_parameters[i].Id; if (Ids[i] != field_name) errors.Add(new Error(Row, Col, string.Format("The field name must be {0}", field_name))); } //chekeo q los valores de retorno de las expresiones //sean del mismo tipo q su campo correspondiente en el record for (int i = 0; i < Exprs.Count(); i++) { //chekeo la semantica de cada exprs Exprs[i].CheckSemantic(scope, errors); TypeInfo temp = scope.ExistType(t.Record_parameters[i].Type); if (Exprs[i].ReturnType != null && temp.BaseType.Name != Exprs[i].ReturnType.BaseType.Name) { if (Exprs[i].ReturnType.BaseType.Name == "nil") { if(scope.ExistType(t.Record_parameters[i].Type).IsInt) errors.Add(new Error(Row, Col, string.Format("Cannot assign <nil> to an <int>"))); } else errors.Add(new Error(Row, Col, string.Format("The field \"{0}\" of record must be of type \"{1}\"",t.Record_parameters[i].Id, t.Record_parameters[i].Type))); } } } } //actualizo el retorno del nodo ReturnType = t; }
public override void CheckSemantic(Scope scope, List<Error> errors) { bool toCheck = false; //busco si hay un tipo con ese mismo nombre en el scope local TypeInfo t = scope.Types.ContainsKey(Id) ? scope.Types[Id] : null; int temp = errors.Count; if (Id == "string" ) errors.Add(new Error(Row, Col, string.Format("Cannot declarate a type named <string>"))); if (Id == "int") errors.Add(new Error(Row, Col, string.Format("Cannot declarate a type named <int>"))); //si ya esta definido lo agrego a los errors if (t!= null) errors.Add(new Error(Row, Col, string.Format("The type \"{0}\" is already defined in this scope", Id))); //veo si el tipo es un tipo definido TypeInfo t1 = scope.ExistType(Type); //si no esta definido el padre lo agrego a los errores if (t1 == null) { //baseType = t1.BaseType.Name; bool exist = false; foreach (var ty in scope.TempTypes) { if (ty.Id == Type) { exist = true; toCheck = true; break; } } if(!exist) errors.Add(new Error(Row, Col, string.Format("The type \"{0}\" is not defined", Type))); } if (temp == errors.Count)//si no hay errores { TypeInfo res = new TypeInfo(Id, t1, TypeDecl.Alias); if (!toCheck) { res.Type = t1.Type;//parche baseType = t1.BaseType.Name; if (t1.IsRecord) res.Record_parameters = t1.Record_parameters; scope.Types.Add(Id, res); } else { res.Parent = new TypeInfo(Type,null,TypeDecl.Base); scope.TypesToCheck.Add(res); } } ReturnType = scope.ExistType("void"); }
public override void CheckSemantic(Scope scope, List<Error> errors) { countLoop++; //chekeo la semantica de la expr inicial ExprFor.CheckSemantic(scope, errors); //si el tipo de retorno no es int lanzo un error if (ExprFor.ReturnType!= null && ExprFor.ReturnType.BaseType.Name != "int") errors.Add(new Error(Row, Col, "The first expression of <for> must be an int")); //chekeo la semantica de la expr final ExprTo.CheckSemantic(scope, errors); //si no tiene errores esa expr //si el tipo de retorno no es int lanzo un error if (ExprTo.ReturnType != null && ExprTo.ReturnType.BaseType.Name != "int") errors.Add(new Error(Row, Col, "The To'expression of <for> must be an int")); //creo un nuevo scope Scope for_scope = new Scope(scope); //agrego la var de ciclo for_scope.Variables.Add(IdLoop, new VarInfo(IdLoop, scope.ExistType("int"))); for_scope.IdLoop = IdLoop; ExprDo.CheckSemantic(for_scope, errors); ReturnType = new TypeInfo("void", null, TypeDecl.Base); countLoop--; }
public override void CheckSemantic(Scope scope, List<Error> errors) { bool toCheck = false; //busco si hay un tipo con ese mismo nombre en el scope local TypeInfo t = scope.Types.ContainsKey(Id) ? scope.Types[Id] : null; int temp = errors.Count; if (Id == Type) errors.Add(new Error(Row, Col, string.Format("The array \"{0}\" can't be recursive",Id))); if (Id == "string") errors.Add(new Error(Row, Col, string.Format("Cannot declarate a type named <string>"))); if (Id == "int") errors.Add(new Error(Row, Col, string.Format("Cannot declarate a type named <int>"))); //si ya esta existe lo agrego a los errors if (t != null) errors.Add(new Error(Row, Col, string.Format("The type \"{0}\" is already defined in this scope", Id))); //busco si el tipo del array esta definido en el scope global TypeInfo t1 = scope.ExistType(Type); //si no esta definido el scope global lo agrego a los errors if (t1 == null) { bool exist = false; foreach (var ty in scope.TempTypes) { if (ty.Id == Type) { exist = true; toCheck = true; break; } } if(!exist) errors.Add(new Error(Row, Col, string.Format("The type \"{0}\" is not defined in this scope", Type))); } if (temp == errors.Count)//si no hay errores { TypeInfo res = new TypeInfo(Id, null, TypeDecl.Array); if (!toCheck) { res.Type = t1; scope.Types.Add(Id, res); } else { scope.TypesToCheck.Add(res); } } ReturnType = scope.ExistType("void"); }
public override void CheckSemantic(Scope scope, List<Error> errors) { if (countLoop <= 0) errors.Add(new Error(Row, Col, "The break is illegal outside <for> or <while>")); else havebreak = true; ReturnType = scope.ExistType("void"); }
public override void CheckSemantic(Scope scope, List<Error> errors) { //busco si hay un tipo con ese mismo nombre en el scope local TypeInfo t = scope.Types.ContainsKey(Id) ? scope.Types[Id] : null; int temp = errors.Count; if (Id == "string") errors.Add(new Error(Row, Col, string.Format("Cannot declarate a type named <string>"))); if (Id == "int") errors.Add(new Error(Row, Col, string.Format("Cannot declarate a type named <int>"))); //si ya esta definido lo agrego a los errors if (t != null) errors.Add(new Error(Row, Col, string.Format("The type \"{0}\" is already defined in this scope", Id))); else { foreach (Parameter p in Parameters)//veo si todos los campos del record son tipos definidos { TypeInfo t1 = scope.ExistType(p.Type); if (t1 == null) { //busco si es alguno de mi bloque bool exist = false; foreach (var ty in scope.TempTypes) { if (ty.Id == p.Type) { exist = true; break; } } if(!exist) errors.Add(new Error(Row, Col, string.Format("The type \"{0}\" is not defined", p.Type))); } } } if (temp == errors.Count)//si no hay errores { TypeInfo res = new TypeInfo(Id,null, TypeDecl.Record); res.Record_parameters = Parameters; scope.Types.Add(Id, res); } ReturnType = scope.ExistType("void"); }
public override void CheckSemantic(Scope scope, List<Error> errors) { ExprIf.CheckSemantic(scope, errors); if (ExprIf.ReturnType!= null && ExprIf.ReturnType.BaseType.Name != "int") errors.Add(new Error(Row, Col, "The condition's expressions of <if-then> must be an int")); ExprThen.CheckSemantic(scope, errors); if (ExprThen is IBreakable) havebreak = ((IBreakable)ExprThen).HaveBreak; if (ExprThen.ReturnType!= null && ExprThen.ReturnType.BaseType.Name != "void") errors.Add(new Error(Row, Col, "The body's expressions of <if-then> must not return a value")); ReturnType = scope.ExistType("void"); }
public override void CheckSemantic(Scope scope, List<Error> errors) { string type = ""; Expr.CheckSemantic(scope, errors); //compruebo q la var sea de tipo record if (Expr.ReturnType != null && Expr.ReturnType.typedecl != TypeDecl.Record) errors.Add(new Error(Row, Col, string.Format("The expression must be record type"))); else { //compruebo que el record tenga un campo con ese nombre sino lanzo un error type = HaveField(Expr.ReturnType); if (type == "") errors.Add(new Error(Row, Col, string.Format("The type \"{0}\" don't have any field \"{1}\"", Expr.ReturnType.Name, Field))); } ReturnType = scope.ExistType(type); }
public override void CheckSemantic(Scope scope, List<Error> errors) { countLoop++; ExprWhile.CheckSemantic(scope, errors); if (ExprWhile.ReturnType!= null && ExprWhile.ReturnType.BaseType.Name != "int") errors.Add(new Error(Row, Col, "The first expression of <while> must be an int")); else { ExprDo.CheckSemantic(scope, errors); if (ExprDo.ReturnType!= null && ExprDo.ReturnType.BaseType.Name != "void") errors.Add(new Error(Row, Col, "The body's expression of <while> must not return a value")); } ReturnType = scope.ExistType("void"); countLoop--; }
public void CheckHeader(List<FunctionDeclNode> listf,List<Error> errors,Scope scope) { foreach (FunctionDeclNode function in listf) { //busco si existe una funcion en el scope con ese mismo nombre FunctionInfo f = scope.Functions.ContainsKey(function.IdFunction) ? scope.Functions[function.IdFunction] : null; //busco si existe una variable en el scope con el mismo nombre //ya q variables y funciones comparten el mismo namespace VarInfo v = scope.Variables.ContainsKey(function.IdFunction) ? scope.Variables[function.IdFunction] : null; //si ya esta definida esa funcion en el scope lo agrego a los errores if (f != null) errors.Add(new Error(Row, Col, string.Format("The function \"{0}\" is already exist in this scope", function.IdFunction)));//si ya existe en el scope del padre //si hay una variable con ese nombre lanzo un error else if (v != null) errors.Add(new Error(Row, Col, string.Format("Already exist a variable named \"{0}\"", function.IdFunction))); //no se puede definir una funcion con el mismo nombre de alguna de la libreria //sino lanzo un error foreach (var func in FunctionsLibrary) { if (function.IdFunction == func) errors.Add(new Error(Row, Col, string.Format("Cannot create a function named \"{0}\"", function.IdFunction))); } //chekeo q no haya 2 params con el mismo nombre foreach (var parameters in function.Parameters) { List<Parameter> equals = function.Parameters.FindAll(p => p.Id == parameters.Id); if (equals.Count() > 1) { errors.Add(new Error(Row, Col, string.Format("Cannot be 2 parameters with the same name"))); break; } } //chekeo q el tipo de todos los parametros este definido foreach (var parameter in function.Parameters) { TypeInfo t1 = scope.ExistType(parameter.Type); if (t1 == null) errors.Add(new Error(Row, Col, string.Format("The type of parameter \"{0}\" is not defined", parameter.Id))); } } }
public override void CheckSemantic(Scope scope, List<Error> errors) { //busco si existe una funcion en el scope FunctionInfo f = scope.ExistFunctions(IdFunction); //si no esta lanzo un error if (f == null) errors.Add(new Error(Row, Col, string.Format("Doesn't exist any function with name \"{0}\"", IdFunction))); else { //chekeo q la ctadad de parametros sea la misma if (Params.Count != f.Parameters.Count) errors.Add(new Error(Row,Col,string.Format("The function \"{0}\" don't receive {1} parameter(s)",IdFunction,Params.Count()))); //chekeo q los parametros sean del mismo tipo de la funcion for (int i = 0; i < Params.Count(); i++) { //chekeo la semantica de cada expr Params[i].CheckSemantic(scope, errors); TypeInfo temp = scope.ExistType(f.Parameters[i].Type); //si no tiene problemas veo que sea del tipo correcto if (Params[i].ReturnType != null && Params[i].ReturnType.BaseType.Name != temp.BaseType.Name) { if (Params[i].ReturnType.BaseType.Name == "nil") { if (temp.BaseType.Name == "int") errors.Add(new Error(Row, Col, string.Format("The parameters \"{0}\" must be <{1}>", i + 1, f.Parameters[i].Type))); } else { errors.Add(new Error(Row, Col, string.Format("The parameters \"{0}\" must be <{1}>", i + 1, f.Parameters[i].Type))); } } } ReturnType = f.ReturnType; } }
public override void CheckSemantic(Scope scope, List<Error> errors) { TypeInfo t = null; //compruebo que exista el tipo del array t = scope.ExistType(Name); //sino lanzo un error if (t == null) errors.Add(new Error(Row, Col, string.Format("Doesn't exist any type with name \"{0}\"", Name))); else if (!t.IsArray) errors.Add(new Error(Row, Col, string.Format("The type \"{0}\" isn't array", Name))); else { //chekea la semantica de la expr del length el array Length.CheckSemantic(scope, errors); if (Length.ReturnType != null && Length.ReturnType.BaseType.Name != "int") errors.Add(new Error(Row, Col, "The type of length of array must be an int")); //chekea la semantica de la expr de rellenar el array Value.CheckSemantic(scope, errors); //compruebo que el valor para rellenar el array sea del mismo tipo que el base de este if (Value.ReturnType != null && t.Type.BaseType.Name != Value.ReturnType.BaseType.Name) { if (Value.ReturnType.BaseType.Name == "nil") { if(t.BaseType.IsInt) errors.Add(new Error(Row, Col, string.Format("The value to fill array cannot be <nil>", t.Type.Name))); } else errors.Add(new Error(Row, Col, string.Format("The value to fill array must be <{0}>", t.Type.Name))); } } ReturnType = t; }
public override void CheckSemantic(Scope scope, List<Error> errors) { int loops = countLoop; countLoop = 0; int count = errors.Count(); TypeInfo t = null; //creo un nuevo scope para la funcion Scope func_scope = new Scope(scope); foreach (var param in Parameters) { func_scope.Variables.Add(param.Id, new VarInfo(param.Id, scope.ExistType(param.Type))); } //cuando esta dentro de un bloque //agrego todas las funciones al scope local para //que puedan ser llamadas dentro de esta if (scope.TempFunctions.Count() != 0) { foreach (var function_decl in scope.TempFunctions) { if (function_decl.IdType == "") func_scope.Functions.Add(function_decl.IdFunction, new FunctionInfo(function_decl.IdFunction, new TypeInfo("void", null, TypeDecl.Base), function_decl.Parameters)); else func_scope.Functions.Add(function_decl.IdFunction, new FunctionInfo(function_decl.IdFunction, scope.ExistType(function_decl.IdType), function_decl.Parameters)); } } //para cuando sea un proceso(no retorna valor) if (IdType == "void") { //cheekeo la semantica de expr Expr.CheckSemantic(func_scope, errors); //el tipo de retorno de expr tiene q ser void ya q es un proceso if (Expr.ReturnType!= null && Expr.ReturnType.Name != "void") errors.Add(new Error(Row, Col, string.Format("The procedure \"{0}\"cannot return any value", IdFunction))); t = new TypeInfo("void", null, TypeDecl.Base); } //para cuando es un funcion (retorna valor) else { t = scope.ExistType(IdType); //cuando no esta en los tipos definidos lanzo un error if (t == null) errors.Add(new Error(Row, Col, string.Format("The type \"{0}\" could not be found", IdType))); else { //cheekeo la semantica de expr Expr.CheckSemantic(func_scope, errors); //esta pero no es el mismo q el del retorno de expr if (Expr.ReturnType != null && t.BaseType.Name != Expr.ReturnType.BaseType.Name) errors.Add(new Error(Row, Col, string.Format("The return type of \"{0}\" must be {1}", IdFunction, IdType))); } } //si no hay errores de ningun tipo if (count == errors.Count()) { //agrego la funcion al scope global FunctionInfo func = new FunctionInfo(IdFunction, t, Parameters); scope.Functions.Add(IdFunction, func); ReturnType = new TypeInfo("void", null, TypeDecl.Base); } countLoop = loops; }
public override void CheckSemantic(Scope scope, List<Error> errors) { scope.TempTypes = new List<TypeDeclNode>(); foreach (var t in Types) { scope.TempTypes.Add(t); } foreach (var t in Types) { t.CheckSemantic(scope, errors); } if (scope.TypesToCheck.Count() > 0) { scope.TypesToCheck.Reverse(); for (int i = 0; i < scope.TypesToCheck.Count();i++) { TypeInfo t = scope.TypesToCheck[i]; if (t.typedecl == TypeDecl.Array) { TypeArrayNode res = (TypeArrayNode)scope.TempTypes.Find(type => type.Id == t.Name); TypeInfo t1 = scope.ExistType(res.Type);//busco si ya existe el tipodel array if (t1 != null) { t.Type = t1; scope.Types.Add(t.Name, t); scope.TypesToCheck.RemoveAt(i); } } if (t.typedecl == TypeDecl.Alias) { TypeInfo type = scope.ExistType(t.Parent.Name); if (type != null) { t.Parent = type; scope.Types.Add(t.Name, t); scope.TypesToCheck.RemoveAt(i); } } } } //chekeo por segunda vez los q se kedaron if (scope.TypesToCheck.Count() > 0) { for(int i = 0; i < scope.TypesToCheck.Count();i++) { TypeInfo t = scope.TypesToCheck[i]; if (t.typedecl == TypeDecl.Array) { TypeArrayNode res = (TypeArrayNode)scope.TempTypes.Find(type => type.Id == t.Name); TypeInfo t1 = scope.ExistType(res.Type);//busco si ya existe el tipodel array if (t1 == null) { errors.Add(new Error(Row, Col, string.Format("The type of the array is not defined"))); } else { t.Type = t1; scope.Types.Add(t.Name, t); scope.TypesToCheck.Remove(t); } } if (t.typedecl == TypeDecl.Alias) { TypeInfo type = scope.ExistType(t.Parent.Name); if (type != null) { t.Parent = type; scope.Types.Add(t.Name, t); scope.TypesToCheck.RemoveAt(i); } else { errors.Add(new Error(Row, Col, string.Format("The type \"{0}\" do not not pass through record or array", t.Name))); } } } scope.TypesToCheck.Clear(); } }
public override void CheckSemantic(Scope scope, List<Error> errors) { TypeInfo t = null; int count = errors.Count; //busco si existe una variable en el scope con el mismo nombre VarInfo v = scope.Variables.ContainsKey(IdVar) ? scope.Variables[IdVar] : null; //busco si existe una funcion en el scope con el mismo nombre //ya q variables y funciones comparten el mismo namespace FunctionInfo f = scope.Functions.ContainsKey(IdVar) ? scope.Functions[IdVar] : null; //si ya esta definida esa variable en el scope lo agrego a los errores if (v != null) errors.Add(new Error(Row, Col, string.Format("The variable \"{0}\" is already exist in this scope", IdVar))); //si hay una funcion con ese nombre lanzo un error else if (f != null) errors.Add(new Error(Row, Col, string.Format("Already exist a function with name \"{0}\"", IdVar))); else { int temp = errors.Count(); //chekeo la semantica de la expr Expr.CheckSemantic(scope, errors); if (IdType == "")//cuando no esta especifcado el tipo { //no puede ser null porq no le podria inferir el tipo if (Expr.ReturnType!= null && Expr.ReturnType.Name == "nil") errors.Add(new Error(Row, Col, string.Format("Cannot assign <nil> to a variable without explicit type"))); if (Expr.ReturnType != null && Expr.ReturnType.Name == "void") errors.Add(new Error(Row, Col, string.Format("Cannot infer the type of the variable \"{0}\"", IdVar))); t = Expr.ReturnType; } else { t = scope.ExistType(IdType); //cuando no esta en los tipos definidos lanzo un error if (t == null) errors.Add(new Error(Row, Col, string.Format("The type \"{0}\" could not be found", IdType))); //esta pero no es el mismo q el del retorno de expr if (t != null && Expr.ReturnType!= null && t.Name != Expr.ReturnType.Name) { if (!AreAlias(t, Expr.ReturnType)) { //string type = t.BaseType.Name; //si no es de tipo int o string o record y expr retorna nil lanzo un error if (Expr.ReturnType!= null && Expr.ReturnType.BaseType.Name == "nil") { if (t.IsInt) errors.Add(new Error(Row, Col, string.Format("Cannot assign <nil> to a varible of type \"{0}\"", IdType))); } else errors.Add(new Error(Row, Col, string.Format("Cannot assisgn \"{0}\" to a variable of type \"{1}\"", Expr.ReturnType.Name, IdType))); } } //en el caso de que sea un record verifico q los campos del record estan en el mimso orden if (t != null && Expr.ReturnType!= null && t.typedecl == TypeDecl.Record && Expr.ReturnType.BaseType.Name != "nil") { for (int i = 0; i < t.Record_parameters.Count; i++) { if (t.Record_parameters[i].Type != Expr.ReturnType.Record_parameters[i].Type) errors.Add(new Error(Row, Col, string.Format("The fields is'nt the order correct"))); } } } } //cuando no hay errores if (count == errors.Count) { VarInfo var = new VarInfo(IdVar, t); scope.Variables.Add(IdVar, var); } ReturnType = new TypeInfo("void", null, TypeDecl.Base); }