コード例 #1
0
        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);
        }
コード例 #2
0
ファイル: LogicOpNode.cs プロジェクト: oisbel/TigerCompiler
        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;
            }
        }
コード例 #3
0
ファイル: VariableNode.cs プロジェクト: oisbel/TigerCompiler
 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;
 }
コード例 #4
0
ファイル: ForNode.cs プロジェクト: oisbel/TigerCompiler
        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--;
        }
コード例 #5
0
ファイル: BreakNode.cs プロジェクト: oisbel/TigerCompiler
        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");
        }
コード例 #6
0
ファイル: Scope.cs プロジェクト: oisbel/TigerCompiler
 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>();
 }
コード例 #7
0
        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);
        }
コード例 #8
0
        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;
        }
コード例 #9
0
ファイル: RecordNode.cs プロジェクト: oisbel/TigerCompiler
        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;
        }
コード例 #10
0
ファイル: TypeAliasNode.cs プロジェクト: oisbel/TigerCompiler
        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");
        }
コード例 #11
0
ファイル: IfThenNode.cs プロジェクト: oisbel/TigerCompiler
        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");
        }
コード例 #12
0
ファイル: TypeArrayNode.cs プロジェクト: oisbel/TigerCompiler
        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");
        }
コード例 #13
0
        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);
        }
コード例 #14
0
ファイル: WhileNode.cs プロジェクト: oisbel/TigerCompiler
        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--;
        }
コード例 #15
0
        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)));
                }
            }
        }
コード例 #16
0
        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;
            }
        }
コード例 #17
0
        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");
        }
コード例 #18
0
ファイル: ElemArrayNode.cs プロジェクト: oisbel/TigerCompiler
        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;
        }
コード例 #19
0
 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);
         }
     }
 }
コード例 #20
0
        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;
        }
コード例 #21
0
ファイル: ExprSeqNode.cs プロジェクト: oisbel/TigerCompiler
 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);
 }
コード例 #22
0
        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;
            }
        }
コード例 #23
0
ファイル: ArrayNode.cs プロジェクト: oisbel/TigerCompiler
        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;
        }
コード例 #24
0
ファイル: IntNode.cs プロジェクト: oisbel/TigerCompiler
 public override void CheckSemantic(Scope scope, List<Error> errors)
 {
     ReturnType = new TypeInfo("int",null,TypeDecl.Base);
 }
コード例 #25
0
ファイル: TigerNode.cs プロジェクト: oisbel/TigerCompiler
 public abstract void CheckSemantic(Scope scope,List<Error> errors);
コード例 #26
0
ファイル: EqualNode.cs プロジェクト: oisbel/TigerCompiler
 public override void CheckSemantic(Scope scope, List<Error> errors)
 {
     base.CheckSemantic(scope, errors, "=");
 }
コード例 #27
0
ファイル: LetNode.cs プロジェクト: oisbel/TigerCompiler
        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);
        }
コード例 #28
0
ファイル: LetNode.cs プロジェクト: oisbel/TigerCompiler
 //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);
 }
コード例 #29
0
ファイル: LetNode.cs プロジェクト: oisbel/TigerCompiler
 //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);
 }
コード例 #30
0
ファイル: EqualityNode.cs プロジェクト: oisbel/TigerCompiler
        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;
            }
        }