예제 #1
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);
        }
예제 #2
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);
        }
예제 #3
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);
        }
예제 #4
0
        public override bool VisitFunctionDeclaration(FunctionDeclarationAST functionDeclaration)
        {
            var other = _other as FunctionDeclarationAST;

            if (other == null)
            {
                return(false);
            }

            return(IsEqualNodes(other.FormalParameterList, functionDeclaration.FormalParameterList) &&
                   other.FunctionId == functionDeclaration.FunctionId &&
                   other.ReturnTypeId == functionDeclaration.ReturnTypeId &&
                   IsEqualNodes(other.ExprInstructions, functionDeclaration.ExprInstructions));
        }
예제 #5
0
        public override Unit VisitFunctionDeclaration(FunctionDeclarationAST functionDeclaration)
        {
            var funDeclGeneratorHelper = new FunctionDeclarationILGeneratorHelper(functionDeclaration);
            //----->
            bool pushOnStack = code.PushOnStack;

            bool isFunction = !string.IsNullOrEmpty(functionDeclaration.ReturnTypeId);

            //ver si tengo que generar una clase que contenga toda la informacion para mis hijas
            MethodBuilder mBuilder;

            //construir la funcion en il con su clase wrapper a las funciones que ella usa
            mBuilder = funDeclGeneratorHelper.GenerateInstanceMethodWithClassWrapper(code);

            //-->
            MethodBuilder temp = code.Method;

            code.Method = mBuilder;

            //-------->
            FunctionInfo temp1 = functionDeclaration.CurrentScope.CurrentFunction;

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

            code.PushOnStack = isFunction;
            functionDeclaration.ExprInstructions.Accept(this);
            mBuilder.GetILGenerator().Emit(OpCodes.Ret);

            //<--------
            functionDeclaration.CurrentScope.CurrentFunction = temp1;
            //<--
            code.Method = temp;

            //<----
            code.PushOnStack = pushOnStack;


            //crear el tipo que acabo de crear como nested

            string currentWrapper = string.Format("Tg_{0}", funDeclGeneratorHelper.FunctionCodeName());
            var    wrapper        = (TypeBuilder)code.DefinedType[currentWrapper];

            wrapper.CreateType();


            return(Unit.Create());
        }
 public FunctionDeclarationILGeneratorHelper(FunctionDeclarationAST functionDeclaration)
 {
     _functionDecl = functionDeclaration;
 }
예제 #7
0
 public abstract T VisitFunctionDeclaration(FunctionDeclarationAST functionDeclaration);
예제 #8
0
 public static AnalysisError FunctionParameterAlreadyExists(FunctionDeclarationAST fDecl, string parameter)
 {
     return(new AnalysisError(
                string.Format(LoadMessage("FuncDeclParams"), parameter, fDecl.FunctionId), fDecl.Line,
                fDecl.Columns));
 }
예제 #9
0
 public static AnalysisError FunctionNotDeclared(FunctionDeclarationAST fDecl)
 {
     return(new AnalysisError(
                $"It is expected that the function {fDecl.FunctionId} is at scope at this point", fDecl.Line, fDecl.Columns));
 }