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); }
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)); }
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)); }