Пример #1
0
 public AssignExpressionAST(LHSExpressionAST leftExp, ExpressionAst rightExp, int line, int col)
     : base(line, col)
 {
     LeftExpression  = leftExp;
     RightExpression = rightExp;
     ReturnType      = TigerType.GetType <NoType>();
 }
Пример #2
0
        public override bool VisitArrayDeclaration(ArrayDeclarationAST arrayDeclaration)
        {
            arrayDeclaration.CurrentScope = _scope;

            //la clase base chequea q el id sea valido
            if (VisitTypeDeclaration(arrayDeclaration))
            {
                TigerType tt;
                if (_scope.HasType(arrayDeclaration.BaseTypeID, out tt) != ScopeLocation.NotDeclared)
                {
                    var at = new ArrayType(tt, arrayDeclaration.TypeId);
                    _scope.AddType(arrayDeclaration.TypeId, at);
                    return(true);
                }
                int savedErrorPos = _errorListener.Count;
                _scope.TypeAdded += (sender, args) =>
                {
                    if (args.TypeName == arrayDeclaration.BaseTypeID)
                    {
                        _scope.AddType(arrayDeclaration.TypeId, new ArrayType(args.NewType, arrayDeclaration.TypeId));
                    }
                };
                _scope.FinalizeScope += (sender, args) =>
                {
                    if (sender.HasType(arrayDeclaration.BaseTypeID) == ScopeLocation.NotDeclared)
                    {
                        _errorListener.Insert(savedErrorPos, AnalysisError.TypeIsNotDefined(arrayDeclaration, arrayDeclaration.BaseTypeID));
                        arrayDeclaration.ReturnType = TigerType.GetType <ErrorType>();
                    }
                };
                return(true);
            }
            return(false);
        }
Пример #3
0
        private bool CheckFunctionParams(FunctionDeclarationAST fDecl)
        {
            int posParam = 0;

            //get from the scope the function signature.
            if (_scope.HasFunction(fDecl.FunctionId) == ScopeLocation.NotDeclared)
            {
                _errorListener.Add(AnalysisError.FunctionNotDeclared(fDecl));
                return(false);
            }
            var funInfo = _scope.GetFunction(fDecl.FunctionId);

            foreach (var parameter in funInfo.ParameterList)
            {
                //existen dos parametros con el mismo nombre.
                if (_scope.HasVar(parameter.Key) == ScopeLocation.DeclaredLocal)
                {
                    _errorListener.Add(AnalysisError.FunctionParameterAlreadyExists(fDecl, parameter.Key));
                    fDecl.ReturnType = TigerType.GetType <ErrorType>();
                    return(false);
                }
                //existe una variable con el mismo nombre que este parametro en un ambito mas externo
                if (_scope.HasVar(parameter.Key) != ScopeLocation.NotDeclared)
                {
                    _errorListener.Add(AnalysisError.VariableHidesAnotherOne(fDecl));
                }
                //se anade este valor al scope de la funcion
                var parameterTypeId = fDecl.ParameterList.First(x => x.Key == parameter.Key).Value;
                _scope.AddVarParameter(parameter.Key, parameterTypeId, posParam, fDecl.FunctionId);
                posParam++;
            }
            return(true);
        }
Пример #4
0
        public override bool VisitArrayAccess(ArrayAccessAST arrayAccess)
        {
            //esto es para quedarme con el scope actual
            arrayAccess.CurrentScope = _scope;


            arrayAccess.ReturnType = TigerType.GetType <ErrorType>();
            //visit the expression represeting the array
            arrayAccess.Array.Accept(this);
            //verifico que la expresion 'array' sea de tipo ArrayType
            var arrayType = arrayAccess.Array.ReturnType as ArrayType;

            if (arrayType != null)
            {
                arrayAccess.Indexer.Accept(this);
                //verifico que la expresion que indexada sea del tipo IntType
                var intType = arrayAccess.Indexer.ReturnType as IntType;
                if (intType != null)
                {
                    arrayAccess.ReturnType = arrayType.BaseType;
                    return(arrayAccess.AlwaysReturn = true);
                }
                _errorListener.Add(new AnalysisError(AnalysisError.LoadMessage("ArrayIndex"), arrayAccess.Line, arrayAccess.Columns));
                return(false);
            }
            _errorListener.Add(new AnalysisError(AnalysisError.LoadMessage("Index"), arrayAccess.Line, arrayAccess.Columns));
            return(false);
        }
