Beispiel #1
0
        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);
        }
Beispiel #2
0
 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;
 }
Beispiel #3
0
        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);
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        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);
                }
            }
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
        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);
            }
        }
Beispiel #12
0
        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);
        }
Beispiel #13
0
        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);
        }
Beispiel #14
0
 public SemanticAttr(string id, SemanticType type)
 {
     Id   = id;
     Type = type;
 }