public override SemanticCheckResult VisitMethod(ASTMethodNode Method)
        {
            var result = Method.SemanticCheckResult;

            result.Ensure(!Types.IsSelf(Method.Name),
                          new Lazy <Error>(() => new Error($"Not allowed to use {Method.Name}.", ErrorKind.SemanticError, Method.Method.Line, Method.Method.Column)));
            var type = CompilationUnit.TypeEnvironment.GetContextType(Method.SymbolTable);
            var def  = CompilationUnit.MethodEnvironment.GetMethodOnIt(type, Method.Name, out var _);

            result.Ensure(!def,
                          new Lazy <Error>(() => new Error($"Multiple declaration of method {Method.Name}  on type {CompilationUnit.TypeEnvironment.GetContextType(Method.SymbolTable)}.", ErrorKind.MethodError)));
            if (!def)
            {
                var defAncestor = CompilationUnit.MethodEnvironment.GetMethodIfDef(type, Method.Name, out var m2);
                if (defAncestor && Method.Name != Functions.Init)
                {
                    var samesignature = Method.Name == m2.Name && Method.ReturnType == m2.ReturnType.Name && m2.EnsureParametersCount(Method.Formals.Count);
                    if (samesignature)
                    {
                        for (int i = 0; i < Method.Formals.Count; i++)
                        {
                            samesignature &= Method.Formals[i].type.Text == m2.GetParam(i).Name;
                        }
                    }
                    result.Ensure(samesignature,
                                  new Lazy <Error>(() => new Error($@"Method {Method.Name} on type {type.Name} has diferent signature that a method 
                                    with the same name defined on an ancestor of {type.Name}.To override methods must have the same signature.",
                                                                   ErrorKind.MethodError, Method.Method.Line, Method.Method.Column)));
                }

                var             defformals  = true;
                List <CoolType> formalTypes = new List <CoolType>();
                foreach (var item in Method.Formals)
                {
                    var defformal = CompilationUnit.TypeEnvironment.GetTypeDefinition(item.type.Text, Method.SymbolTable, out var ftype);
                    Method.SemanticCheckResult.Ensure(defformal,
                                                      new Lazy <Error>(() => new Error($"Mising declaration for type {item.type}.", ErrorKind.TypeError, item.type.Line, item.type.Column)));
                    Method.SemanticCheckResult.Ensure(!Types.IsSelfType(item.type.Text),
                                                      new Lazy <Error>(() => new Error($"Not Allowed {item.type.Text}", ErrorKind.SemanticError, item.type.Line, item.type.Column)));
                    Method.SemanticCheckResult.Ensure(!Types.IsSelf(Method.Name),
                                                      new Lazy <Error>(() => new Error($"Not allowed to use {Method.Name}.", ErrorKind.SemanticError, Method.Method.Line, Method.Method.Column)));
                    defformals &= defformal;
                    formalTypes.Add(ftype);
                }
                var defreturn = CompilationUnit.TypeEnvironment.GetTypeDefinition(Method.ReturnType, Method.SymbolTable, out var ret);
                result.Ensure(defreturn, new Lazy <Error>(() => new Error($"Missing declaration for type {Method.ReturnType}.", ErrorKind.TypeError, Method.Return.Line, Method.Return.Column)));
                if (defreturn && defformals)
                {
                    CompilationUnit.MethodEnvironment.AddMethod(type, Method.Name, formalTypes, ret, Method.SymbolTable);
                    var definedMethod = CompilationUnit.MethodEnvironment.GetMethod(type, Method.Name);
                    definedMethod.AssignParametersAndLocals();
                }
            }

            return(result);
        }
コード例 #2
0
        public ASTCILNode VisitMethod(ASTMethodNode Method)
        {
            var type = compilationUnit.TypeEnvironment.GetContextType(Method.SymbolTable);

            compilationUnit.MethodEnvironment.GetMethodOnIt(type, Method.Name, out var coolMethod);

            bool boxing = coolMethod.ReturnType == compilationUnit.TypeEnvironment.Object && (Method.Body.SemanticCheckResult.Type == compilationUnit.TypeEnvironment.Int || Method.Body.SemanticCheckResult.Type == compilationUnit.TypeEnvironment.Int);

            return(new ASTCILFuncNode(labelIlGenerator.GenerateFunc(coolMethod.Type.Name, coolMethod.Name), coolMethod,
                                      new[] { (ASTCILExpressionNode)Method.Body.Accept(this) }, boxing, Method.Body.SemanticCheckResult.Type));
        }
コード例 #3
0
        public override SemanticCheckResult VisitMethod(ASTMethodNode Method)
        {
            var exprResult = Method.Body.Accept(this);
            var isDefRet   = CompilationUnit.TypeEnvironment.GetTypeDefinition(Method.ReturnType, Method.SymbolTable, out var ret);

            Method.SemanticCheckResult.Ensure(isDefRet,
                                              new Lazy <Error>(() => new Error($"Missing Declaration for type {Method.ReturnType}.", ErrorKind.TypeError, Method.Return.Line, Method.Return.Column)));
            Method.SemanticCheckResult.EnsureReturnType(ret);
            if (isDefRet)
            {
                Method.SemanticCheckResult.Ensure(exprResult, exprResult.Type.IsIt(ret),
                                                  new Lazy <Error>(() => new Error($"Type {exprResult.Type} does not inherit from type {ret}.", ErrorKind.TypeError, Method.Return.Line, Method.Return.Column)));
                Method.SemanticCheckResult.EnsureReturnType(ret);
            }

            return(Method.SemanticCheckResult);
        }
 public virtual T VisitMethod(ASTMethodNode Method)
 {
     Method.Body.Accept(this);
     return(default(T));
 }