Пример #5
0
        public override bool VisitSequence(SequenceExpressionAST sequenceExpression)
        {
            //Se asume q no se retorna nada
            sequenceExpression.ReturnType = TigerType.GetType <NoType>();

            foreach (var exp in sequenceExpression.ExpressionList)
            {
                if (!exp.Accept(this))
                {
                    //hubo error
                    sequenceExpression.ReturnType = TigerType.GetType <ErrorType>();
                }
            }

            ExpressionAst last = sequenceExpression.ExpressionList.LastOrDefault();

            if (last != null)
            {
                //si existe una ultima expresion, esta define el retorno del let
                sequenceExpression.AlwaysReturn = last.AlwaysReturn;
                sequenceExpression.ReturnType   = last.ReturnType;
            }
            //true si no hubo ningun error
            return(sequenceExpression.ReturnType != TigerType.GetType <ErrorType>());
        }
Пример #6
0
        public override bool VisitRecordDeclaration(RecordDeclarationAST recordDeclaration)
        {
            recordDeclaration.CurrentScope = _scope;

            //se asuma que no habra problemas
            recordDeclaration.ReturnType = TigerType.GetType <NoType>();
            //la clase base verifica el ID del type
            if (VisitTypeDeclaration(recordDeclaration))
            {
                var rt = new RecordType(recordDeclaration.TypeId);
                //se anade el record creado al scope para q puedan haber records recursivos en su def
                _scope.AddType(recordDeclaration.TypeId, rt);
                //se verifica cada una de las declaraciones de los campos del record
                int savedErrorPos = _errorListener.Count;
                foreach (var kvp in recordDeclaration.Fields)
                {
                    if (!rt.Contains(kvp.Key))
                    {
                        TigerType tt;
                        if (_scope.HasType(kvp.Value, out tt) == ScopeLocation.NotDeclared)
                        {
                            KeyValuePair <string, string> savedKvp = kvp;
                            _scope.TypeAdded += (sender, args) =>
                            {
                                if (args.TypeName == savedKvp.Value)
                                {
                                    rt.AddField(savedKvp.Key, args.NewType);
                                }
                            };
                            _scope.FinalizeScope += (sender, args) =>
                            {
                                if (sender.HasType(savedKvp.Value) ==
                                    ScopeLocation.NotDeclared)
                                {
                                    _errorListener.Insert(savedErrorPos,
                                                          new AnalysisError(
                                                              string.Format(
                                                                  AnalysisError.LoadMessage("TypeUndecl"),
                                                                  savedKvp.Value), recordDeclaration.Line, recordDeclaration.Columns));
                                    recordDeclaration.ReturnType = TigerType.GetType <ErrorType>();
                                }
                            };
                        }
                        else
                        {
                            rt.AddField(kvp.Key, tt);
                        }
                    }
                    else
                    {
                        _errorListener.Add(new AnalysisError(string.Format(AnalysisError.LoadMessage("RecDecl"), kvp.Key, recordDeclaration.TypeId),
                                                             recordDeclaration.Line, recordDeclaration.Columns));
                    }
                }
                //TODO aqui se ve el prob con los ret Types y los return true pq no se puede decir nada en este momento
                return(true);
            }
            return(false);
        }
