public bool Visit(AST_ClassProperty node) { bool solve = true; var type = CurrContext.GetType(node.decl.id.Id); bool visit_tuple = true; if (node.exp != null) { visit_tuple = node.exp.Visit(this); } if (!visit_tuple || type != null) { CurrErrorLoger.LogError(node.row, node.col, "El tipo " + node.decl.id.Id + " ya posee un tipo"); return(false); } if (type == null) { if (!All_Types.ContainsKey(node.decl.type.Type)) { CurrErrorLoger.LogError(node.row, node.col, "Tipo no definido"); return(false); } else { //if (node.decl.type.Type == "int") // node.decl.type.Type = "Int"; //if (node.decl.type.Type == "string") // node.decl.type.Type = "String"; //if (node.decl.type.Type == "bool") // node.decl.type.Type = "Bool"; node.decl.id.MyType = All_Types[node.decl.type.Type]; CurrContext.SetType(node.decl.id.Id, All_Types[node.decl.type.Type]); } } if (node.decl.id.MyType != null && node.exp != null) { SemanticType lca = SemanticType.LCA(All_Types[node.decl.type.Type], node.exp.MyType); if (lca.Name != node.decl.id.MyType.Name) { CurrErrorLoger.LogError(node.row, node.col, "El tipo " + node.exp.MyType.Name + " no se conforma a " + node.decl.type.Type); return(false); } } return(solve); }
public static void SetLevels(SemanticType t, Dictionary <string, bool> mark) { if (t.Father == null) { return; } if (mark[t.Name]) { return; } mark[t.Name] = true; SetLevels(t.Father, mark); t.Level = t.Father.Level + 1; }
public bool Visit(AST_Asignacion node) { if (!node.Exp.Visit(this)) { return(false); } var x = CurrContext.GetType(node.Id); //if (x.Name != node.Exp.MyType.Name) if (SemanticType.LCA(x, node.Exp.MyType).Name != x.Name) { CurrErrorLoger.LogError(node.row, node.col, "El tipo de " + node.Exp.MyType.Name + " no se conforma a " + x.Name); return(false); } node.MyType = node.Exp.MyType; return(true); }
public bool Visit(AST_ClassDef node) { bool solve = true; CurrContext = CurrContext.CreateChild(); SemanticType father = All_Types[node.Id.Id].Father; while (true) { var my_atributes = father.GetAllAttr(); foreach (var attr in my_atributes) { if (CurrContext.IsDefine(attr.Id)) { solve = false; CurrErrorLoger.LogError(node.row, node.col, "Propiedad " + attr.Id + " previamente definida"); } CurrContext.Define(attr.Id); } father = father.Father; if (father == null) { break; } } foreach (var prop in node.Property_list.Propertys) { if (CurrContext.IsDefine(prop.decl.id.Id)) { solve = false; CurrErrorLoger.LogError(prop.decl.row, prop.decl.col, "Propiedad " + node.Id + " previamente definida"); } else { CurrContext.Define(prop.decl.id.Id); } } solve = node.Method_list.Visit(this); if (!CurrContext.NullFather()) { CurrContext = CurrContext.GetParent(); } return(solve); }
public bool Visit(AST_CaseOf node) { if (!node.expr.Visit(this)) { return(false); } var types = new List <SemanticType>(); foreach (var item in node.props.Propertys) { CurrContext = CurrContext.CreateChild(); if (!item.decl.Visit(this)) { if (!CurrContext.NullFather()) { CurrContext = CurrContext.GetParent(); } return(false); } if (!item.exp.Visit(this)) { if (!CurrContext.NullFather()) { CurrContext = CurrContext.GetParent(); } return(false); } CurrContext = CurrContext.GetParent(); types.Add(item.exp.MyType); } SemanticType lca = types[0]; for (int i = 1; i < types.Count; i++) { lca = SemanticType.LCA(lca, types[i]); } node.MyType = lca; return(true); }
public static Dictionary <string, SemanticType> BuildSystemType() { Dictionary <string, SemanticType> solve = new Dictionary <string, SemanticType>(); var Object = new SemanticType("Object"); var SelfType = new SemanticType("SELF_TYPE"); var String = new SemanticType("String", Object); var Int = new SemanticType("Int", Object); var IO = new SemanticType("IO", Object); var Bool = new SemanticType("Bool", Object); var abort = new SemanticMethod("abort", Object); var type_name = new SemanticMethod("type_name", String); var copy = new SemanticMethod("copy", SelfType); Object.Methods = new List <SemanticMethod> { abort, type_name, copy }; var length = new SemanticMethod("length", Int); var concat = new SemanticMethod("concat", String, new SemanticAttr[] { new SemanticAttr("x", String) }); var substring = new SemanticMethod("substr", String, new SemanticAttr[] { new SemanticAttr("i", Int), new SemanticAttr("l", Int) }); String.Methods = new List <SemanticMethod> { length, concat, substring }; var out_string = new SemanticMethod("out_string", SelfType, new SemanticAttr[] { new SemanticAttr("x", String) }); var out_int = new SemanticMethod("out_int", SelfType, new SemanticAttr[] { new SemanticAttr("x", Int) }); var in_string = new SemanticMethod("in_string", String); var in_int = new SemanticMethod("in_int", Int); IO.Methods = new List <SemanticMethod> { out_string, out_int, in_string, in_int }; foreach (var item in (new SemanticType[] { Object, Int, IO, SelfType, String, Bool })) { solve.Add(item.Name, item); } return(solve); }
public bool Visit(AST_Call node) { bool solve = true; if (!CurrType.HasMethod(node.id.Id)) { CurrErrorLoger.LogError(node.row, node.col, "El tipo " + CurrType.Name + " no posee el metodo " + node.id.Id); return(false); } var my_method = CurrType.GetMethod(node.id.Id); var invok_params = node.arg.stament_list; if (my_method.AttrParams.Count != invok_params.Count) { CurrErrorLoger.LogError(node.row, node.col, "No coinciden la cantidad de parametros"); return(false); } for (int i = 0; i < my_method.AttrParams.Count; i++) { if (!invok_params[i].Visit(this)) { return(false); } if (SemanticType.LCA(my_method.AttrParams[i].Type, invok_params[i].MyType).Name != my_method.AttrParams[i].Type.Name) { CurrErrorLoger.LogError(node.row, node.col, "No coinciden los tipos de los parametros"); return(false); } } node.MyType = my_method.ReturnType; return(true); }
public SemanticMethod ChangeType(SemanticType t) { var l = new List <SemanticAttr>(); foreach (var item in AttrParams) { if (item.Type.Name == "SELF_TYPE") { l.Add(item.ChangeType(t)); } else { l.Add(item); } } var solve = new SemanticMethod(Name, ReturnType, AttrParams); solve.Self = Self; if (solve.ReturnType.Name == "SELF_TYPE") { solve.ReturnType = t; } return(solve); }
public bool Visit(AST_ExpCall node) { bool solve = true; bool visit_left = node.expr.Visit(this); if (node.explicittype == null) { if (node.expr.MyType == null) { return(false); } var my_type = node.expr.MyType; if (!my_type.HasMethod(node.id.Id)) { CurrErrorLoger.LogError(node.row, node.col, "El tipo " + my_type.Name + " no posee el metodo " + node.id.Id); return(false); } var my_method = my_type.GetMethod(node.id.Id); var invok_params = node.arg.stament_list; if (my_method.AttrParams.Count != invok_params.Count) { CurrErrorLoger.LogError(node.row, node.col, "La cantidad de parametros no coinciden"); return(false); } for (int i = 0; i < my_method.AttrParams.Count; i++) { if (!invok_params[i].Visit(this)) { return(false); } if (SemanticType.LCA(my_method.AttrParams[i].Type, invok_params[i].MyType).Name != my_method.AttrParams[i].Type.Name) //if (my_method.AttrParams[i].Type.Name != invok_params[i].MyType.Name) { CurrErrorLoger.LogError(node.row, node.col, "No coinciden los tipos de los parametros"); return(false); } } node.MyType = my_method.ReturnType; return(true); } else { string cast_type_in_str = node.explicittype.Type; if (!All_Types.ContainsKey(cast_type_in_str)) { CurrErrorLoger.LogError(node.row, node.col, "El tipo al que se esta casteando no esta definido"); return(false); } var cast_type = All_Types[cast_type_in_str]; var my_type = node.expr.MyType; if (!cast_type.HasMethod(node.id.Id)) { CurrErrorLoger.LogError(node.row, node.col, "El tipo de casteo no posee ese metodo"); return(false); } var my_method = cast_type.GetMethod(node.id.Id); var invok_params = node.arg.stament_list; if (my_method.AttrParams.Count != invok_params.Count) { CurrErrorLoger.LogError(node.row, node.col, "La cantidad de parametros no coinciden"); return(false); } for (int i = 0; i < my_method.AttrParams.Count; i++) { if (!invok_params[i].Visit(this)) { return(false); } if (SemanticType.LCA(my_method.AttrParams[i].Type, invok_params[i].MyType).Name != my_method.AttrParams[i].Type.Name) //if (my_method.AttrParams[i].Type.Name != invok_params[i].MyType.Name) { CurrErrorLoger.LogError(node.row, node.col, "No coinciden los tipos de los parametros"); return(false); } } var lca = SemanticType.LCA(my_type, cast_type); node.MyType = my_method.ReturnType; if (lca.Name == cast_type.Name) { return(true); } else { CurrErrorLoger.LogError(node.row, node.col, "El tipo " + my_type.Name + "no se conforma" + cast_type.Name); return(false); } } }
public bool Visit(AST_Let node) { bool solve = true; CurrContext = CurrContext.CreateChild(); foreach (var arg in node.props.Propertys) { //if (arg.decl.type.Type == "int") // arg.decl.type.Type = "Int"; //if (arg.decl.type.Type == "string") // arg.decl.type.Type = "String"; //if (arg.decl.type.Type == "bool") // arg.decl.type.Type = "Bool"; if (!All_Types.ContainsKey(arg.decl.type.Type)) { CurrErrorLoger.LogError(node.row, node.col, "El tipo de la declaracion de la variable no existe"); if (!CurrContext.NullFather()) { CurrContext = CurrContext.GetParent(); } return(false); } if (arg.exp != null) { if (!arg.exp.Visit(this)) { if (!CurrContext.NullFather()) { CurrContext = CurrContext.GetParent(); } return(false); } if (SemanticType.LCA(arg.exp.MyType, All_Types[arg.decl.type.Type]).Name != All_Types[arg.decl.type.Type].Name) { CurrErrorLoger.LogError(node.row, node.col, "El tipo de la expresion no es un subtipo del tipo de la declaracion"); if (!CurrContext.NullFather()) { CurrContext = CurrContext.GetParent(); } return(false); } } if (CurrContext.GetTypeInMe(arg.decl.id.Id) == null) { CurrContext.SetType(arg.decl.id.Id, All_Types[arg.decl.type.Type]); } else { CurrContext.ChangeType(arg.decl.id.Id, All_Types[arg.decl.type.Type]); } } if (!node.expr.Visit(this)) { if (!CurrContext.NullFather()) { CurrContext = CurrContext.GetParent(); } return(false); } node.MyType = node.expr.MyType; if (!CurrContext.NullFather()) { CurrContext = CurrContext.GetParent(); } return(true); }
public bool Visit(AST_BinaryOp node) { bool solve = true; bool visit_right = node.Right.Visit(this); bool visit_left = node.Left.Visit(this); if (!visit_left || !visit_right) { return(false); } if (!All_Types.ContainsKey(node.Right.MyType.Name)) { CurrErrorLoger.LogError(node.Right.row, node.Right.col, "Tipo inexistente"); return(false); } if (!All_Types.ContainsKey(node.Left.MyType.Name)) { CurrErrorLoger.LogError(node.Left.row, node.Left.col, "Tipo inexistente"); return(false); } if (node.Op.Text == "=") { bool ok = true; if (node.Right.MyType.Name == "String" || node.Right.MyType.Name == "Int" || node.Right.MyType.Name == "Bool" || node.Left.MyType.Name == "String" || node.Left.MyType.Name == "Int" || node.Left.MyType.Name == "Bool" || node.Left.MyType.Name == "Object" || node.Right.MyType.Name == "Object") { ok = node.Right.MyType.Name == node.Left.MyType.Name; } //else solve &= false; node.MyType = All_Types["Bool"]; if (node.Right.MyType == null || node.Left.MyType == null || !ok) { return(false); } var lca = SemanticType.LCA(node.Right.MyType, node.Left.MyType); if (lca.Name != node.Right.MyType.Name && lca.Name != node.Left.MyType.Name) { CurrErrorLoger.LogError(node.row, node.col, "No se encuentran en la misma rama del arbol de herencia"); return(false); } return(true); } else { if (node.Right.MyType.Name != node.Left.MyType.Name) { CurrErrorLoger.LogError(node.row, node.col, "Los tipos de la expresion deben ser iguales"); return(false); } if (node.Right.MyType.Name != "Int") { CurrErrorLoger.LogError(node.Right.row, node.Right.col, "El tipo de la expresion debe ser INT"); return(false); } if (node.Left.MyType.Name != "Int") { CurrErrorLoger.LogError(node.Left.row, node.Left.col, "El tipo de la expresion debe ser INT"); return(false); } if (node.Op.Text == "<" || node.Op.Text == "<=") { node.MyType = All_Types["Bool"]; } else { node.MyType = All_Types["Int"]; } return(true); } }
public bool Visit(AST_MethodDef node) { bool solve = true; if (!CurrType.HasMethod(node.Id.Id)) { CurrErrorLoger.LogError(node.row, node.col, "El tipo de retorno del metodo no existe"); return(false); } CurrContext = CurrContext.CreateChild(); //if (node.type.Type == "int") // node.type.Type = "Int"; //if (node.type.Type == "string") // node.type.Type = "String"; //if (node.type.Type == "bool") // node.type.Type = "Bool"; if (!All_Types.ContainsKey(node.type.Type)) { CurrErrorLoger.LogError(node.row, node.col, "El tipo de retorno del metodo no existe"); if (!CurrContext.NullFather()) { CurrContext = CurrContext.GetParent(); } return(false); } foreach (var arg in node.Propertys.Propertys) { //if (arg.decl.type.Type == "int") // arg.decl.type.Type = "Int"; //if (arg.decl.type.Type == "string") // arg.decl.type.Type = "String"; //if (arg.decl.type.Type == "bool") // node.type.Type = "Bool"; if (!All_Types.ContainsKey(arg.decl.type.Type)) { CurrErrorLoger.LogError(node.row, node.col, "El tipo de la declaracion del argumento no existe"); if (!CurrContext.NullFather()) { CurrContext = CurrContext.GetParent(); } return(false); } if (CurrContext.GetType(arg.decl.id.Id) == null) { CurrContext.SetType(arg.decl.id.Id, All_Types[arg.decl.type.Type]); } else { CurrContext.ChangeType(arg.decl.id.Id, All_Types[arg.decl.type.Type]); } } var visit = node.Statament.Visit(this); if (!visit) { if (!CurrContext.NullFather()) { CurrContext = CurrContext.GetParent(); } return(false); } SemanticType lca = SemanticType.LCA(All_Types[node.type.Type], node.Statament.MyType); if (lca.Name == node.type.Type) { solve &= true; } else { CurrErrorLoger.LogError(node.row, node.col, "El tipo " + node.Statament.MyType + " no se conforma a " + node.type.Type); if (!CurrContext.NullFather()) { CurrContext = CurrContext.GetParent(); } return(false); } if (!CurrContext.NullFather()) { CurrContext = CurrContext.GetParent(); } return(solve); }
public bool Visit(AST_ClassDef node) { if (node.Id.Id == "Main") { if (!All_Types["Main"].HasMethod("main")) { CurrErrorLoger.LogError(node.row, node.col, "Tiene que tener un metodo main"); return(false); } } bool solve = true; solve &= node.Property_list.Visit(this); solve &= node.Method_list.Visit(this); SemanticType curr = All_Types[node.Id.Id]; var my_methods = curr.Methods; while (curr.Father != null) { var curr_father = curr.Father; if (curr_father.Name == "Bool" || curr_father.Name == "String" || curr_father.Name == "Int") { CurrErrorLoger.LogError(node.row, node.col, "No se puede heredar de los tipos built_int"); return(false); } var father_method = curr_father.Methods; foreach (var mine in my_methods) { foreach (var him in father_method) { if (mine.Name == him.Name && mine.Name != "init") { if (mine.AttrParams.Count != him.AttrParams.Count) { CurrErrorLoger.LogError(node.row, node.col, "Para sobresicribir metodos deben tener la misma signatura"); solve = false; } else { var x = All_Types[node.Id.Id].GetMethod(mine.Name); var y = curr_father.GetMethod(him.Name); if (x.Name != y.Name || x.ReturnType.Name != y.ReturnType.Name) { solve = false; CurrErrorLoger.LogError(node.row, node.col, "Tiene que ser el mismo tipo de retorno para la redefinicion de metodos"); } else { for (int i = 0; i < mine.AttrParams.Count; i++) { if (mine.AttrParams[i].Type.Name != him.AttrParams[i].Type.Name) { solve = false; CurrErrorLoger.LogError(node.row, node.col, "Tienen que ser del mismo tipo los parametros para la redefinicion de metodos"); } } } } } } } curr = curr.Father; } return(solve); }
public SemanticAttr(string id, SemanticType type) { Id = id; Type = type; }