public void Visit(LetNode node) { var scopeLet = scope.CreateChild(); foreach (var expInit in node.Initialization) { expInit.AssignExp.Accept(new SecondSemanticVisit(scopeLet, errors)); var typeAssignExp = expInit.AssignExp.StaticType; if (!scopeLet.IsDefinedType(expInit.Formal.Type.Text, out TypeInfo typeDeclared)) { errors.Add(SemanticError.NotDeclaredType(expInit.Formal.Type)); } if (!(typeAssignExp <= typeDeclared)) { errors.Add(SemanticError.CannotConvert(expInit.Formal.Type, typeAssignExp, typeDeclared)); } if (scopeLet.IsDefined(expInit.Formal.Id.Text, out TypeInfo typeOld)) { scopeLet.UpdateType(expInit.Formal.Id.Text, typeDeclared); } else { scopeLet.Define(expInit.Formal.Id.Text, typeDeclared); } } node.ExpressionBody.Accept(new SecondSemanticVisit(scopeLet, errors)); node.StaticType = node.ExpressionBody.StaticType; }
public void Visit(DispatchExplicitNode node) { node.Expression.Accept(this); if (node.IdType.Text == "Object") { node.IdType = new TypeNode(node.Expression.Line, node.Expression.Column, node.Expression.StaticType.Text); } if (!scope.IsDefinedType(node.IdType.Text, out TypeInfo typeSuperClass)) { errors.Add(SemanticError.NotDeclaredType(node.IdType)); } if (!(node.Expression.StaticType <= typeSuperClass)) { errors.Add(SemanticError.CannotConvert(node, node.Expression.StaticType, typeSuperClass)); } node.Arguments.ForEach(x => x.Accept(this)); var scopeSuperClass = typeSuperClass.ClassReference.Scope; if (!(scopeSuperClass.IsDefined(node.IdMethod.Text, node.Arguments.Select(x => x.StaticType).ToArray(), out node.StaticType))) { errors.Add(SemanticError.NotDeclareFunction(node, node.IdMethod.Text)); } }
public void Visit(MethodNode node) { var scopeMethod = scope.CreateChild(); foreach (var arg in node.Arguments) { if (!scope.IsDefinedType(arg.Type.Text, out TypeInfo typeArg)) { errors.Add(SemanticError.NotDeclaredType(arg.Type)); } scopeMethod.Define(arg.Id.Text, typeArg); } if (!scope.IsDefinedType(node.TypeReturn.Text, out TypeInfo typeReturn)) { errors.Add(SemanticError.NotDeclaredType(node.TypeReturn)); } scope.Define(node.Id.Text, node.Arguments.Select(x => scope.GetType(x.Type.Text)).ToArray(), typeReturn); node.Body.Accept(new SecondSemanticVisit(scopeMethod, errors)); if (!(node.Body.StaticType <= typeReturn)) { errors.Add(SemanticError.CannotConvert(node.Body, node.Body.StaticType, typeReturn)); } node.TypeReturn = new TypeNode(node.Body.Line, node.Body.Column, typeReturn.Text); }
public void Visit(IfNode node) { node.Condition.Accept(this); node.Body.Accept(this); node.ElseBody.Accept(this); if (node.Condition.StaticType.Text != "Bool") { errors.Add(SemanticError.CannotConvert(node.Condition, node.Condition.StaticType, scope.GetType("Bool"))); } node.StaticType = SemanticAlgorithm.LowerCommonAncestor(node.Body.StaticType, node.ElseBody.StaticType); }
public void Visit(WhileNode node) { node.Condition.Accept(this); node.Body.Accept(this); if (node.Condition.StaticType.Text != "Bool") { errors.Add(SemanticError.CannotConvert(node.Condition, node.Condition.StaticType, scope.GetType("Bool"))); } if (!scope.IsDefinedType("Object", out node.StaticType)) { errors.Add(SemanticError.NotDeclaredType(new TypeNode(node.Line, node.Column, "Object"))); } }
public void Visit(AssignmentNode node) { node.ExpressionRight.Accept(this); if (!scope.IsDefined(node.ID.Text, out TypeInfo type)) { errors.Add(SemanticError.NotDeclaredVariable(node.ID)); } if (!(node.ExpressionRight.StaticType <= type)) { errors.Add(SemanticError.CannotConvert(node, node.ExpressionRight.StaticType, type)); } node.StaticType = node.ExpressionRight.StaticType; }
public void Visit(AttributeNode node) { node.AssignExp.Accept(this); var typeAssignExp = node.AssignExp.StaticType; if (!scope.IsDefinedType(node.Formal.Type.Text, out TypeInfo typeDeclared)) { errors.Add(SemanticError.NotDeclaredType(node.Formal.Type)); } if (!(typeAssignExp <= typeDeclared)) { errors.Add(SemanticError.CannotConvert(node.Formal.Type, typeAssignExp, typeDeclared)); } scope.Define(node.Formal.Id.Text, typeDeclared); }