Пример #7
0
        /// <summary>
        /// This method verifies that the function signature is correct. That is that the return type and parameter types are already
        /// defined. It also verifies that the function does not exist in the scope.
        /// </summary>
        /// <param name="fDecl"></param>
        /// <returns></returns>
        private bool CheckFunctionSignature(FunctionDeclarationAST fDecl)
        {
            TigerType ret = null;

            if (!string.IsNullOrEmpty(fDecl.ReturnTypeId))
            {
                //si se especifica retorno pero este no es un tipo ya definido ERROR
                //esto lo garantiza haber organizado las declaraciones
                if (_scope.HasType(fDecl.ReturnTypeId, out ret) == ScopeLocation.NotDeclared)
                {
                    _errorListener.Add(AnalysisError.TypeIsNotDefined(fDecl, fDecl.ReturnTypeId));
                    fDecl.ReturnType = TigerType.GetType <ErrorType>();
                    return(false);
                }
                if (!ret.IsLegalType)
                {
                    //TODO: Hasta que punto interesa lanzar este error??
                    _errorListener.Add(new AnalysisError(
                                           string.Format(AnalysisError.LoadMessage("InavalidRet"), fDecl.ReturnTypeId), fDecl.Line,
                                           fDecl.Columns));
                    fDecl.ReturnType = TigerType.GetType <ErrorType>();
                    return(false);
                }
            }

            //ver que la funcion no este previamente declarada
            if (_scope.HasFunction(fDecl.FunctionId) == ScopeLocation.NotDeclared)
            {
                var paramsInfo = new List <KeyValuePair <string, TigerType> >();
                foreach (var nameType in fDecl.ParameterList)
                {
                    TigerType t;
                    //verificar si existe el tipo del parametro.
                    if (_scope.HasType(nameType.Value, out t) == ScopeLocation.NotDeclared)
                    {
                        _errorListener.Add(new AnalysisError(
                                               $"Type {nameType.Value} in parameter {fDecl.FunctionId} is not defined", fDecl.Line, fDecl.Columns));
                        fDecl.ReturnType = TigerType.GetType <ErrorType>();
                        return(false);
                    }
                    paramsInfo.Add(new KeyValuePair <string, TigerType>(nameType.Key, t));
                }
                var funInfo = new FunctionInfo(paramsInfo, ret ?? TigerType.GetType <NoType>())
                {
                    FunctionName   = fDecl.FunctionId,
                    FunctionParent = _scope.CurrentFunction
                };
                //se anade en el padre para q este disponible en el scope donde se declara
                _scope.AddFunction(fDecl.FunctionId, funInfo);
                return(true);
            }

            //ya habia una funcion con ese nombre
            _errorListener.Add(new AnalysisError(string.Format(AnalysisError.LoadMessage("FuncDecl"), fDecl.FunctionId), fDecl.Line,
                                                 fDecl.Columns));
            return(false);
        }
Пример #8
0
 public void InitScope(Scope scope)
 {
     //predifined types
     scope.AddType("int", TigerType.GetType <IntType>());
     scope.AddType("string", TigerType.GetType <StringType>());
     //We add ErrorType to scope, because when a variable is not defined
     //we say that it has ErrorType, so ErrorType must be in the
     //Scope.
     scope.AddType(TigerType.GetType <ErrorType>().TypeID, TigerType.GetType <StringType>());
 }
Пример #9
0
        public override bool VisitFunctionDeclaration(FunctionDeclarationAST functionDeclaration)
        {
            //chequear la semantica del cuerpo de la funcion, la signatura ya fue chequeada en el let correspondiente
            //here we create a new scope for this function and its parameters
            PushScope(new Scope(_scope));

            //verificar que todos los tipos de los parametros existan y si ya existe el nombre de los parametros
            //en el scope

            if (!CheckFunctionParams(functionDeclaration))
            {
                PopScope();
                return(false);
            }

            functionDeclaration.CurrentScope = _scope;
            TigerType retType = functionDeclaration.ReturnTypeId != null?
                                functionDeclaration.CurrentScope.GetType(functionDeclaration.ReturnTypeId) : TigerType.GetType <NoType>();


            //poner esta funcion como la funcion actual de scope donde se encuentra.
            FunctionInfo temp = _scope.CurrentFunction;

            _scope.CurrentFunction = _scope.GetFunction(functionDeclaration.FunctionId);

            functionDeclaration.ExprInstructions.Accept(this);

            _scope.CurrentFunction = temp;

            if (!functionDeclaration.ExprInstructions.AlwaysReturn && retType != TigerType.GetType <NoType>())
            {
                _errorListener.Add(new AnalysisError(string.Format(AnalysisError.LoadMessage("FuncDeclRet"), functionDeclaration.FunctionId),
                                                     functionDeclaration.Line, functionDeclaration.Columns));
            }
            else if (string.IsNullOrEmpty(functionDeclaration.ReturnTypeId) ||
                     functionDeclaration.ExprInstructions.ReturnType.CanConvertTo(
                         _scope.GetType(functionDeclaration.ReturnTypeId)))
            {
                PopScope();
                return(true);
            }
            else
            {
                _errorListener.Add(
                    new AnalysisError(
                        string.Format(AnalysisError.LoadMessage("Match"), functionDeclaration.ReturnTypeId,
                                      functionDeclaration.ExprInstructions.ReturnType), functionDeclaration.Line,
                        functionDeclaration.Columns));
            }
            functionDeclaration.ReturnType = TigerType.GetType <ErrorType>();

            PopScope();
            return(false);
        }
Пример #10
0
 private bool VisitTypeDeclaration(TypeDeclarationAST typeDeclaration)
 {
     if (_scope.HasType(typeDeclaration.TypeId, out _) != ScopeLocation.NotDeclared)
     {
         _errorListener.Add(new AnalysisError(string.Format(AnalysisError.LoadMessage("TypeDecl"), typeDeclaration.TypeId), typeDeclaration.Line, typeDeclaration.Columns));
         typeDeclaration.ReturnType = TigerType.GetType <ErrorType>();
         return(false);
     }
     typeDeclaration.ReturnType = TigerType.GetType <NoType>();
     return(true);
 }
