public override void CheckSemantic(Scope scope, List<Error> errors) { string id_var = ""; //chekeo la semantica del lvalue LeftExpr.CheckSemantic(scope, errors); TypeInfo t = LeftExpr.ReturnType; //en el caso de q sea una variable guardo //su valor para despues compararlo con el id del ciclo if (LeftExpr is VariableNode) id_var = ((VariableNode)LeftExpr).Value; //chekeo la semantica del rvalue RigthExpr.CheckSemantic(scope, errors); TypeInfo t1 = RigthExpr.ReturnType; if (t != null && t1 != null && t.Name != t1.Name) { if (t1.Name == "nil") { if (t.Name == "int") errors.Add(new Error(Row, Col, string.Format("Cannot assign nil to an int"))); } else if(t1.Name == "void") errors.Add(new Error(Row, Col, string.Format("The expression that try assign to \"{0}\" not return value", t.Name))); else errors.Add(new Error(Row, Col, string.Format("Cannot asssign \"{0}\" to \"{1}\"", t1.Name, t.Name))); } else { if (countLoop >0 && id_var == scope.IdLoop) errors.Add(new Error(Row, Col, string.Format("Cannot assign any value to variable \"{0}\" of <for>", scope.IdLoop))); } ReturnType = new TypeInfo("void", null, TypeDecl.Base); }
public void CheckSemantic(Scope scope, List<Error> errors, string op) { //coumpruebo sintacticamente el primer operando LeftOperand.CheckSemantic(scope, errors); if (RigthOperand != null) { //compruebo q el tipo de retorno del operando izq sea int if (LeftOperand.ReturnType!= null &&LeftOperand.ReturnType.BaseType.Name != "int") errors.Add(new Error(Row, Col, string.Format("The left operand in \"{0}\" operator must be return an int", op))); //coumpruebo sintacticamente el segundo operando RigthOperand.CheckSemantic(scope, errors); //compruebo q el tipo de retorno sea int if (RigthOperand.ReturnType != null && RigthOperand.ReturnType.BaseType.Name != "int") errors.Add(new Error(Row, Col, string.Format("The rigth operand in \"{0}\" operator must be return an int", op))); // pongo su tipo de retorno en int ReturnType = new TypeInfo("int",null,TypeDecl.Base); } else { ReturnType = LeftOperand.ReturnType; } }
public override void CheckSemantic(Scope scope, List<Error> errors) { VarInfo v = scope.ExistVariable(Value); if (v == null) errors.Add(new Error(Row, Col, string.Format("The variable \"{0}\" doesn't exist in the current scope", Value))); else ReturnType = v.Type; }
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) { 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 Scope(Scope parent) { this.parent = parent; Variables = new Dictionary<string, VarInfo>(); Types = new Dictionary<string, TypeInfo>(); Functions = new Dictionary<string, FunctionInfo>(); TempFunctions = new List<FunctionDeclNode>(); TempTypes = new List<TypeDeclNode>(); TypesToCheck = new List<TypeInfo>(); }
public override void CheckSemantic(Scope scope, List<Error> errors) { //chekeo la semantica de la expr Expr.CheckSemantic(scope, errors); //compruebo q el tipo de retorno de expr sea int if (Expr.ReturnType!= null && Expr.ReturnType.BaseType.Name != "int") errors.Add(new Error(Row, Col, "The expression must be return an int")); //pongo el tipo de retorno del nodo en int ReturnType = new TypeInfo("int", null, TypeDecl.Base); }
public override void CheckSemantic(Scope scope, List<Error> errors) { int count = errors.Count(); Id.CheckSemantic(scope, errors); lval = (TigerNode)Id; GetLValues(Access, ref lval); count = errors.Count(); lval.CheckSemantic(scope, errors); if (count == errors.Count()) ReturnType = lval.ReturnType; }
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) { 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) { 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) { 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 void CheckSemantic(Scope scope, List<Error> errors, string op) { string type = ""; string type1 = ""; //comprobando la semantica del primer operando LeftOperand.CheckSemantic(scope, errors); if (RigthOperand != null) { //coumpruebo que sea int el tipo de retorno if (LeftOperand.ReturnType != null && LeftOperand.ReturnType.BaseType.Name == "int") type = "int"; //sino veo si es string else if (LeftOperand.ReturnType!= null && LeftOperand.ReturnType.BaseType.Name == "string") type = "string"; //sino lanzo un error porq solo puede ser estos dos tipos else errors.Add(new Error(Row, Col, string.Format("The left operand in \"{0}\" operator must be return an int or a string", op))); //compruebo la semantica del segundo operando RigthOperand.CheckSemantic(scope, errors); //coumpruebo que sea int el tipo de retorno if (RigthOperand.ReturnType!= null && RigthOperand.ReturnType.BaseType.Name == "int") type1 = "int"; //sino veo si es string else if (RigthOperand.ReturnType!= null && RigthOperand.ReturnType.BaseType.Name == "string") type1 = "string"; //sino lanzo un error porq solo puede ser estos dos tipos else errors.Add(new Error(Row, Col, string.Format("The rigth operand in \"{0}\" must be return an int or a string", op))); //compruebo que ambos sean int o string if (type1 != type) { errors.Add(new Error(Row, Col, string.Format("The left and rigth operand in \"{0}\" operator may be either both <integer> or both <string>", op))); } ReturnType = new TypeInfo("int", null, TypeDecl.Base); } else { ReturnType = LeftOperand.ReturnType; } }
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) { //chekeo la semantica de expr Expr.CheckSemantic(scope, errors); //compruebo q la var sea de tipo array if (Expr.ReturnType!= null && Expr.ReturnType.typedecl != TypeDecl.Array) errors.Add(new Error(Row, Col, string.Format("Only can indexer to array type"))); else { //chekeo la semantica de index Index.CheckSemantic(scope, errors); //compruebo que el tipo de retorno de index sea int if ( Index.ReturnType != null && Index.ReturnType.BaseType.Name != "int") errors.Add(new Error(Row, Col, string.Format("The index must be return an int"))); } //actualizo el tipo de retorno del nodo ReturnType = Expr.ReturnType.Type; }
public override void CheckSemantic(Scope scope, List<Error> errors) { //limpio el bloque de funciones temporales scope.TempFunctions = new List<FunctionDeclNode>(); int temp = errors.Count(); //agrego las funciones a la lista temporal foreach (var function in Functions) { if (scope.TempFunctions.Contains(function)) errors.Add(new Error(Row, Col, string.Format("Already exist a function named \"{0}\" in this block",function.IdFunction))); else scope.TempFunctions.Add(function); } CheckHeader(scope.TempFunctions,errors,scope); if (temp == errors.Count()) { //chekeo la semantice de cada funcion en el bloque foreach (var function in Functions) { function.CheckSemantic(scope, errors); } } }
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-else> must be an int")); ExprThen.CheckSemantic(scope, errors); if (ExprThen is IBreakable) havebreak = ((IBreakable)ExprThen).HaveBreak; TypeInfo t = ExprThen.ReturnType; ExprElse.CheckSemantic(scope, errors); if (ExprElse is IBreakable) havebreak = ((IBreakable)ExprElse).HaveBreak; TypeInfo t1 = ExprElse.ReturnType; if (t.Name != t1.Name) { errors.Add(new Error(Row, Col, string.Format("The second and third expressions of <if-then-else> must be of the same type"))); } else ReturnType = t; }
public override void CheckSemantic(Scope scope, List<Error> errors) { TypeInfo t = null; for (int i = 0; i < Exprs.Count(); i++) { Exprs[i].CheckSemantic(scope, errors); if (Exprs[i] is IBreakable) { if (((IBreakable)Exprs[i]).HaveBreak) existbreak = true; } if (i == Exprs.Count() - 1 ) { t = Exprs[i].ReturnType; } } if (!existbreak) { ReturnType = (t == null) ? new TypeInfo("void", null, TypeDecl.Base) : t; } else ReturnType = new TypeInfo("void", null, TypeDecl.Base); }
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) { ReturnType = new TypeInfo("int",null,TypeDecl.Base); }
public abstract void CheckSemantic(Scope scope,List<Error> errors);
public override void CheckSemantic(Scope scope, List<Error> errors) { base.CheckSemantic(scope, errors, "="); }
public override void CheckSemantic(Scope scope, List<Error> errors) { int count = errors.Count(); //inicializo el scope del let Scope letscope = new Scope(scope); //para guadar siempre la ultima declaracion DeclarationNode temp = null; //para guardar los bloques consecutivos de tipos y funciones List<TypeDeclNode> blockTypes = new List<TypeDeclNode>(); List<FunctionDeclNode> blockFunctions = new List<FunctionDeclNode>(); //guardo el primer decl if (Declarations.Count() != 0) { temp = Declarations[0]; if (temp is FunctionDeclNode) blockFunctions.Add((FunctionDeclNode)temp); else if (temp is TypeDeclNode) blockTypes.Add((TypeDeclNode)temp); else temp.CheckSemantic(letscope, errors); } if (Declarations.Count() == 1) { if (temp is TypeDeclNode) { CheckSemanticBlockTypes(blockTypes, letscope, errors); blockTypes = new List<TypeDeclNode>(); } else { CheckSemanticBlockFunctions(blockFunctions, letscope, errors); blockFunctions = new List<FunctionDeclNode>(); } } //recorro las declaraciones y voy rellenando las listas //en dependencia del tipo de delaracion for (int i = 1; i < Declarations.Count(); i++) { if (Declarations[i] is TypeDeclNode) { blockTypes.Add((TypeDeclNode)Declarations[i]); if (temp is FunctionDeclNode) { CheckSemanticBlockFunctions(blockFunctions, letscope, errors); blockFunctions = new List<FunctionDeclNode>(); } } else if (Declarations[i] is FunctionDeclNode) { blockFunctions.Add((FunctionDeclNode)Declarations[i]); if (temp is TypeDeclNode) { CheckSemanticBlockTypes(blockTypes, letscope, errors); blockTypes = new List<TypeDeclNode>(); } } else //(Declarations[i] is VariableDeclNode) { if (temp is TypeDeclNode) { CheckSemanticBlockTypes(blockTypes, letscope, errors); blockTypes = new List<TypeDeclNode>(); } if (temp is FunctionDeclNode) { CheckSemanticBlockFunctions(blockFunctions, letscope, errors); blockFunctions = new List<FunctionDeclNode>(); } Declarations[i].CheckSemantic(letscope, errors); } temp = Declarations[i]; } if (blockFunctions.Count() > 0) { CheckSemanticBlockFunctions(blockFunctions, letscope, errors); } if (blockTypes.Count() > 0) { CheckSemanticBlockTypes(blockTypes, letscope, errors); } TypeInfo t = null; //chequeo la semantica de las expresiones //en la seccion in-end si existe alguna if (Exprs.Count() > 0) { for (int i = 0; i < Exprs.Count() - 1; i++) { Exprs[i].CheckSemantic(letscope, errors); } //chekeo la semantica de la ultima expresion y si //no tiene errores pongo su tipo de retorno como tipo de retorno del let int aux = errors.Count(); Exprs[Exprs.Count() - 1].CheckSemantic(letscope, errors); if (aux == errors.Count()) t = Exprs[Exprs.Count() - 1].ReturnType; } //actualizo el tipo de retorno del nodo if (t != null) ReturnType = t; else ReturnType = new TypeInfo("void", null, TypeDecl.Base); }
//chekeo la semantica de las declaraciones de tipo //en dependencia de si es un bloque o no void CheckSemanticBlockTypes(List<TypeDeclNode> blockTypes, Scope scope, List<Error> errors) { TypesBlockNode block_t = new TypesBlockNode(blockTypes); block_t.CheckSemantic(scope, errors); }
//chekeo la semantica de las declaraciones de funciones //en dependencia de si es un bloque o no void CheckSemanticBlockFunctions(List<FunctionDeclNode> blockFunctions, Scope scope, List<Error> errors) { FunctionsBlockNode block_f = new FunctionsBlockNode(blockFunctions); block_f.CheckSemantic(scope, errors); }
public void CheckSemantic(Scope scope, List<Error> errors, string op) { string type = ""; string type1 = ""; //comprobando la semantica del primer operando LeftOperand.CheckSemantic(scope, errors); if (RigthOperand != null) { //guardo el tipo de retorno del operando izquierdo if (LeftOperand.ReturnType!= null && LeftOperand.ReturnType.BaseType.Name == "int") type = "int"; //sino veo si es string else if (LeftOperand.ReturnType != null && LeftOperand.ReturnType.BaseType.Name == "string") type = "string"; //sino veo si es un record else if (LeftOperand.ReturnType != null && LeftOperand.ReturnType.typedecl == TypeDecl.Record) type = "record"; //sino veo si es array else if (LeftOperand.ReturnType != null && LeftOperand.ReturnType.typedecl == TypeDecl.Array) type = "array"; //sino veo si es nil else if (LeftOperand.ReturnType != null && LeftOperand.ReturnType.BaseType.Name == "nil") type = "nil"; //sino lanzo un error porq solo puede ser uno de estos tipos else errors.Add(new Error(Row, Col, string.Format("The left operand in \"{0}\" operator must be one of the defined types", op))); //compruebo la semantica del segundo operando RigthOperand.CheckSemantic(scope, errors); //gurado el tipo de retorno del segundo operando if (RigthOperand.ReturnType != null && RigthOperand.ReturnType.BaseType.Name == "int") type1 = "int"; //sino veo si es string else if (RigthOperand.ReturnType != null && RigthOperand.ReturnType.BaseType.Name == "string") type1 = "string"; //sino veo si es un record else if (RigthOperand.ReturnType != null && RigthOperand.ReturnType.typedecl == TypeDecl.Record) type1 = "record"; //sino veo si es array else if (RigthOperand.ReturnType != null && RigthOperand.ReturnType.typedecl == TypeDecl.Array) type1 = "array"; //sino veo si es nil else if (RigthOperand.ReturnType != null && RigthOperand.ReturnType.BaseType.Name == "nil") type1 = "nil"; //sino lanzo un error porq solo puede ser estos dos tipos else errors.Add(new Error(Row, Col, string.Format("The rigth operand in \"{0}\" must be one of the defined types", op))); //si son de distintos tipos y ninguno es nil lanzo un error if (type1 != type) { if(type != "nil" && type1 != "nil") errors.Add(new Error(Row, Col, string.Format("The left and rigth operand in \"{0}\" operator may be either of the same type", op))); } //si son del mismo tipo pero nil lanzo un error else if (type == "nil") { errors.Add(new Error(Row, Col, string.Format("The left and rigth operand in \"{0}\" operator can't be nill", op))); } // actualizo su tipo de retorno en int ReturnType = new TypeInfo("int", null, TypeDecl.Base); } else { ReturnType = LeftOperand.ReturnType; } }