Пример #11
0
 private FunctionDeclarationAST(string id, FormalParameterList parameterList,
                                ExpressionAst exprInstructions)
 {
     FunctionId          = id;
     FormalParameterList = parameterList;
     ParameterList       = (parameterList ?? new FormalParameterList())
                           .Parameters
                           .Select(x => new KeyValuePair <string, string>(x.Name, x.TypeIdentifier)).ToList();
     ExprInstructions = exprInstructions;
     ReturnType       = TigerType.GetType <NoType>();
 }
Пример #12
0
        public static void AddCharFunctionToScope(Inizializator <ILCode> init)
        {
            FunctionInfo funInfo;

            funInfo = new FunctionInfo(new List <KeyValuePair <string, TigerType> >(), TigerType.GetType <StringType>());
            funInfo.ParameterList.Add(GetKeyValue("i", TigerType.GetType <IntType>()));
            funInfo.FunctionName = "chr";
            funInfo.IsPredifined = true;
            var chr = new FunctionPredifined <ILCode>(funInfo, CharFunction);

            init.AddPredifinedFunction(chr);
        }
Пример #13
0
        public static void AddPrintIntFunctionToScope(Inizializator <ILCode> init)
        {
            FunctionInfo funInfo;

            funInfo = new FunctionInfo(new List <KeyValuePair <string, TigerType> >(), TigerType.GetType <NoType>());
            funInfo.ParameterList.Add(new KeyValuePair <string, TigerType>("i", TigerType.GetType <IntType>()));
            funInfo.FunctionName = "printi";
            funInfo.IsPredifined = true;

            var printi = new FunctionPredifined <ILCode>(funInfo, PrintIntFunction);

            init.AddPredifinedFunction(printi);
        }
Пример #14
0
        public override bool VisitBreakStatement(BreakAST breakStm)
        {
            breakStm.CurrentScope = _scope;

            if (!_scope.IsInLoop)
            {
                _errorListener.Add(new AnalysisError(AnalysisError.LoadMessage("Break"), breakStm.Line, breakStm.Columns));
                breakStm.ReturnType = TigerType.GetType <ErrorType>();
                return(false);
            }
            breakStm.BreakeableLoop = _scope.ContainerLoop;
            breakStm.ReturnType     = TigerType.GetType <NoType>();
            return(true);
        }
Пример #15
0
 public override bool VisitNegExpression(NegExpressionAST negExpression)
 {
     negExpression.CurrentScope = _scope;
     if (negExpression.Expression.Accept(this))
     {
         if (negExpression.Expression.ReturnType == TigerType.GetType <IntType>())
         {
             negExpression.ReturnType = TigerType.GetType <IntType>();
             return(true);
         }
         _errorListener.Add(new AnalysisError(string.Format(AnalysisError.LoadMessage("NegExp"), negExpression.Expression.ReturnType), negExpression.Line,
                                              negExpression.Columns));
     }
     negExpression.ReturnType = TigerType.GetType <ErrorType>();
     return(false);
 }
Пример #16
0
        public void BasicArrayAccess()
        {
            var arrayDecl     = ArrayDecl("intArray", "int");
            var arrayInstDecl = VarDecl("a", ArrayInst("intArray", Num(1), Num(5)));

            var let = Let(
                Decls(arrayDecl, arrayInstDecl),
                Seq(ArrayAccess(Var("a"), Num(0)))
                );

            var errorCollector = new PrinterErrorListener();
            var staticChecker  = new StaticChecker(errorCollector, InitialScope());

            Assert.IsTrue(let.Accept(staticChecker));
            Assert.IsTrue(errorCollector.Count == 0);
            Assert.IsTrue(let.ReturnType == TigerType.GetType <IntType>());
        }
Пример #17
0
        public override bool VisitFunctionInvocation(CallFunctionAST functionInvocation)
        {
            //probablemente se cambie
            functionInvocation.CurrentScope = _scope;

            bool ok = true;

            FunctionInfo functionInfo;
            string       message;

            //verificar que la funcion existe.
            if (_scope.HasFunction(functionInvocation.FunctionId, out functionInfo) != ScopeLocation.NotDeclared)
            {
                //coger su tipo de retorno
                if (functionInfo.ParameterList.Count == functionInvocation.RealParam.Count)
                {
                    for (int i = 0; i < functionInfo.ParameterList.Count; i++)
                    {
                        //no es necesario chequear q el chequeo de los parametros sea true o no
                        functionInvocation.RealParam[i].Accept(this);
                        ok = ok && (functionInvocation.RealParam[i].ReturnType.CanConvertTo(functionInfo.ParameterList[i].Value));
                    }
                    if (ok)
                    {
                        functionInvocation.AlwaysReturn = !(functionInfo.FunctionReturnType is NoType);
                        functionInvocation.ReturnType   = functionInfo.FunctionReturnType;
                        return(true);
                    }
                    message = string.Format(AnalysisError.LoadMessage("FuncParams"), functionInvocation.FunctionId);
                }
                else
                {
                    message = string.Format(AnalysisError.LoadMessage("FuncParamsCount"), functionInvocation.FunctionId, functionInvocation.RealParam.Count);
                }
            }
            else
            {
                message = string.Format(AnalysisError.LoadMessage("FuncUndecl"), functionInvocation.FunctionId);
            }
            _errorListener.Add(new AnalysisError(message, functionInvocation.Line, functionInvocation.Columns));
            functionInvocation.ReturnType = TigerType.GetType <ErrorType>();
            return(false);
        }
Пример #18
0
        public override bool VisitRecordInstantiation(RecordInstantiationAST recordInstantiation)
        {
            recordInstantiation.CurrentScope = _scope;

            TigerType  tt;
            RecordType rt;

            //verificando que exista el tipo,
            if (_scope.HasType(recordInstantiation.Id, out tt) != ScopeLocation.NotDeclared && (rt = tt as RecordType) != null)
            {
                recordInstantiation.ReturnType = rt;
                if (recordInstantiation.ExpressionValue == null)
                {
                    return(true);
                }

                foreach (var kvp in recordInstantiation.ExpressionValue)
                {
                    kvp.Value.Accept(this);
                    if (rt.Contains(kvp.Key))
                    {
                        if (kvp.Value.ReturnType.CanConvertTo(rt[kvp.Key]))
                        {
                            continue;
                        }
                        _errorListener.Add(
                            new AnalysisError(
                                string.Format(AnalysisError.LoadMessage("Match"), kvp.Value.ReturnType, rt[kvp.Key].TypeID),
                                recordInstantiation.Line, recordInstantiation.Columns));
                    }
                    else
                    {
                        _errorListener.Add(new AnalysisError(string.Format(AnalysisError.LoadMessage("RecField"), recordInstantiation.Id, kvp.Key), recordInstantiation.Line,
                                                             recordInstantiation.Columns));
                    }
                    recordInstantiation.ReturnType = TigerType.GetType <ErrorType>();
                }
                return(recordInstantiation.ReturnType != TigerType.GetType <ErrorType>());
            }
            recordInstantiation.ReturnType = TigerType.GetType <ErrorType>();
            _errorListener.Add(AnalysisError.TypeIsNotDefined(recordInstantiation, recordInstantiation.Id));
            return(false);
        }
Пример #19
0
        public override bool VisitBinaryExpression(BinaryExpressionAst expr)
        {
            expr.LeftExp.Accept(this);
            TigerType leftType = expr.LeftExp.ReturnType;

            expr.RightExp.Accept(this);
            TigerType rightType = expr.RightExp.ReturnType;

            if (CheckOperator(leftType, rightType, expr.Operator, out var tt))
            {
                expr.ReturnType = tt;
                return(true);
            }
            _errorListener.Add(
                new AnalysisError(string.Format(AnalysisError.LoadMessage("SupportOp"), expr.Operator, leftType, rightType), expr.Line,
                                  expr.Columns));
            expr.ReturnType = TigerType.GetType <ErrorType>();
            return(false);
        }
Пример #20
0
        public override bool VisitForExpression(ForExpressionAST forExpression)
        {
            forExpression.ExpressionFrom.Accept(this);
            forExpression.ReturnType = TigerType.GetType <ErrorType>();
            //si la expresion "from" no es de tipo entero.
            if (forExpression.ExpressionFrom.ReturnType != TigerType.GetType <IntType>())
            {
                _errorListener.Add(new AnalysisError(string.Format(AnalysisError.LoadMessage("ForInit"), forExpression.VarId), forExpression.Line,
                                                     forExpression.Columns));
            }
            else
            {
                forExpression.ExpressionTo.Accept(this);
                // si la expresion "to" no es tipo entero.
                if (forExpression.ExpressionTo.ReturnType != TigerType.GetType <IntType>())
                {
                    _errorListener.Add(new AnalysisError(string.Format(AnalysisError.LoadMessage("ForStop"), forExpression.VarId),
                                                         forExpression.Line, forExpression.Columns));
                }
                else
                {
                    var sc = new Scope(_scope, forExpression);
                    forExpression.CurrentScope = sc;
                    if (_scope.HasVar(forExpression.VarId) != ScopeLocation.NotDeclared)
                    {
                        _errorListener.Add(new AnalysisError(string.Format(AnalysisError.LoadMessage("VarDecl"), forExpression.VarId),
                                                             forExpression.Line, forExpression.Columns));
                        forExpression.ReturnType = TigerType.GetType <ErrorType>();
                        return(false);
                    }
                    //annado la variable al scope
                    sc.AddVarFor(forExpression.VarId, TigerType.Int);

                    if (forExpression.BodyExpressions.Accept(this))
                    {
                        forExpression.ReturnType = forExpression.BodyExpressions.ReturnType;
                        return(true);
                    }
                }
            }
            return(false);
        }
Пример #21
0
        public override bool VisitAssignExpression(AssignExpressionAST assignExpression)
        {
            assignExpression.CurrentScope = _scope;

            assignExpression.ReturnType = TigerType.GetType <ErrorType>();
            if (!assignExpression.LeftExpression.Accept(this) || !assignExpression.RightExpression.Accept(this))
            {
                return(false);
            }
            if (assignExpression.RightExpression.ReturnType.CanConvertTo(assignExpression.LeftExpression.ReturnType))
            {
                assignExpression.ReturnType = TigerType.GetType <NoType>();
                return(true);
            }
            _errorListener.Add(
                new AnalysisError(
                    string.Format(AnalysisError.LoadMessage("Match"), assignExpression.LeftExpression.ReturnType, assignExpression.RightExpression.ReturnType),
                    assignExpression.Line, assignExpression.Columns));
            return(false);
        }
Пример #22
0
        public override bool VisitArrayInstantiation(ArrayInstatiationAST arrayInstatiation)
        {
            arrayInstatiation.CurrentScope = _scope;

            arrayInstatiation.ReturnType = TigerType.GetType <ErrorType>();
            TigerType t;

            if (_scope.HasType(arrayInstatiation.ArrayTypeIdentifier, out t) != ScopeLocation.NotDeclared)
            //Chequeo si este tipo de array fue declarado
            {
                var typeArray = t as ArrayType;
                if (typeArray != null)
                {
                    arrayInstatiation.SizeExp.Accept(this);
                    if (arrayInstatiation.SizeExp.ReturnType != TigerType.GetType <IntType>())
                    {
                        //Chequeo que el length del array sea un entero
                        _errorListener.Add(new AnalysisError(AnalysisError.LoadMessage("ArrayIndex"), arrayInstatiation.Line, arrayInstatiation.Columns));
                    }
                    else
                    {
                        arrayInstatiation.InitializationExp.Accept(this);
                        if (!arrayInstatiation.InitializationExp.ReturnType.CanConvertTo(typeArray.BaseType))
                        {
                            _errorListener.Add(
                                new AnalysisError(
                                    string.Format(AnalysisError.LoadMessage("Match"), arrayInstatiation.InitializationExp.ReturnType,
                                                  typeArray.BaseType), arrayInstatiation.Line, arrayInstatiation.Columns));
                        }
                        else
                        {
                            arrayInstatiation.ReturnType = typeArray;
                            return(arrayInstatiation.AlwaysReturn = true);
                        }
                    }
                    return(false);
                }
            }
            _errorListener.Add(AnalysisError.TypeIsNotDefined(arrayInstatiation, arrayInstatiation.ArrayTypeIdentifier));
            return(false);
        }
Пример #23
0
        public override bool VisitAlias(TypeAliasAST alias)
        {
            //se asume que no habra problema
            alias.ReturnType = TigerType.GetType <NoType>();
            //la clase base verifica q el id del type sea valido
            //aqui si se ve q el return true hace falta
            if (VisitTypeDeclaration(alias))
            {
                TigerType tt;
                //se verifica que exista el tipo del cual se esta creando un alias
                if (_scope.HasType(alias.AliasToWho, out tt) != ScopeLocation.NotDeclared)
                {
                    //se anade una nueva entrada del mismo type, lo q con otro id
                    _scope.AddAlias(alias.TypeId, alias.AliasToWho);
                    return(true);
                }
                int savedErrorPos = _errorListener.Count;
                //manejador de evento
                _scope.TypeAdded += (sender, args) =>
                {
                    if (args.TypeName == alias.AliasToWho)
                    {
                        _scope.AddType(alias.TypeId, args.NewType);
                    }
                };

                //manejador de evento
                _scope.FinalizeScope += (sender, args) =>
                {
                    if (sender.HasType(alias.AliasToWho) == ScopeLocation.NotDeclared)
                    {
                        _errorListener.Insert(savedErrorPos, AnalysisError.TypeIsNotDefined(alias, alias.AliasToWho));
                        alias.ReturnType = TigerType.GetType <ErrorType>();
                    }
                };
                return(true);
            }
            return(false);
        }
Пример #24
0
        public override bool VisitVar(VarAST ast)
        {
            //es posible que se quite
            ast.CurrentScope = _scope;

            //comprobar que la variable esta definida
            if (_scope.HasVar(ast.VarId, out var tt) != ScopeLocation.NotDeclared)
            {
                //dar el valor correspondiente al tipo de esa expresion
                ast.ReturnType = tt;

                if (IsVarFromDifferentFunction(ast))
                {
                    SetVarAsUsedForAnotherFunction(ast);
                }

                return(true);
            }
            //error en caso q la variable no este definida
            _errorListener.Add(AnalysisError.VariableIsNotDefined(ast, ast.VarId));
            ast.ReturnType = TigerType.GetType <ErrorType>();
            return(false);
        }
Пример #25
0
        /// <summary>
        /// Annade los tipos predefinidos
        /// </summary>
        /// <param name="init"></param>
        private static void AddTypes(Inizializator <ILCode> init)
        {
            //anadir los tipos
            //--> int
            var typeTemp = new PrefinedType <ILCode>(TigerType.GetType <IntType>(),
                                                     (name, code) =>
                                                     code.DefinedType.Add(name, typeof(int)));

            init.AddPredifinedTypes(typeTemp);
            //<-- end int
            //--> string
            typeTemp = new PrefinedType <ILCode>(TigerType.GetType <StringType>(),
                                                 (name, code) => code.DefinedType.Add(name, typeof(string)));

            init.AddPredifinedTypes(typeTemp);
            //<-- end string

            //--> errorType
            typeTemp = new PrefinedType <ILCode>(TigerType.GetType <ErrorType>(),
                                                 (name, code) => { });
            init.AddPredifinedTypes(typeTemp);
            //<-- end errorType
        }
Пример #26
0
 public override bool VisitWhileExpression(WhileExpressionAST whileExpression)
 {
     whileExpression.ExpressionConditional.Accept(this);
     whileExpression.ReturnType = TigerType.GetType <ErrorType>();
     if (whileExpression.ExpressionConditional.ReturnType != TigerType.GetType <IntType>())
     {
         _errorListener.Add(new AnalysisError(AnalysisError.LoadMessage("IfCond"), whileExpression.Line, whileExpression.Columns));
     }
     else
     {
         //guardo, si hay, el ciclo previo
         LoopAST prevLoop = _scope.ContainerLoop;
         _scope.ContainerLoop = whileExpression;
         if (whileExpression.BodyExpressions.Accept(this))
         {
             //repongo el ciclo q habia
             _scope.ContainerLoop       = prevLoop;
             whileExpression.ReturnType = TigerType.GetType <NoType>();
             return(true);
         }
     }
     return(false);
 }
Пример #27
0
        public override bool VisitIfExpression(IfExpressionAST ifExpr)
        {
            ifExpr.ExpConditional.Accept(this);
            ifExpr.ReturnType = TigerType.GetType <ErrorType>();
            if (ifExpr.ExpConditional.ReturnType != TigerType.GetType <IntType>())
            {
                _errorListener.Add(new AnalysisError(AnalysisError.LoadMessage("IfCond"), ifExpr.Line, ifExpr.Columns));
            }
            else if (ifExpr.ExpressionThen.Accept(this))
            {
                if (ifExpr.ExpressionElse != null)
                {
                    ifExpr.ExpressionElse.Accept(this);
                    ifExpr.ReturnType = ifExpr.ExpressionElse.ReturnType.CanConvertTo(ifExpr.ExpressionThen.ReturnType)
                                     ?
                                        ifExpr.ExpressionThen.ReturnType
                                     :
                                        ifExpr.ExpressionThen.ReturnType.CanConvertTo(ifExpr.ExpressionElse.ReturnType)
                                             ?
                                        ifExpr.ExpressionElse.ReturnType
                                             : TigerType.GetType <ErrorType>();
                    if (!(ifExpr.ReturnType is ErrorType))
                    {
                        return(ifExpr.AlwaysReturn = true);
                    }

                    _errorListener.Add(
                        new AnalysisError(
                            string.Format(AnalysisError.LoadMessage("Match"), ifExpr.ExpressionThen.ReturnType,
                                          ifExpr.ExpressionElse.ReturnType), ifExpr.Line, ifExpr.Columns));
                }
                ifExpr.AlwaysReturn = false;
                ifExpr.ReturnType   = TigerType.GetType <NoType>();
                return(true);
            }
            return(false);
        }
Пример #28
0
        public override bool VisitRecordAccess(RecordAccessAST recordAccess)
        {
            recordAccess.CurrentScope = _scope;
            recordAccess.ExpressionRecord.Accept(this);
            TigerType record = recordAccess.ExpressionRecord.ReturnType;

            if (record is RecordType)
            {
                //verificar que el record contiene el campo
                var r = (RecordType)record;
                if (r.Contains(recordAccess.FieldId))
                {
                    recordAccess.ReturnType = r[recordAccess.FieldId];
                    return(recordAccess.AlwaysReturn = true);
                }
                _errorListener.Add(AnalysisError.RecordFieldDoNotExists(recordAccess));
                recordAccess.ReturnType = TigerType.GetType <ErrorType>();
                return(false);
            }
            //la expresion no es un record
            recordAccess.ReturnType = TigerType.GetType <ErrorType>();
            _errorListener.Add(AnalysisError.ExpressionIsNotARecord(recordAccess));
            return(false);
        }
Пример #29
0
 private FunctionInfo(List <KeyValuePair <string, TigerType> > parameterList)
 {
     ParameterList              = parameterList ?? new List <KeyValuePair <string, TigerType> >();
     FunctionReturnType         = TigerType.GetType <NoType>();
     VarsUsedForAnotherFunction = new List <VarInfo>();
 }
Пример #30
0
        public override bool VisitLetExpression(LetExpressionAST letExpr)
        {
            //First, we process the type declaration in the let.
            var typeDeclarations = letExpr.DeclarationList.Where(x => x is TypeDeclarationAST).ToList();

            //el let abre un nuevo scope
            var sc = new Scope(_scope, _scope.ContainerLoop);

            PushScope(sc);
            letExpr.CurrentScope = sc;

            foreach (var typeDeclaration in typeDeclarations)
            {
                typeDeclaration.Accept(this);
            }

            //notify that all types in this scope where proccessed. Then if there was fields with unsolved
            //types, this is the momemnt to catch errors.
            sc.NotifyEndTypeScope();
            var errorAfterClosingScope = _errorListener.Count != 0;

            //Declaration List

            //se asume q no habra problemas
            letExpr.ReturnType = TigerType.GetType <NoType>();

            //Second. We do a first pass over function declarations
            //to verifies function signatures and then add function signature to the scope.

            var functionDeclarations = letExpr.DeclarationList.Where(x => (x is FunctionDeclarationAST)).Cast <FunctionDeclarationAST>();

            foreach (var fDecl in functionDeclarations)
            {
                //se hace el primer chequeo
                CheckFunctionSignature(fDecl);
            }

            //a medida q aparezcan las funciones se incrementa el contador
            var noTypeDeclarations = letExpr.DeclarationList.Where(x => !(x is TypeDeclarationAST));

            foreach (var noTypeDeclaration in noTypeDeclarations)
            {
                FunctionDeclarationAST fDecl;
                //si es una declaracion de funcion
                if ((fDecl = noTypeDeclaration as FunctionDeclarationAST) != null)
                {
                    //segundo chequeo para comprobar el cuerpo
                    if (!fDecl.Accept(this))
                    {
                        letExpr.ReturnType = TigerType.GetType <ErrorType>();
                    }
                }
                else if (!noTypeDeclaration.Accept(this))
                {
                    letExpr.ReturnType = TigerType.GetType <ErrorType>();
                }
            }

            //cierra el scope pq no habran mas declaraciones


            //checks the body of the let
            //verifies that there were no errors (eg. that a type was not found after closing the scope)
            if (letExpr.SequenceExpressionList.Accept(this) && letExpr.ReturnType == TigerType.GetType <NoType>() && !errorAfterClosingScope)
            {
                letExpr.AlwaysReturn = letExpr.SequenceExpressionList.AlwaysReturn;
                letExpr.ReturnType   = letExpr.SequenceExpressionList.ReturnType;
                PopScope();
                return(true);
            }
            PopScope();
            return(false);
        }